mirror of
https://github.com/encounter/aurora.git
synced 2025-07-06 13:16:20 +00:00
Update fmtlib
This commit is contained in:
parent
3d53dbed93
commit
b07d55f71d
2
extern/fmt
vendored
2
extern/fmt
vendored
@ -1 +1 @@
|
||||
Subproject commit c4ee726532178e556d923372f29163bd206d7732
|
||||
Subproject commit 123913715afeb8a437e6388b4473fcc4753e1c9a
|
@ -48,7 +48,7 @@ typedef struct {
|
||||
typedef struct SDL_Window SDL_Window;
|
||||
typedef struct AuroraEvent AuroraEvent;
|
||||
|
||||
typedef void (*AuroraLogCallback)(AuroraLogLevel level, const char* message, unsigned int len);
|
||||
typedef void (*AuroraLogCallback)(AuroraLogLevel level, const char* module, const char* message, unsigned int len);
|
||||
typedef void (*AuroraImGuiInitCallback)(const AuroraWindowSize* size);
|
||||
|
||||
typedef struct {
|
||||
|
@ -8,15 +8,15 @@
|
||||
#include "window.hpp"
|
||||
|
||||
#include <SDL3/SDL_filesystem.h>
|
||||
#include <imgui.h>
|
||||
#include <magic_enum.hpp>
|
||||
#include <webgpu/webgpu_cpp.h>
|
||||
|
||||
namespace aurora {
|
||||
static Module Log("aurora");
|
||||
|
||||
AuroraConfig g_config;
|
||||
|
||||
namespace {
|
||||
Module Log("aurora");
|
||||
|
||||
// GPU
|
||||
using webgpu::g_device;
|
||||
using webgpu::g_queue;
|
||||
@ -49,10 +49,11 @@ constexpr std::array PreferredBackendOrder{
|
||||
#endif
|
||||
};
|
||||
|
||||
static bool g_initialFrame = false;
|
||||
bool g_initialFrame = false;
|
||||
|
||||
static AuroraInfo initialize(int argc, char* argv[], const AuroraConfig& config) noexcept {
|
||||
AuroraInfo initialize(int argc, char* argv[], const AuroraConfig& config) noexcept {
|
||||
g_config = config;
|
||||
Log.report(LOG_INFO, "Aurora initializing");
|
||||
if (g_config.appName == nullptr) {
|
||||
g_config.appName = "Aurora";
|
||||
}
|
||||
@ -106,7 +107,7 @@ static AuroraInfo initialize(int argc, char* argv[], const AuroraConfig& config)
|
||||
|
||||
imgui::create_context();
|
||||
const auto size = window::get_window_size();
|
||||
Log.report(LOG_INFO, FMT_STRING("Using framebuffer size {}x{} scale {}"), size.fb_width, size.fb_height, size.scale);
|
||||
Log.report(LOG_INFO, "Using framebuffer size {}x{} scale {}", size.fb_width, size.fb_height, size.scale);
|
||||
if (g_config.imGuiInitCallback != nullptr) {
|
||||
g_config.imGuiInitCallback(&size);
|
||||
}
|
||||
@ -122,9 +123,9 @@ static AuroraInfo initialize(int argc, char* argv[], const AuroraConfig& config)
|
||||
};
|
||||
}
|
||||
|
||||
static wgpu::TextureView g_currentView;
|
||||
wgpu::TextureView g_currentView;
|
||||
|
||||
static void shutdown() noexcept {
|
||||
void shutdown() noexcept {
|
||||
g_currentView = {};
|
||||
imgui::shutdown();
|
||||
gfx::shutdown();
|
||||
@ -132,7 +133,7 @@ static void shutdown() noexcept {
|
||||
window::shutdown();
|
||||
}
|
||||
|
||||
static const AuroraEvent* update() noexcept {
|
||||
const AuroraEvent* update() noexcept {
|
||||
if (g_initialFrame) {
|
||||
g_initialFrame = false;
|
||||
input::initialize();
|
||||
@ -140,7 +141,7 @@ static const AuroraEvent* update() noexcept {
|
||||
return window::poll_events();
|
||||
}
|
||||
|
||||
static bool begin_frame() noexcept {
|
||||
bool begin_frame() noexcept {
|
||||
wgpu::SurfaceTexture surfaceTexture;
|
||||
g_surface.GetCurrentTexture(&surfaceTexture);
|
||||
switch (surfaceTexture.status) {
|
||||
@ -148,15 +149,14 @@ static bool begin_frame() noexcept {
|
||||
g_currentView = surfaceTexture.texture.CreateView();
|
||||
break;
|
||||
case wgpu::SurfaceGetCurrentTextureStatus::SuccessSuboptimal: {
|
||||
Log.report(LOG_WARNING, FMT_STRING("Surface texture is suboptimal"));
|
||||
Log.report(LOG_WARNING, "Surface texture is suboptimal");
|
||||
// Force swapchain recreation
|
||||
const auto size = window::get_window_size();
|
||||
webgpu::resize_swapchain(size.fb_width, size.fb_height, true);
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
Log.report(LOG_ERROR, FMT_STRING("Failed to get surface texture: {}"),
|
||||
magic_enum::enum_name(surfaceTexture.status));
|
||||
Log.report(LOG_ERROR, "Failed to get surface texture: {}", magic_enum::enum_name(surfaceTexture.status));
|
||||
return false;
|
||||
}
|
||||
imgui::new_frame(window::get_window_size());
|
||||
@ -164,7 +164,7 @@ static bool begin_frame() noexcept {
|
||||
return true;
|
||||
}
|
||||
|
||||
static void end_frame() noexcept {
|
||||
void end_frame() noexcept {
|
||||
const auto encoderDescriptor = wgpu::CommandEncoderDescriptor{
|
||||
.label = "Redraw encoder",
|
||||
};
|
||||
@ -198,6 +198,7 @@ static void end_frame() noexcept {
|
||||
g_surface.Present();
|
||||
g_currentView = {};
|
||||
}
|
||||
} // namespace
|
||||
} // namespace aurora
|
||||
|
||||
// C API bindings
|
||||
|
@ -23,95 +23,6 @@
|
||||
#endif
|
||||
|
||||
namespace aurora::webgpu::utils {
|
||||
|
||||
//#if defined(DAWN_ENABLE_BACKEND_OPENGL)
|
||||
//struct GLUserData {
|
||||
// SDL_Window* window;
|
||||
// SDL_GLContext context;
|
||||
//};
|
||||
//void GLMakeCurrent(void* userData) {
|
||||
// auto* data = static_cast<GLUserData*>(userData);
|
||||
// SDL_GL_MakeCurrent(data->window, data->context);
|
||||
//}
|
||||
//void GLDestroy(void* userData) {
|
||||
// auto* data = static_cast<GLUserData*>(userData);
|
||||
// SDL_GL_DestroyContext(data->context);
|
||||
// delete data;
|
||||
//}
|
||||
//#endif
|
||||
//
|
||||
//bool DiscoverAdapter(dawn::native::Instance* instance, [[maybe_unused]] SDL_Window* window, wgpu::BackendType type) {
|
||||
// switch (type) {
|
||||
//#if defined(DAWN_ENABLE_BACKEND_D3D11)
|
||||
// case wgpu::BackendType::D3D11: {
|
||||
// dawn::native::d3d11::PhysicalDeviceDiscoveryOptions options;
|
||||
// return instance->DiscoverPhysicalDevices(&options);
|
||||
// }
|
||||
//#endif
|
||||
//#if defined(DAWN_ENABLE_BACKEND_D3D12)
|
||||
// case wgpu::BackendType::D3D12: {
|
||||
// dawn::native::d3d12::PhysicalDeviceDiscoveryOptions options;
|
||||
// return instance->DiscoverPhysicalDevices(&options);
|
||||
// }
|
||||
//#endif
|
||||
//#if defined(DAWN_ENABLE_BACKEND_METAL)
|
||||
// case wgpu::BackendType::Metal: {
|
||||
// dawn::native::metal::PhysicalDeviceDiscoveryOptions options;
|
||||
// return instance->DiscoverPhysicalDevices(&options);
|
||||
// }
|
||||
//#endif
|
||||
//#if defined(DAWN_ENABLE_BACKEND_VULKAN)
|
||||
// case wgpu::BackendType::Vulkan: {
|
||||
// dawn::native::vulkan::PhysicalDeviceDiscoveryOptions options;
|
||||
// return instance->DiscoverPhysicalDevices(&options);
|
||||
// }
|
||||
//#endif
|
||||
//#if defined(DAWN_ENABLE_BACKEND_DESKTOP_GL)
|
||||
// case wgpu::BackendType::OpenGL: {
|
||||
// SDL_GL_ResetAttributes();
|
||||
// SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
// SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
|
||||
// SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 4);
|
||||
// SDL_GLContext context = SDL_GL_CreateContext(window);
|
||||
// dawn::native::opengl::PhysicalDeviceDiscoveryOptions options{WGPUBackendType_OpenGL};
|
||||
// options.getProc = reinterpret_cast<void* (*)(const char*)>(SDL_GL_GetProcAddress);
|
||||
// options.makeCurrent = GLMakeCurrent;
|
||||
// options.destroy = GLDestroy;
|
||||
// options.userData = new GLUserData{
|
||||
// .window = window,
|
||||
// .context = context,
|
||||
// };
|
||||
// return instance->DiscoverPhysicalDevices(&options);
|
||||
// }
|
||||
//#endif
|
||||
//#if defined(DAWN_ENABLE_BACKEND_OPENGLES)
|
||||
// case wgpu::BackendType::OpenGLES: {
|
||||
// SDL_GL_ResetAttributes();
|
||||
// SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
|
||||
// SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
||||
// SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
||||
// SDL_GLContext context = SDL_GL_CreateContext(window);
|
||||
// dawn::native::opengl::PhysicalDeviceDiscoveryOptions options{WGPUBackendType_OpenGLES};
|
||||
// options.getProc = reinterpret_cast<void* (*)(const char*)>(SDL_GL_GetProcAddress);
|
||||
// options.makeCurrent = GLMakeCurrent;
|
||||
// options.destroy = GLDestroy;
|
||||
// options.userData = new GLUserData{
|
||||
// .window = window,
|
||||
// .context = context,
|
||||
// };
|
||||
// return instance->DiscoverPhysicalDevices(&options);
|
||||
// }
|
||||
//#endif
|
||||
//#if defined(DAWN_ENABLE_BACKEND_NULL)
|
||||
// case wgpu::BackendType::Null:
|
||||
// instance->DiscoverDefaultPhysicalDevices();
|
||||
// return true;
|
||||
//#endif
|
||||
// default:
|
||||
// return false;
|
||||
// }
|
||||
//}
|
||||
|
||||
std::unique_ptr<wgpu::ChainedStruct> SetupWindowAndGetSurfaceDescriptorCocoa(SDL_Window* window);
|
||||
|
||||
std::unique_ptr<wgpu::ChainedStruct> SetupWindowAndGetSurfaceDescriptor(SDL_Window* window) {
|
||||
@ -120,22 +31,20 @@ std::unique_ptr<wgpu::ChainedStruct> SetupWindowAndGetSurfaceDescriptor(SDL_Wind
|
||||
#else
|
||||
const auto props = SDL_GetWindowProperties(window);
|
||||
#if defined(SDL_PLATFORM_WIN32)
|
||||
std::unique_ptr<wgpu::SurfaceSourceWindowsHWND> desc =
|
||||
std::make_unique<wgpu::SurfaceSourceWindowsHWND>();
|
||||
desc->hwnd = wmInfo.info.win.window;
|
||||
desc->hinstance = wmInfo.info.win.hinstance;
|
||||
std::unique_ptr<wgpu::SurfaceSourceWindowsHWND> desc = std::make_unique<wgpu::SurfaceSourceWindowsHWND>();
|
||||
desc->hwnd = SDL_GetPointerProperty(props, SDL_PROP_WINDOW_WIN32_HWND_POINTER, nullptr);
|
||||
desc->hinstance = SDL_GetPointerProperty(props, SDL_PROP_WINDOW_WIN32_INSTANCE_POINTER, nullptr);
|
||||
return std::move(desc);
|
||||
#elif defined(SDL_PLATFORM_LINUX)
|
||||
if (SDL_strcmp(SDL_GetCurrentVideoDriver(), "wayland") == 0) {
|
||||
std::unique_ptr<wgpu::SurfaceSourceWaylandSurface> desc =
|
||||
std::make_unique<wgpu::SurfaceSourceWaylandSurface>();
|
||||
const char* driver = SDL_GetCurrentVideoDriver();
|
||||
if (SDL_strcmp(driver, "wayland") == 0) {
|
||||
std::unique_ptr<wgpu::SurfaceSourceWaylandSurface> desc = std::make_unique<wgpu::SurfaceSourceWaylandSurface>();
|
||||
desc->display = SDL_GetPointerProperty(props, SDL_PROP_WINDOW_WAYLAND_DISPLAY_POINTER, nullptr);
|
||||
desc->surface = SDL_GetPointerProperty(props, SDL_PROP_WINDOW_WAYLAND_SURFACE_POINTER, nullptr);
|
||||
return std::move(desc);
|
||||
}
|
||||
if (SDL_strcmp(SDL_GetCurrentVideoDriver(), "x11") == 0) {
|
||||
std::unique_ptr<wgpu::SurfaceSourceXlibWindow> desc =
|
||||
std::make_unique<wgpu::SurfaceSourceXlibWindow>();
|
||||
if (SDL_strcmp(driver, "x11") == 0) {
|
||||
std::unique_ptr<wgpu::SurfaceSourceXlibWindow> desc = std::make_unique<wgpu::SurfaceSourceXlibWindow>();
|
||||
desc->display = SDL_GetPointerProperty(props, SDL_PROP_WINDOW_X11_DISPLAY_POINTER, nullptr);
|
||||
desc->window = SDL_GetNumberProperty(props, SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0);
|
||||
return std::move(desc);
|
||||
|
@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <dawn/native/DawnNative.h>
|
||||
#include <memory>
|
||||
#include <webgpu/webgpu_cpp.h>
|
||||
|
||||
@ -8,7 +7,6 @@ struct SDL_Window;
|
||||
|
||||
namespace aurora::webgpu::utils {
|
||||
|
||||
bool DiscoverAdapter(dawn::native::Instance* instance, SDL_Window* window, wgpu::BackendType type);
|
||||
std::unique_ptr<wgpu::ChainedStruct> SetupWindowAndGetSurfaceDescriptor(SDL_Window* window);
|
||||
|
||||
} // namespace aurora::webgpu::utils
|
||||
|
@ -1,37 +0,0 @@
|
||||
#include "BackendBinding.hpp"
|
||||
|
||||
#include <SDL3/SDL_syswm.h>
|
||||
#include <dawn/native/D3D12Backend.h>
|
||||
|
||||
namespace aurora::webgpu::utils {
|
||||
class D3D12Binding : public BackendBinding {
|
||||
public:
|
||||
D3D12Binding(SDL_Window* window, WGPUDevice device) : BackendBinding(window, device) {}
|
||||
|
||||
uint64_t GetSwapChainImplementation() override {
|
||||
if (m_swapChainImpl.userData == nullptr) {
|
||||
CreateSwapChainImpl();
|
||||
}
|
||||
return reinterpret_cast<uint64_t>(&m_swapChainImpl);
|
||||
}
|
||||
|
||||
WGPUTextureFormat GetPreferredSwapChainTextureFormat() override {
|
||||
if (m_swapChainImpl.userData == nullptr) {
|
||||
CreateSwapChainImpl();
|
||||
}
|
||||
return dawn::native::d3d12::GetNativeSwapChainPreferredFormat(&m_swapChainImpl);
|
||||
}
|
||||
|
||||
private:
|
||||
DawnSwapChainImplementation m_swapChainImpl{};
|
||||
|
||||
void CreateSwapChainImpl() {
|
||||
SDL_SysWMinfo wmInfo;
|
||||
SDL_VERSION(&wmInfo.version);
|
||||
SDL_GetWindowWMInfo(m_window, &wmInfo);
|
||||
m_swapChainImpl = dawn::native::d3d12::CreateNativeSwapChainImpl(m_device, wmInfo.info.win.window);
|
||||
}
|
||||
};
|
||||
|
||||
BackendBinding* CreateD3D12Binding(SDL_Window* window, WGPUDevice device) { return new D3D12Binding(window, device); }
|
||||
} // namespace aurora::webgpu::utils
|
@ -5,8 +5,7 @@
|
||||
namespace aurora::webgpu::utils {
|
||||
std::unique_ptr<wgpu::ChainedStruct> SetupWindowAndGetSurfaceDescriptorCocoa(SDL_Window* window) {
|
||||
SDL_MetalView view = SDL_Metal_CreateView(window);
|
||||
std::unique_ptr<wgpu::SurfaceDescriptorFromMetalLayer> desc =
|
||||
std::make_unique<wgpu::SurfaceDescriptorFromMetalLayer>();
|
||||
std::unique_ptr<wgpu::SurfaceSourceMetalLayer> desc = std::make_unique<wgpu::SurfaceSourceMetalLayer>();
|
||||
desc->layer = SDL_Metal_GetLayer(view);
|
||||
return std::move(desc);
|
||||
}
|
||||
|
@ -1,26 +0,0 @@
|
||||
#include "BackendBinding.hpp"
|
||||
|
||||
#include <dawn/native/NullBackend.h>
|
||||
|
||||
namespace aurora::webgpu::utils {
|
||||
class NullBinding : public BackendBinding {
|
||||
public:
|
||||
NullBinding(SDL_Window* window, WGPUDevice device) : BackendBinding(window, device) {}
|
||||
|
||||
uint64_t GetSwapChainImplementation() override {
|
||||
if (m_swapChainImpl.userData == nullptr) {
|
||||
m_swapChainImpl = dawn::native::null::CreateNativeSwapChainImpl();
|
||||
}
|
||||
return reinterpret_cast<uint64_t>(&m_swapChainImpl);
|
||||
}
|
||||
|
||||
WGPUTextureFormat GetPreferredSwapChainTextureFormat() override {
|
||||
return WGPUTextureFormat_RGBA8Unorm;
|
||||
}
|
||||
|
||||
private:
|
||||
DawnSwapChainImplementation m_swapChainImpl{};
|
||||
};
|
||||
|
||||
BackendBinding* CreateNullBinding(SDL_Window* window, WGPUDevice device) { return new NullBinding(window, device); }
|
||||
} // namespace aurora::webgpu::utils
|
@ -1,35 +0,0 @@
|
||||
#include "BackendBinding.hpp"
|
||||
|
||||
#include <SDL3/SDL_video.h>
|
||||
#include <dawn/native/OpenGLBackend.h>
|
||||
|
||||
namespace aurora::webgpu::utils {
|
||||
class OpenGLBinding : public BackendBinding {
|
||||
public:
|
||||
OpenGLBinding(SDL_Window* window, WGPUDevice device) : BackendBinding(window, device) {}
|
||||
|
||||
uint64_t GetSwapChainImplementation() override {
|
||||
if (m_swapChainImpl.userData == nullptr) {
|
||||
CreateSwapChainImpl();
|
||||
}
|
||||
return reinterpret_cast<uint64_t>(&m_swapChainImpl);
|
||||
}
|
||||
|
||||
WGPUTextureFormat GetPreferredSwapChainTextureFormat() override {
|
||||
if (m_swapChainImpl.userData == nullptr) {
|
||||
CreateSwapChainImpl();
|
||||
}
|
||||
return dawn::native::opengl::GetNativeSwapChainPreferredFormat(&m_swapChainImpl);
|
||||
}
|
||||
|
||||
private:
|
||||
DawnSwapChainImplementation m_swapChainImpl{};
|
||||
|
||||
void CreateSwapChainImpl() {
|
||||
m_swapChainImpl = dawn::native::opengl::CreateNativeSwapChainImpl(
|
||||
m_device, [](void* userdata) { SDL_GL_SwapWindow(static_cast<SDL_Window*>(userdata)); }, m_window);
|
||||
}
|
||||
};
|
||||
|
||||
BackendBinding* CreateOpenGLBinding(SDL_Window* window, WGPUDevice device) { return new OpenGLBinding(window, device); }
|
||||
} // namespace aurora::webgpu::utils
|
@ -1,41 +0,0 @@
|
||||
#include "BackendBinding.hpp"
|
||||
|
||||
#include "../internal.hpp"
|
||||
|
||||
#include <SDL3/SDL_vulkan.h>
|
||||
#include <dawn/native/VulkanBackend.h>
|
||||
|
||||
namespace aurora::webgpu::utils {
|
||||
static Module Log("aurora::webgpu::utils::VulkanBinding");
|
||||
|
||||
class VulkanBinding : public BackendBinding {
|
||||
public:
|
||||
VulkanBinding(SDL_Window* window, WGPUDevice device) : BackendBinding(window, device) {}
|
||||
|
||||
uint64_t GetSwapChainImplementation() override {
|
||||
if (m_swapChainImpl.userData == nullptr) {
|
||||
CreateSwapChainImpl();
|
||||
}
|
||||
return reinterpret_cast<uint64_t>(&m_swapChainImpl);
|
||||
}
|
||||
|
||||
WGPUTextureFormat GetPreferredSwapChainTextureFormat() override {
|
||||
if (m_swapChainImpl.userData == nullptr) {
|
||||
CreateSwapChainImpl();
|
||||
}
|
||||
return dawn::native::vulkan::GetNativeSwapChainPreferredFormat(&m_swapChainImpl);
|
||||
}
|
||||
|
||||
private:
|
||||
DawnSwapChainImplementation m_swapChainImpl{};
|
||||
|
||||
void CreateSwapChainImpl() {
|
||||
VkSurfaceKHR surface = VK_NULL_HANDLE;
|
||||
ASSERT(SDL_Vulkan_CreateSurface(m_window, dawn::native::vulkan::GetInstance(m_device), &surface),
|
||||
"Failed to create Vulkan surface: {}", SDL_GetError());
|
||||
m_swapChainImpl = dawn::native::vulkan::CreateNativeSwapChainImpl(m_device, surface);
|
||||
}
|
||||
};
|
||||
|
||||
BackendBinding* CreateVulkanBinding(SDL_Window* window, WGPUDevice device) { return new VulkanBinding(window, device); }
|
||||
} // namespace aurora::webgpu::utils
|
@ -113,8 +113,9 @@ void GXInitTexObjTlut(GXTexObj* obj_, u32 tlut) {
|
||||
void GXLoadTexObj(GXTexObj* obj_, GXTexMapID id) {
|
||||
auto* obj = reinterpret_cast<GXTexObj_*>(obj_);
|
||||
if (!obj->ref) {
|
||||
obj->ref = aurora::gfx::new_dynamic_texture_2d(obj->width, obj->height, u32(obj->maxLod) + 1, obj->fmt,
|
||||
fmt::format(FMT_STRING("GXLoadTexObj_{}"), obj->fmt).c_str());
|
||||
const auto name = fmt::format("GXLoadTexObj_{}", obj->fmt);
|
||||
obj->ref =
|
||||
aurora::gfx::new_dynamic_texture_2d(obj->width, obj->height, u32(obj->maxLod) + 1, obj->fmt, name.c_str());
|
||||
}
|
||||
if (obj->dataInvalidated) {
|
||||
aurora::gfx::write_texture(*obj->ref, {static_cast<const u8*>(obj->data), UINT32_MAX /* TODO */});
|
||||
|
@ -219,7 +219,7 @@ static PipelineRef find_pipeline(ShaderType type, const PipelineConfig& config,
|
||||
static inline void push_command(CommandType type, const Command::Data& data) {
|
||||
if (g_currentRenderPass == UINT32_MAX)
|
||||
UNLIKELY {
|
||||
Log.report(LOG_WARNING, FMT_STRING("Dropping command {}"), magic_enum::enum_name(type));
|
||||
Log.report(LOG_WARNING, "Dropping command {}", magic_enum::enum_name(type));
|
||||
return;
|
||||
}
|
||||
g_renderPasses[g_currentRenderPass].commands.push_back({
|
||||
@ -391,7 +391,7 @@ void load_pipeline_cache() {
|
||||
find_pipeline(type, config, [=]() { return model::create_pipeline(g_state.model, config); }, true);
|
||||
} break;
|
||||
default:
|
||||
Log.report(LOG_WARNING, FMT_STRING("Unknown pipeline type {}"), static_cast<int>(type));
|
||||
Log.report(LOG_WARNING, "Unknown pipeline type {}", static_cast<int>(type));
|
||||
break;
|
||||
}
|
||||
offset += size;
|
||||
@ -445,7 +445,7 @@ void initialize() {
|
||||
createBuffer(g_storageBuffer, wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopyDst, StorageBufferSize,
|
||||
"Shared Storage Buffer");
|
||||
for (int i = 0; i < g_stagingBuffers.size(); ++i) {
|
||||
const auto label = fmt::format(FMT_STRING("Staging Buffer {}"), i);
|
||||
const auto label = fmt::format("Staging Buffer {}", i);
|
||||
createBuffer(g_stagingBuffers[i], wgpu::BufferUsage::MapWrite | wgpu::BufferUsage::CopySrc, StagingBufferSize,
|
||||
label.c_str());
|
||||
}
|
||||
@ -605,7 +605,7 @@ void render(wgpu::CommandEncoder& cmd) {
|
||||
.depthStoreOp = wgpu::StoreOp::Store,
|
||||
.depthClearValue = 1.f,
|
||||
};
|
||||
const auto label = fmt::format(FMT_STRING("Render pass {}"), i);
|
||||
const auto label = fmt::format("Render pass {}", i);
|
||||
const wgpu::RenderPassDescriptor renderPassDescriptor{
|
||||
.label = label.c_str(),
|
||||
.colorAttachmentCount = attachments.size(),
|
||||
|
526
lib/gfx/gx_fmt.hpp
Normal file
526
lib/gfx/gx_fmt.hpp
Normal file
@ -0,0 +1,526 @@
|
||||
#include <dolphin/gx/GXEnum.h>
|
||||
#include <fmt/format.h>
|
||||
#include <string>
|
||||
|
||||
inline std::string format_as(const GXTevOp& op) {
|
||||
switch (op) {
|
||||
case GX_TEV_ADD:
|
||||
return "GX_TEV_ADD";
|
||||
case GX_TEV_SUB:
|
||||
return "GX_TEV_SUB";
|
||||
case GX_TEV_COMP_R8_GT:
|
||||
return "GX_TEV_COMP_R8_GT";
|
||||
case GX_TEV_COMP_R8_EQ:
|
||||
return "GX_TEV_COMP_R8_EQ";
|
||||
case GX_TEV_COMP_GR16_GT:
|
||||
return "GX_TEV_COMP_GR16_GT";
|
||||
case GX_TEV_COMP_GR16_EQ:
|
||||
return "GX_TEV_COMP_GR16_EQ";
|
||||
case GX_TEV_COMP_BGR24_GT:
|
||||
return "GX_TEV_COMP_BGR24_GT";
|
||||
case GX_TEV_COMP_BGR24_EQ:
|
||||
return "GX_TEV_COMP_BGR24_EQ";
|
||||
case GX_TEV_COMP_RGB8_GT:
|
||||
return "GX_TEV_COMP_RGB8_GT";
|
||||
case GX_TEV_COMP_RGB8_EQ:
|
||||
return "GX_TEV_COMP_RGB8_EQ";
|
||||
default:
|
||||
return fmt::format("GXTevOp({})", static_cast<int>(op));
|
||||
}
|
||||
}
|
||||
|
||||
inline std::string format_as(const GXTevColorArg& arg) {
|
||||
switch (arg) {
|
||||
case GX_CC_CPREV:
|
||||
return "GX_CC_CPREV";
|
||||
case GX_CC_APREV:
|
||||
return "GX_CC_APREV";
|
||||
case GX_CC_C0:
|
||||
return "GX_CC_C0";
|
||||
case GX_CC_A0:
|
||||
return "GX_CC_A0";
|
||||
case GX_CC_C1:
|
||||
return "GX_CC_C1";
|
||||
case GX_CC_A1:
|
||||
return "GX_CC_A1";
|
||||
case GX_CC_C2:
|
||||
return "GX_CC_C2";
|
||||
case GX_CC_A2:
|
||||
return "GX_CC_A2";
|
||||
case GX_CC_TEXC:
|
||||
return "GX_CC_TEXC";
|
||||
case GX_CC_TEXA:
|
||||
return "GX_CC_TEXA";
|
||||
case GX_CC_RASC:
|
||||
return "GX_CC_RASC";
|
||||
case GX_CC_RASA:
|
||||
return "GX_CC_RASA";
|
||||
case GX_CC_ONE:
|
||||
return "GX_CC_ONE";
|
||||
case GX_CC_HALF:
|
||||
return "GX_CC_HALF";
|
||||
case GX_CC_KONST:
|
||||
return "GX_CC_KONST";
|
||||
case GX_CC_ZERO:
|
||||
return "GX_CC_ZERO";
|
||||
default:
|
||||
return fmt::format("GXTevColorArg({})", static_cast<int>(arg));
|
||||
}
|
||||
}
|
||||
|
||||
inline std::string format_as(const GXTevAlphaArg& arg) {
|
||||
switch (arg) {
|
||||
case GX_CA_APREV:
|
||||
return "GX_CA_APREV";
|
||||
case GX_CA_A0:
|
||||
return "GX_CA_A0";
|
||||
case GX_CA_A1:
|
||||
return "GX_CA_A1";
|
||||
case GX_CA_A2:
|
||||
return "GX_CA_A2";
|
||||
case GX_CA_TEXA:
|
||||
return "GX_CA_TEXA";
|
||||
case GX_CA_RASA:
|
||||
return "GX_CA_RASA";
|
||||
case GX_CA_KONST:
|
||||
return "GX_CA_KONST";
|
||||
case GX_CA_ZERO:
|
||||
return "GX_CA_ZERO";
|
||||
default:
|
||||
return fmt::format("GXTevAlphaArg({})", static_cast<int>(arg));
|
||||
}
|
||||
}
|
||||
|
||||
inline std::string format_as(const GXTexGenSrc& src) {
|
||||
switch (src) {
|
||||
case GX_TG_POS:
|
||||
return "GX_TG_POS";
|
||||
case GX_TG_NRM:
|
||||
return "GX_TG_NRM";
|
||||
case GX_TG_BINRM:
|
||||
return "GX_TG_BINRM";
|
||||
case GX_TG_TANGENT:
|
||||
return "GX_TG_TANGENT";
|
||||
case GX_TG_TEX0:
|
||||
return "GX_TG_TEX0";
|
||||
case GX_TG_TEX1:
|
||||
return "GX_TG_TEX1";
|
||||
case GX_TG_TEX2:
|
||||
return "GX_TG_TEX2";
|
||||
case GX_TG_TEX3:
|
||||
return "GX_TG_TEX3";
|
||||
case GX_TG_TEX4:
|
||||
return "GX_TG_TEX4";
|
||||
case GX_TG_TEX5:
|
||||
return "GX_TG_TEX5";
|
||||
case GX_TG_TEX6:
|
||||
return "GX_TG_TEX6";
|
||||
case GX_TG_TEX7:
|
||||
return "GX_TG_TEX7";
|
||||
default:
|
||||
return fmt::format("GXTexGenSrc({})", static_cast<int>(src));
|
||||
}
|
||||
}
|
||||
|
||||
inline std::string format_as(const GXTexGenType& type) {
|
||||
switch (type) {
|
||||
case GX_TG_MTX2x4:
|
||||
return "GX_TG_MTX2x4";
|
||||
case GX_TG_MTX3x4:
|
||||
return "GX_TG_MTX3x4";
|
||||
case GX_TG_BUMP0:
|
||||
return "GX_TG_BUMP0";
|
||||
case GX_TG_BUMP1:
|
||||
return "GX_TG_BUMP1";
|
||||
default:
|
||||
return fmt::format("GXTexGenType({})", static_cast<int>(type));
|
||||
}
|
||||
}
|
||||
|
||||
inline std::string format_as(const GXTevBias& bias) {
|
||||
switch (bias) {
|
||||
case GX_TB_ZERO:
|
||||
return "GX_TB_ZERO";
|
||||
case GX_TB_ADDHALF:
|
||||
return "GX_TB_ADDHALF";
|
||||
case GX_TB_SUBHALF:
|
||||
return "GX_TB_SUBHALF";
|
||||
default:
|
||||
return fmt::format("GXTevBias({})", static_cast<int>(bias));
|
||||
}
|
||||
}
|
||||
|
||||
inline std::string format_as(const GXTevScale& scale) {
|
||||
switch (scale) {
|
||||
case GX_CS_SCALE_1:
|
||||
return "GX_CS_SCALE_1";
|
||||
case GX_CS_SCALE_2:
|
||||
return "GX_CS_SCALE_2";
|
||||
case GX_CS_SCALE_4:
|
||||
return "GX_CS_SCALE_4";
|
||||
case GX_CS_DIVIDE_2:
|
||||
return "GX_CS_DIVIDE_2";
|
||||
default:
|
||||
return fmt::format("GXTevScale({})", static_cast<int>(scale));
|
||||
}
|
||||
}
|
||||
|
||||
inline std::string format_as(const GXTevRegID& reg) {
|
||||
switch (reg) {
|
||||
case GX_TEVPREV:
|
||||
return "GX_TEVPREV";
|
||||
case GX_TEVREG0:
|
||||
return "GX_TEVREG0";
|
||||
case GX_TEVREG1:
|
||||
return "GX_TEVREG1";
|
||||
case GX_TEVREG2:
|
||||
return "GX_TEVREG2";
|
||||
default:
|
||||
return fmt::format("GXTevRegID({})", static_cast<int>(reg));
|
||||
}
|
||||
}
|
||||
|
||||
inline std::string format_as(const GXTevKColorSel& sel) {
|
||||
switch (sel) {
|
||||
case GX_TEV_KCSEL_8_8:
|
||||
return "GX_TEV_KCSEL_8_8";
|
||||
case GX_TEV_KCSEL_7_8:
|
||||
return "GX_TEV_KCSEL_7_8";
|
||||
case GX_TEV_KCSEL_6_8:
|
||||
return "GX_TEV_KCSEL_6_8";
|
||||
case GX_TEV_KCSEL_5_8:
|
||||
return "GX_TEV_KCSEL_5_8";
|
||||
case GX_TEV_KCSEL_4_8:
|
||||
return "GX_TEV_KCSEL_4_8";
|
||||
case GX_TEV_KCSEL_3_8:
|
||||
return "GX_TEV_KCSEL_3_8";
|
||||
case GX_TEV_KCSEL_2_8:
|
||||
return "GX_TEV_KCSEL_2_8";
|
||||
case GX_TEV_KCSEL_1_8:
|
||||
return "GX_TEV_KCSEL_1_8";
|
||||
case GX_TEV_KCSEL_K0_R:
|
||||
return "GX_TEV_KCSEL_K0_R";
|
||||
case GX_TEV_KCSEL_K1_R:
|
||||
return "GX_TEV_KCSEL_K1_R";
|
||||
case GX_TEV_KCSEL_K2_R:
|
||||
return "GX_TEV_KCSEL_K2_R";
|
||||
case GX_TEV_KCSEL_K3_R:
|
||||
return "GX_TEV_KCSEL_K3_R";
|
||||
case GX_TEV_KCSEL_K0_G:
|
||||
return "GX_TEV_KCSEL_K0_G";
|
||||
case GX_TEV_KCSEL_K1_G:
|
||||
return "GX_TEV_KCSEL_K1_G";
|
||||
case GX_TEV_KCSEL_K2_G:
|
||||
return "GX_TEV_KCSEL_K2_G";
|
||||
case GX_TEV_KCSEL_K3_G:
|
||||
return "GX_TEV_KCSEL_K3_G";
|
||||
case GX_TEV_KCSEL_K0_B:
|
||||
return "GX_TEV_KCSEL_K0_B";
|
||||
case GX_TEV_KCSEL_K1_B:
|
||||
return "GX_TEV_KCSEL_K1_B";
|
||||
case GX_TEV_KCSEL_K2_B:
|
||||
return "GX_TEV_KCSEL_K2_B";
|
||||
case GX_TEV_KCSEL_K3_B:
|
||||
return "GX_TEV_KCSEL_K3_B";
|
||||
case GX_TEV_KCSEL_K0_A:
|
||||
return "GX_TEV_KCSEL_K0_A";
|
||||
case GX_TEV_KCSEL_K1_A:
|
||||
return "GX_TEV_KCSEL_K1_A";
|
||||
case GX_TEV_KCSEL_K2_A:
|
||||
return "GX_TEV_KCSEL_K2_A";
|
||||
case GX_TEV_KCSEL_K3_A:
|
||||
return "GX_TEV_KCSEL_K3_A";
|
||||
default:
|
||||
return fmt::format("GXTevKColorSel({})", static_cast<int>(sel));
|
||||
}
|
||||
}
|
||||
|
||||
inline std::string format_as(const GXTevKAlphaSel& sel) {
|
||||
switch (sel) {
|
||||
case GX_TEV_KASEL_8_8:
|
||||
return "GX_TEV_KASEL_8_8";
|
||||
case GX_TEV_KASEL_7_8:
|
||||
return "GX_TEV_KASEL_7_8";
|
||||
case GX_TEV_KASEL_6_8:
|
||||
return "GX_TEV_KASEL_6_8";
|
||||
case GX_TEV_KASEL_5_8:
|
||||
return "GX_TEV_KASEL_5_8";
|
||||
case GX_TEV_KASEL_4_8:
|
||||
return "GX_TEV_KASEL_4_8";
|
||||
case GX_TEV_KASEL_3_8:
|
||||
return "GX_TEV_KASEL_3_8";
|
||||
case GX_TEV_KASEL_2_8:
|
||||
return "GX_TEV_KASEL_2_8";
|
||||
case GX_TEV_KASEL_1_8:
|
||||
return "GX_TEV_KASEL_1_8";
|
||||
case GX_TEV_KASEL_K0_R:
|
||||
return "GX_TEV_KASEL_K0_R";
|
||||
case GX_TEV_KASEL_K1_R:
|
||||
return "GX_TEV_KASEL_K1_R";
|
||||
case GX_TEV_KASEL_K2_R:
|
||||
return "GX_TEV_KASEL_K2_R";
|
||||
case GX_TEV_KASEL_K3_R:
|
||||
return "GX_TEV_KASEL_K3_R";
|
||||
case GX_TEV_KASEL_K0_G:
|
||||
return "GX_TEV_KASEL_K0_G";
|
||||
case GX_TEV_KASEL_K1_G:
|
||||
return "GX_TEV_KASEL_K1_G";
|
||||
case GX_TEV_KASEL_K2_G:
|
||||
return "GX_TEV_KASEL_K2_G";
|
||||
case GX_TEV_KASEL_K3_G:
|
||||
return "GX_TEV_KASEL_K3_G";
|
||||
case GX_TEV_KASEL_K0_B:
|
||||
return "GX_TEV_KASEL_K0_B";
|
||||
case GX_TEV_KASEL_K1_B:
|
||||
return "GX_TEV_KASEL_K1_B";
|
||||
case GX_TEV_KASEL_K2_B:
|
||||
return "GX_TEV_KASEL_K2_B";
|
||||
case GX_TEV_KASEL_K3_B:
|
||||
return "GX_TEV_KASEL_K3_B";
|
||||
case GX_TEV_KASEL_K0_A:
|
||||
return "GX_TEV_KASEL_K0_A";
|
||||
case GX_TEV_KASEL_K1_A:
|
||||
return "GX_TEV_KASEL_K1_A";
|
||||
case GX_TEV_KASEL_K2_A:
|
||||
return "GX_TEV_KASEL_K2_A";
|
||||
case GX_TEV_KASEL_K3_A:
|
||||
return "GX_TEV_KASEL_K3_A";
|
||||
default:
|
||||
return fmt::format("GXTevKAlphaSel({})", static_cast<int>(sel));
|
||||
}
|
||||
}
|
||||
|
||||
inline std::string format_as(const GXTexMapID& id) {
|
||||
switch (id) {
|
||||
case GX_TEXMAP0:
|
||||
return "GX_TEXMAP0";
|
||||
case GX_TEXMAP1:
|
||||
return "GX_TEXMAP1";
|
||||
case GX_TEXMAP2:
|
||||
return "GX_TEXMAP2";
|
||||
case GX_TEXMAP3:
|
||||
return "GX_TEXMAP3";
|
||||
case GX_TEXMAP4:
|
||||
return "GX_TEXMAP4";
|
||||
case GX_TEXMAP5:
|
||||
return "GX_TEXMAP5";
|
||||
case GX_TEXMAP6:
|
||||
return "GX_TEXMAP6";
|
||||
case GX_TEXMAP7:
|
||||
return "GX_TEXMAP7";
|
||||
case GX_TEXMAP_NULL:
|
||||
return "GX_TEXMAP_NULL";
|
||||
case GX_TEX_DISABLE:
|
||||
return "GX_TEX_DISABLE";
|
||||
default:
|
||||
return fmt::format("GXTexMapID({})", static_cast<int>(id));
|
||||
}
|
||||
}
|
||||
|
||||
inline std::string format_as(const GXChannelID& id) {
|
||||
switch (id) {
|
||||
case GX_COLOR0:
|
||||
return "GX_COLOR0";
|
||||
case GX_COLOR1:
|
||||
return "GX_COLOR1";
|
||||
case GX_ALPHA0:
|
||||
return "GX_ALPHA0";
|
||||
case GX_ALPHA1:
|
||||
return "GX_ALPHA1";
|
||||
case GX_COLOR0A0:
|
||||
return "GX_COLOR0A0";
|
||||
case GX_COLOR1A1:
|
||||
return "GX_COLOR1A1";
|
||||
case GX_COLOR_ZERO:
|
||||
return "GX_COLOR_ZERO";
|
||||
case GX_ALPHA_BUMP:
|
||||
return "GX_ALPHA_BUMP";
|
||||
case GX_ALPHA_BUMPN:
|
||||
return "GX_ALPHA_BUMPN";
|
||||
case GX_COLOR_NULL:
|
||||
return "GX_COLOR_NULL";
|
||||
default:
|
||||
return fmt::format("GXChannelID({})", static_cast<int>(id));
|
||||
}
|
||||
}
|
||||
|
||||
inline std::string format_as(const GXColorSrc& src) {
|
||||
switch (src) {
|
||||
case GX_SRC_REG:
|
||||
return "GX_SRC_REG";
|
||||
case GX_SRC_VTX:
|
||||
return "GX_SRC_VTX";
|
||||
default:
|
||||
return fmt::format("GXColorSrc({})", static_cast<int>(src));
|
||||
}
|
||||
}
|
||||
|
||||
inline std::string format_as(const GXTexMtx& mtx) {
|
||||
switch (mtx) {
|
||||
case GX_TEXMTX0:
|
||||
return "GX_TEXMTX0";
|
||||
case GX_TEXMTX1:
|
||||
return "GX_TEXMTX1";
|
||||
case GX_TEXMTX2:
|
||||
return "GX_TEXMTX2";
|
||||
case GX_TEXMTX3:
|
||||
return "GX_TEXMTX3";
|
||||
case GX_TEXMTX4:
|
||||
return "GX_TEXMTX4";
|
||||
case GX_TEXMTX5:
|
||||
return "GX_TEXMTX5";
|
||||
case GX_TEXMTX6:
|
||||
return "GX_TEXMTX6";
|
||||
case GX_TEXMTX7:
|
||||
return "GX_TEXMTX7";
|
||||
case GX_TEXMTX8:
|
||||
return "GX_TEXMTX8";
|
||||
case GX_TEXMTX9:
|
||||
return "GX_TEXMTX9";
|
||||
case GX_IDENTITY:
|
||||
return "GX_IDENTITY";
|
||||
default:
|
||||
return fmt::format("GXTexMtx({})", static_cast<int>(mtx));
|
||||
}
|
||||
}
|
||||
|
||||
inline std::string format_as(const GXPTTexMtx& mtx) {
|
||||
switch (mtx) {
|
||||
case GX_PTTEXMTX0:
|
||||
return "GX_PTTEXMTX0";
|
||||
case GX_PTTEXMTX1:
|
||||
return "GX_PTTEXMTX1";
|
||||
case GX_PTTEXMTX2:
|
||||
return "GX_PTTEXMTX2";
|
||||
case GX_PTTEXMTX3:
|
||||
return "GX_PTTEXMTX3";
|
||||
case GX_PTTEXMTX4:
|
||||
return "GX_PTTEXMTX4";
|
||||
case GX_PTTEXMTX5:
|
||||
return "GX_PTTEXMTX5";
|
||||
case GX_PTTEXMTX6:
|
||||
return "GX_PTTEXMTX6";
|
||||
case GX_PTTEXMTX7:
|
||||
return "GX_PTTEXMTX7";
|
||||
case GX_PTTEXMTX8:
|
||||
return "GX_PTTEXMTX8";
|
||||
case GX_PTTEXMTX9:
|
||||
return "GX_PTTEXMTX9";
|
||||
case GX_PTTEXMTX10:
|
||||
return "GX_PTTEXMTX10";
|
||||
case GX_PTTEXMTX11:
|
||||
return "GX_PTTEXMTX11";
|
||||
case GX_PTTEXMTX12:
|
||||
return "GX_PTTEXMTX12";
|
||||
case GX_PTTEXMTX13:
|
||||
return "GX_PTTEXMTX13";
|
||||
case GX_PTTEXMTX14:
|
||||
return "GX_PTTEXMTX14";
|
||||
case GX_PTTEXMTX15:
|
||||
return "GX_PTTEXMTX15";
|
||||
case GX_PTTEXMTX16:
|
||||
return "GX_PTTEXMTX16";
|
||||
case GX_PTTEXMTX17:
|
||||
return "GX_PTTEXMTX17";
|
||||
case GX_PTTEXMTX18:
|
||||
return "GX_PTTEXMTX18";
|
||||
case GX_PTTEXMTX19:
|
||||
return "GX_PTTEXMTX19";
|
||||
case GX_PTIDENTITY:
|
||||
return "GX_PTIDENTITY";
|
||||
default:
|
||||
return fmt::format("GXPTTexMtx({})", static_cast<int>(mtx));
|
||||
}
|
||||
}
|
||||
|
||||
inline std::string format_as(const GXCompare& comp) {
|
||||
switch (comp) {
|
||||
case GX_NEVER:
|
||||
return "GX_NEVER";
|
||||
case GX_LESS:
|
||||
return "GX_LESS";
|
||||
case GX_EQUAL:
|
||||
return "GX_EQUAL";
|
||||
case GX_LEQUAL:
|
||||
return "GX_LEQUAL";
|
||||
case GX_GREATER:
|
||||
return "GX_GREATER";
|
||||
case GX_NEQUAL:
|
||||
return "GX_NEQUAL";
|
||||
case GX_GEQUAL:
|
||||
return "GX_GEQUAL";
|
||||
case GX_ALWAYS:
|
||||
return "GX_ALWAYS";
|
||||
default:
|
||||
return fmt::format("GXCompare({})", static_cast<int>(comp));
|
||||
}
|
||||
}
|
||||
|
||||
inline std::string format_as(const GXAlphaOp& op) {
|
||||
switch (op) {
|
||||
case GX_AOP_AND:
|
||||
return "GX_AOP_AND";
|
||||
case GX_AOP_OR:
|
||||
return "GX_AOP_OR";
|
||||
case GX_AOP_XOR:
|
||||
return "GX_AOP_XOR";
|
||||
case GX_AOP_XNOR:
|
||||
return "GX_AOP_XNOR";
|
||||
default:
|
||||
return fmt::format("GXAlphaOp({})", static_cast<int>(op));
|
||||
}
|
||||
}
|
||||
|
||||
inline std::string format_as(const GXFogType& type) {
|
||||
switch (type) {
|
||||
case GX_FOG_NONE:
|
||||
return "GX_FOG_NONE";
|
||||
case GX_FOG_PERSP_LIN:
|
||||
return "GX_FOG_PERSP_LIN";
|
||||
case GX_FOG_PERSP_EXP:
|
||||
return "GX_FOG_PERSP_EXP";
|
||||
case GX_FOG_PERSP_EXP2:
|
||||
return "GX_FOG_PERSP_EXP2";
|
||||
case GX_FOG_PERSP_REVEXP:
|
||||
return "GX_FOG_PERSP_REVEXP";
|
||||
case GX_FOG_PERSP_REVEXP2:
|
||||
return "GX_FOG_PERSP_REVEXP2";
|
||||
case GX_FOG_ORTHO_LIN:
|
||||
return "GX_FOG_ORTHO_LIN";
|
||||
case GX_FOG_ORTHO_EXP:
|
||||
return "GX_FOG_ORTHO_EXP";
|
||||
case GX_FOG_ORTHO_EXP2:
|
||||
return "GX_FOG_ORTHO_EXP2";
|
||||
case GX_FOG_ORTHO_REVEXP:
|
||||
return "GX_FOG_ORTHO_REVEXP";
|
||||
case GX_FOG_ORTHO_REVEXP2:
|
||||
return "GX_FOG_ORTHO_REVEXP2";
|
||||
default:
|
||||
return fmt::format("GXFogType({})", static_cast<int>(type));
|
||||
}
|
||||
}
|
||||
|
||||
inline std::string format_as(const GXTexCoordID& id) {
|
||||
switch (id) {
|
||||
case GX_TEXCOORD0:
|
||||
return "GX_TEXCOORD0";
|
||||
case GX_TEXCOORD1:
|
||||
return "GX_TEXCOORD1";
|
||||
case GX_TEXCOORD2:
|
||||
return "GX_TEXCOORD2";
|
||||
case GX_TEXCOORD3:
|
||||
return "GX_TEXCOORD3";
|
||||
case GX_TEXCOORD4:
|
||||
return "GX_TEXCOORD4";
|
||||
case GX_TEXCOORD5:
|
||||
return "GX_TEXCOORD5";
|
||||
case GX_TEXCOORD6:
|
||||
return "GX_TEXCOORD6";
|
||||
case GX_TEXCOORD7:
|
||||
return "GX_TEXCOORD7";
|
||||
case GX_TEXCOORD_NULL:
|
||||
return "GX_TEXCOORD_NULL";
|
||||
default:
|
||||
return fmt::format("GXTexCoordID({})", static_cast<int>(id));
|
||||
}
|
||||
}
|
@ -2,8 +2,13 @@
|
||||
|
||||
#include "../webgpu/gpu.hpp"
|
||||
#include "gx.hpp"
|
||||
#include "gx_fmt.hpp"
|
||||
|
||||
#include <dolphin/gx/GXEnum.h>
|
||||
|
||||
#include <absl/container/flat_hash_map.h>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
|
||||
constexpr bool EnableNormalVisualization = false;
|
||||
constexpr bool EnableDebugPrints = false;
|
||||
@ -157,15 +162,14 @@ static std::string color_arg_reg(GXTevColorArg arg, size_t stageIdx, const Shade
|
||||
CHECK(stage.texMapId >= GX_TEXMAP0 && stage.texMapId <= GX_TEXMAP7, "invalid texture {} for stage {}",
|
||||
static_cast<int>(stage.texMapId), stageIdx);
|
||||
const auto& swap = config.tevSwapTable[stage.tevSwapTex];
|
||||
return fmt::format(FMT_STRING("sampled{}.{}{}{}"), stageIdx, chan_comp(swap.red), chan_comp(swap.green),
|
||||
chan_comp(swap.blue));
|
||||
return fmt::format("sampled{}.{}{}{}", stageIdx, chan_comp(swap.red), chan_comp(swap.green), chan_comp(swap.blue));
|
||||
}
|
||||
case GX_CC_TEXA: {
|
||||
CHECK(stage.texMapId != GX_TEXMAP_NULL, "unmapped texture for stage {}", stageIdx);
|
||||
CHECK(stage.texMapId >= GX_TEXMAP0 && stage.texMapId <= GX_TEXMAP7, "invalid texture {} for stage {}",
|
||||
static_cast<int>(stage.texMapId), stageIdx);
|
||||
const auto& swap = config.tevSwapTable[stage.tevSwapTex];
|
||||
return fmt::format(FMT_STRING("vec3<f32>(sampled{}.{})"), stageIdx, chan_comp(swap.alpha));
|
||||
return fmt::format("vec3<f32>(sampled{}.{})", stageIdx, chan_comp(swap.alpha));
|
||||
}
|
||||
case GX_CC_RASC: {
|
||||
CHECK(stage.channelId != GX_COLOR_NULL, "unmapped color channel for stage {}", stageIdx);
|
||||
@ -176,8 +180,7 @@ static std::string color_arg_reg(GXTevColorArg arg, size_t stageIdx, const Shade
|
||||
static_cast<int>(stage.channelId), stageIdx);
|
||||
u32 idx = stage.channelId - GX_COLOR0A0;
|
||||
const auto& swap = config.tevSwapTable[stage.tevSwapRas];
|
||||
return fmt::format(FMT_STRING("rast{}.{}{}{}"), idx, chan_comp(swap.red), chan_comp(swap.green),
|
||||
chan_comp(swap.blue));
|
||||
return fmt::format("rast{}.{}{}{}", idx, chan_comp(swap.red), chan_comp(swap.green), chan_comp(swap.blue));
|
||||
}
|
||||
case GX_CC_RASA: {
|
||||
CHECK(stage.channelId != GX_COLOR_NULL, "unmapped color channel for stage {}", stageIdx);
|
||||
@ -188,7 +191,7 @@ static std::string color_arg_reg(GXTevColorArg arg, size_t stageIdx, const Shade
|
||||
static_cast<int>(stage.channelId), stageIdx);
|
||||
u32 idx = stage.channelId - GX_COLOR0A0;
|
||||
const auto& swap = config.tevSwapTable[stage.tevSwapRas];
|
||||
return fmt::format(FMT_STRING("vec3<f32>(rast{}.{})"), idx, chan_comp(swap.alpha));
|
||||
return fmt::format("vec3<f32>(rast{}.{})", idx, chan_comp(swap.alpha));
|
||||
}
|
||||
case GX_CC_ONE:
|
||||
return "vec3<f32>(1.0)";
|
||||
@ -345,7 +348,7 @@ static std::string alpha_arg_reg(GXTevAlphaArg arg, size_t stageIdx, const Shade
|
||||
CHECK(stage.texMapId >= GX_TEXMAP0 && stage.texMapId <= GX_TEXMAP7, "invalid texture {} for stage {}",
|
||||
static_cast<int>(stage.texMapId), stageIdx);
|
||||
const auto& swap = config.tevSwapTable[stage.tevSwapTex];
|
||||
return fmt::format(FMT_STRING("sampled{}.{}"), stageIdx, chan_comp(swap.alpha));
|
||||
return fmt::format("sampled{}.{}", stageIdx, chan_comp(swap.alpha));
|
||||
}
|
||||
case GX_CA_RASA: {
|
||||
CHECK(stage.channelId != GX_COLOR_NULL, "unmapped color channel for stage {}", stageIdx);
|
||||
@ -356,7 +359,7 @@ static std::string alpha_arg_reg(GXTevAlphaArg arg, size_t stageIdx, const Shade
|
||||
static_cast<int>(stage.channelId), stageIdx);
|
||||
u32 idx = stage.channelId - GX_COLOR0A0;
|
||||
const auto& swap = config.tevSwapTable[stage.tevSwapRas];
|
||||
return fmt::format(FMT_STRING("rast{}.{}"), idx, chan_comp(swap.alpha));
|
||||
return fmt::format("rast{}.{}", idx, chan_comp(swap.alpha));
|
||||
}
|
||||
case GX_CA_KONST: {
|
||||
switch (stage.kaSel) {
|
||||
@ -445,17 +448,17 @@ static std::string alpha_compare(GXCompare comp, u8 ref, bool& valid) {
|
||||
case GX_NEVER:
|
||||
return "false"s;
|
||||
case GX_LESS:
|
||||
return fmt::format(FMT_STRING("(prev.a < {}f)"), fref);
|
||||
return fmt::format("(prev.a < {}f)", fref);
|
||||
case GX_LEQUAL:
|
||||
return fmt::format(FMT_STRING("(prev.a <= {}f)"), fref);
|
||||
return fmt::format("(prev.a <= {}f)", fref);
|
||||
case GX_EQUAL:
|
||||
return fmt::format(FMT_STRING("(prev.a == {}f)"), fref);
|
||||
return fmt::format("(prev.a == {}f)", fref);
|
||||
case GX_NEQUAL:
|
||||
return fmt::format(FMT_STRING("(prev.a != {}f)"), fref);
|
||||
return fmt::format("(prev.a != {}f)", fref);
|
||||
case GX_GEQUAL:
|
||||
return fmt::format(FMT_STRING("(prev.a >= {}f)"), fref);
|
||||
return fmt::format("(prev.a >= {}f)", fref);
|
||||
case GX_GREATER:
|
||||
return fmt::format(FMT_STRING("(prev.a > {}f)"), fref);
|
||||
return fmt::format("(prev.a > {}f)", fref);
|
||||
case GX_ALWAYS:
|
||||
valid = false;
|
||||
return "true"s;
|
||||
@ -493,11 +496,11 @@ static inline std::string vtx_attr(const ShaderConfig& config, GXAttr attr) {
|
||||
}
|
||||
if (attr == GX_VA_CLR0 || attr == GX_VA_CLR1) {
|
||||
const auto idx = attr - GX_VA_CLR0;
|
||||
return fmt::format(FMT_STRING("in_clr{}"), idx);
|
||||
return fmt::format("in_clr{}", idx);
|
||||
}
|
||||
if (attr >= GX_VA_TEX0 && attr <= GX_VA_TEX7) {
|
||||
const auto idx = attr - GX_VA_TEX0;
|
||||
return fmt::format(FMT_STRING("in_tex{}_uv"), idx);
|
||||
return fmt::format("in_tex{}_uv", idx);
|
||||
}
|
||||
UNLIKELY FATAL("unhandled vtx attr {}", static_cast<int>(attr));
|
||||
}
|
||||
@ -510,15 +513,14 @@ static inline std::string texture_conversion(const TextureConfig& tex, u32 stage
|
||||
break;
|
||||
case GX_TF_RGB565:
|
||||
// Set alpha channel to 1.0
|
||||
out += fmt::format(FMT_STRING("\n sampled{0}.a = 1.0;"), stageIdx);
|
||||
out += fmt::format("\n sampled{0}.a = 1.0;", stageIdx);
|
||||
break;
|
||||
case GX_TF_I4:
|
||||
case GX_TF_I8:
|
||||
// FIXME HACK
|
||||
if (!is_palette_format(tex.loadFmt)) {
|
||||
// Perform intensity conversion
|
||||
out += fmt::format(FMT_STRING("\n sampled{0} = vec4<f32>(intensityF32(sampled{0}.rgb), 0.f, 0.f, 1.f);"),
|
||||
stageIdx);
|
||||
out += fmt::format("\n sampled{0} = vec4<f32>(intensityF32(sampled{0}.rgb), 0.f, 0.f, 1.f);", stageIdx);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -529,7 +531,7 @@ static inline std::string texture_conversion(const TextureConfig& tex, u32 stage
|
||||
case GX_TF_I8:
|
||||
case GX_TF_R8_PC:
|
||||
// Splat R to RGBA
|
||||
out += fmt::format(FMT_STRING("\n sampled{0} = vec4<f32>(sampled{0}.r);"), stageIdx);
|
||||
out += fmt::format("\n sampled{0} = vec4<f32>(sampled{0}.r);", stageIdx);
|
||||
break;
|
||||
}
|
||||
return out;
|
||||
@ -663,52 +665,51 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config, const ShaderInfo& in
|
||||
}
|
||||
|
||||
if (EnableDebugPrints) {
|
||||
Log.report(LOG_INFO, FMT_STRING("Shader config (hash {:x}):"), hash);
|
||||
Log.report(LOG_INFO, "Shader config (hash {:x}):", hash);
|
||||
{
|
||||
for (int i = 0; i < config.tevStageCount; ++i) {
|
||||
const auto& stage = config.tevStages[i];
|
||||
Log.report(LOG_INFO, FMT_STRING(" tevStages[{}]:"), i);
|
||||
Log.report(LOG_INFO, FMT_STRING(" color_a: {}"), TevColorArgNames[stage.colorPass.a]);
|
||||
Log.report(LOG_INFO, FMT_STRING(" color_b: {}"), TevColorArgNames[stage.colorPass.b]);
|
||||
Log.report(LOG_INFO, FMT_STRING(" color_c: {}"), TevColorArgNames[stage.colorPass.c]);
|
||||
Log.report(LOG_INFO, FMT_STRING(" color_d: {}"), TevColorArgNames[stage.colorPass.d]);
|
||||
Log.report(LOG_INFO, FMT_STRING(" alpha_a: {}"), TevAlphaArgNames[stage.alphaPass.a]);
|
||||
Log.report(LOG_INFO, FMT_STRING(" alpha_b: {}"), TevAlphaArgNames[stage.alphaPass.b]);
|
||||
Log.report(LOG_INFO, FMT_STRING(" alpha_c: {}"), TevAlphaArgNames[stage.alphaPass.c]);
|
||||
Log.report(LOG_INFO, FMT_STRING(" alpha_d: {}"), TevAlphaArgNames[stage.alphaPass.d]);
|
||||
Log.report(LOG_INFO, FMT_STRING(" color_op_clamp: {}"), stage.colorOp.clamp);
|
||||
Log.report(LOG_INFO, FMT_STRING(" color_op_op: {}"), stage.colorOp.op);
|
||||
Log.report(LOG_INFO, FMT_STRING(" color_op_bias: {}"), stage.colorOp.bias);
|
||||
Log.report(LOG_INFO, FMT_STRING(" color_op_scale: {}"), stage.colorOp.scale);
|
||||
Log.report(LOG_INFO, FMT_STRING(" color_op_reg_id: {}"), stage.colorOp.outReg);
|
||||
Log.report(LOG_INFO, FMT_STRING(" alpha_op_clamp: {}"), stage.alphaOp.clamp);
|
||||
Log.report(LOG_INFO, FMT_STRING(" alpha_op_op: {}"), stage.alphaOp.op);
|
||||
Log.report(LOG_INFO, FMT_STRING(" alpha_op_bias: {}"), stage.alphaOp.bias);
|
||||
Log.report(LOG_INFO, FMT_STRING(" alpha_op_scale: {}"), stage.alphaOp.scale);
|
||||
Log.report(LOG_INFO, FMT_STRING(" alpha_op_reg_id: {}"), stage.alphaOp.outReg);
|
||||
Log.report(LOG_INFO, FMT_STRING(" kc_sel: {}"), stage.kcSel);
|
||||
Log.report(LOG_INFO, FMT_STRING(" ka_sel: {}"), stage.kaSel);
|
||||
Log.report(LOG_INFO, FMT_STRING(" texCoordId: {}"), stage.texCoordId);
|
||||
Log.report(LOG_INFO, FMT_STRING(" texMapId: {}"), stage.texMapId);
|
||||
Log.report(LOG_INFO, FMT_STRING(" channelId: {}"), stage.channelId);
|
||||
Log.report(LOG_INFO, " tevStages[{}]:", i);
|
||||
Log.report(LOG_INFO, " color_a: {}", TevColorArgNames[stage.colorPass.a]);
|
||||
Log.report(LOG_INFO, " color_b: {}", TevColorArgNames[stage.colorPass.b]);
|
||||
Log.report(LOG_INFO, " color_c: {}", TevColorArgNames[stage.colorPass.c]);
|
||||
Log.report(LOG_INFO, " color_d: {}", TevColorArgNames[stage.colorPass.d]);
|
||||
Log.report(LOG_INFO, " alpha_a: {}", TevAlphaArgNames[stage.alphaPass.a]);
|
||||
Log.report(LOG_INFO, " alpha_b: {}", TevAlphaArgNames[stage.alphaPass.b]);
|
||||
Log.report(LOG_INFO, " alpha_c: {}", TevAlphaArgNames[stage.alphaPass.c]);
|
||||
Log.report(LOG_INFO, " alpha_d: {}", TevAlphaArgNames[stage.alphaPass.d]);
|
||||
Log.report(LOG_INFO, " color_op_clamp: {}", stage.colorOp.clamp);
|
||||
Log.report(LOG_INFO, " color_op_op: {}", stage.colorOp.op);
|
||||
Log.report(LOG_INFO, " color_op_bias: {}", stage.colorOp.bias);
|
||||
Log.report(LOG_INFO, " color_op_scale: {}", stage.colorOp.scale);
|
||||
Log.report(LOG_INFO, " color_op_reg_id: {}", stage.colorOp.outReg);
|
||||
Log.report(LOG_INFO, " alpha_op_clamp: {}", stage.alphaOp.clamp);
|
||||
Log.report(LOG_INFO, " alpha_op_op: {}", stage.alphaOp.op);
|
||||
Log.report(LOG_INFO, " alpha_op_bias: {}", stage.alphaOp.bias);
|
||||
Log.report(LOG_INFO, " alpha_op_scale: {}", stage.alphaOp.scale);
|
||||
Log.report(LOG_INFO, " alpha_op_reg_id: {}", stage.alphaOp.outReg);
|
||||
Log.report(LOG_INFO, " kc_sel: {}", stage.kcSel);
|
||||
Log.report(LOG_INFO, " ka_sel: {}", stage.kaSel);
|
||||
Log.report(LOG_INFO, " texCoordId: {}", stage.texCoordId);
|
||||
Log.report(LOG_INFO, " texMapId: {}", stage.texMapId);
|
||||
Log.report(LOG_INFO, " channelId: {}", stage.channelId);
|
||||
}
|
||||
for (int i = 0; i < config.colorChannels.size(); ++i) {
|
||||
const auto& chan = config.colorChannels[i];
|
||||
Log.report(LOG_INFO, FMT_STRING(" colorChannels[{}]: enabled {} mat {} amb {}"), i, chan.lightingEnabled,
|
||||
chan.matSrc, chan.ambSrc);
|
||||
Log.report(LOG_INFO, " colorChannels[{}]: enabled {} mat {} amb {}", i, chan.lightingEnabled, chan.matSrc,
|
||||
chan.ambSrc);
|
||||
}
|
||||
for (int i = 0; i < config.tcgs.size(); ++i) {
|
||||
const auto& tcg = config.tcgs[i];
|
||||
if (tcg.src != GX_MAX_TEXGENSRC) {
|
||||
Log.report(LOG_INFO, FMT_STRING(" tcg[{}]: src {} mtx {} post {} type {} norm {}"), i, tcg.src, tcg.mtx,
|
||||
tcg.postMtx, tcg.type, tcg.normalize);
|
||||
Log.report(LOG_INFO, " tcg[{}]: src {} mtx {} post {} type {} norm {}", i, tcg.src, tcg.mtx, tcg.postMtx,
|
||||
tcg.type, tcg.normalize);
|
||||
}
|
||||
}
|
||||
Log.report(LOG_INFO, FMT_STRING(" alphaCompare: comp0 {} ref0 {} op {} comp1 {} ref1 {}"),
|
||||
config.alphaCompare.comp0, config.alphaCompare.ref0, config.alphaCompare.op, config.alphaCompare.comp1,
|
||||
config.alphaCompare.ref1);
|
||||
Log.report(LOG_INFO, FMT_STRING(" indexedAttributeCount: {}"), config.indexedAttributeCount);
|
||||
Log.report(LOG_INFO, FMT_STRING(" fogType: {}"), config.fogType);
|
||||
Log.report(LOG_INFO, " alphaCompare: comp0 {} ref0 {} op {} comp1 {} ref1 {}", config.alphaCompare.comp0,
|
||||
config.alphaCompare.ref0, config.alphaCompare.op, config.alphaCompare.comp1, config.alphaCompare.ref1);
|
||||
Log.report(LOG_INFO, " indexedAttributeCount: {}", config.indexedAttributeCount);
|
||||
Log.report(LOG_INFO, " fogType: {}", config.fogType);
|
||||
}
|
||||
}
|
||||
|
||||
@ -742,7 +743,7 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config, const ShaderInfo& in
|
||||
attrName = VtxAttributeNames[attr];
|
||||
}
|
||||
vtxXfrAttrsPre +=
|
||||
fmt::format(FMT_STRING("\n var {} = v_arr_{}[in_dl{}[{}]];"), vtx_attr(config, attr), attrName, div, rem);
|
||||
fmt::format("\n var {} = v_arr_{}[in_dl{}[{}]];", vtx_attr(config, attr), attrName, div, rem);
|
||||
if (addUniformBinding) {
|
||||
std::string_view arrType;
|
||||
if (attr == GX_VA_POS || attr == GX_VA_NRM) {
|
||||
@ -769,7 +770,7 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config, const ShaderInfo& in
|
||||
} else {
|
||||
vtxInAttrs += "\n ";
|
||||
}
|
||||
vtxInAttrs += fmt::format(FMT_STRING("@location({}) in_dl{}: vec4<i32>"), locIdx++, i);
|
||||
vtxInAttrs += fmt::format("@location({}) in_dl{}: vec4<i32>", locIdx++, i);
|
||||
}
|
||||
for (u32 i = 0; i < num2xAttrArrays; ++i) {
|
||||
if (locIdx > 0) {
|
||||
@ -777,7 +778,7 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config, const ShaderInfo& in
|
||||
} else {
|
||||
vtxInAttrs += "\n ";
|
||||
}
|
||||
vtxInAttrs += fmt::format(FMT_STRING("@location({}) in_dl{}: vec2<i32>"), locIdx++, num4xAttrArrays + i);
|
||||
vtxInAttrs += fmt::format("@location({}) in_dl{}: vec2<i32>", locIdx++, num4xAttrArrays + i);
|
||||
}
|
||||
}
|
||||
for (GXAttr attr{}; attr < MaxVtxAttr; attr = GXAttr(attr + 1)) {
|
||||
@ -791,21 +792,22 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config, const ShaderInfo& in
|
||||
vtxInAttrs += "\n ";
|
||||
}
|
||||
if (attr == GX_VA_POS) {
|
||||
vtxInAttrs += fmt::format(FMT_STRING("@location({}) in_pos: vec3<f32>"), locIdx++);
|
||||
vtxInAttrs += fmt::format("@location({}) in_pos: vec3<f32>", locIdx++);
|
||||
} else if (attr == GX_VA_NRM) {
|
||||
vtxInAttrs += fmt::format(FMT_STRING("@location({}) in_nrm: vec3<f32>"), locIdx++);
|
||||
vtxInAttrs += fmt::format("@location({}) in_nrm: vec3<f32>", locIdx++);
|
||||
} else if (attr == GX_VA_CLR0 || attr == GX_VA_CLR1) {
|
||||
vtxInAttrs += fmt::format(FMT_STRING("@location({}) in_clr{}: vec4<f32>"), locIdx++, attr - GX_VA_CLR0);
|
||||
vtxInAttrs += fmt::format("@location({}) in_clr{}: vec4<f32>", locIdx++, attr - GX_VA_CLR0);
|
||||
} else if (attr >= GX_VA_TEX0 && attr <= GX_VA_TEX7) {
|
||||
vtxInAttrs += fmt::format(FMT_STRING("@location({}) in_tex{}_uv: vec2<f32>"), locIdx++, attr - GX_VA_TEX0);
|
||||
vtxInAttrs += fmt::format("@location({}) in_tex{}_uv: vec2<f32>", locIdx++, attr - GX_VA_TEX0);
|
||||
}
|
||||
}
|
||||
vtxXfrAttrsPre += fmt::format(FMT_STRING("\n var mv_pos = mul4x3(ubuf.pos_mtx, vec4<f32>({}, 1.0));"
|
||||
"\n var mv_nrm = normalize(mul4x3(ubuf.nrm_mtx, vec4<f32>({}, 0.0)));"
|
||||
"\n out.pos = mul4x4(ubuf.proj, vec4<f32>(mv_pos, 1.0));"),
|
||||
vtx_attr(config, GX_VA_POS), vtx_attr(config, GX_VA_NRM));
|
||||
vtxXfrAttrsPre += fmt::format(
|
||||
"\n var mv_pos = mul4x3(ubuf.pos_mtx, vec4<f32>({}, 1.0));"
|
||||
"\n var mv_nrm = normalize(mul4x3(ubuf.nrm_mtx, vec4<f32>({}, 0.0)));"
|
||||
"\n out.pos = mul4x4(ubuf.proj, vec4<f32>(mv_pos, 1.0));",
|
||||
vtx_attr(config, GX_VA_POS), vtx_attr(config, GX_VA_NRM));
|
||||
if constexpr (EnableNormalVisualization) {
|
||||
vtxOutAttrs += fmt::format(FMT_STRING("\n @location({}) nrm: vec3<f32>,"), vtxOutIdx++);
|
||||
vtxOutAttrs += fmt::format("\n @location({}) nrm: vec3<f32>,", vtxOutIdx++);
|
||||
vtxXfrAttrsPre += "\n out.nrm = mv_nrm;";
|
||||
}
|
||||
|
||||
@ -831,15 +833,14 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config, const ShaderInfo& in
|
||||
break;
|
||||
}
|
||||
std::string op = fmt::format(
|
||||
FMT_STRING("(({4}mix({0}, {1}, {2}) + {3}){5}){6}"), color_arg_reg(stage.colorPass.a, idx, config, stage),
|
||||
"(({4}mix({0}, {1}, {2}) + {3}){5}){6}", color_arg_reg(stage.colorPass.a, idx, config, stage),
|
||||
color_arg_reg(stage.colorPass.b, idx, config, stage), color_arg_reg(stage.colorPass.c, idx, config, stage),
|
||||
color_arg_reg(stage.colorPass.d, idx, config, stage), tev_op(stage.colorOp.op), tev_bias(stage.colorOp.bias),
|
||||
tev_scale(stage.colorOp.scale));
|
||||
if (stage.colorOp.clamp) {
|
||||
op = fmt::format(FMT_STRING("clamp({}, vec3<f32>(0.0), vec3<f32>(1.0))"), op);
|
||||
op = fmt::format("clamp({}, vec3<f32>(0.0), vec3<f32>(1.0))", op);
|
||||
}
|
||||
fragmentFn +=
|
||||
fmt::format(FMT_STRING("\n // TEV stage {2}\n {0} = vec4<f32>({1}, {0}.a);"), outReg, op, idx);
|
||||
fragmentFn += fmt::format("\n // TEV stage {2}\n {0} = vec4<f32>({1}, {0}.a);", outReg, op, idx);
|
||||
}
|
||||
{
|
||||
std::string outReg;
|
||||
@ -859,14 +860,14 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config, const ShaderInfo& in
|
||||
break;
|
||||
}
|
||||
std::string op = fmt::format(
|
||||
FMT_STRING("(({4}mix({0}, {1}, {2}) + {3}){5}){6}"), alpha_arg_reg(stage.alphaPass.a, idx, config, stage),
|
||||
"(({4}mix({0}, {1}, {2}) + {3}){5}){6}", alpha_arg_reg(stage.alphaPass.a, idx, config, stage),
|
||||
alpha_arg_reg(stage.alphaPass.b, idx, config, stage), alpha_arg_reg(stage.alphaPass.c, idx, config, stage),
|
||||
alpha_arg_reg(stage.alphaPass.d, idx, config, stage), tev_op(stage.alphaOp.op), tev_bias(stage.alphaOp.bias),
|
||||
tev_scale(stage.alphaOp.scale));
|
||||
if (stage.alphaOp.clamp) {
|
||||
op = fmt::format(FMT_STRING("clamp({}, 0.0, 1.0)"), op);
|
||||
op = fmt::format("clamp({}, 0.0, 1.0)", op);
|
||||
}
|
||||
fragmentFn += fmt::format(FMT_STRING("\n {0} = {1};"), outReg, op);
|
||||
fragmentFn += fmt::format("\n {0} = {1};", outReg, op);
|
||||
}
|
||||
}
|
||||
if (info.loadsTevReg.test(0)) {
|
||||
@ -877,10 +878,10 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config, const ShaderInfo& in
|
||||
}
|
||||
for (int i = 1 /* Skip TEVPREV */; i < info.loadsTevReg.size(); ++i) {
|
||||
if (info.loadsTevReg.test(i)) {
|
||||
uniBufAttrs += fmt::format(FMT_STRING("\n tevreg{}: vec4<f32>,"), i - 1);
|
||||
fragmentFnPre += fmt::format(FMT_STRING("\n var tevreg{0} = ubuf.tevreg{0};"), i - 1);
|
||||
uniBufAttrs += fmt::format("\n tevreg{}: vec4<f32>,", i - 1);
|
||||
fragmentFnPre += fmt::format("\n var tevreg{0} = ubuf.tevreg{0};", i - 1);
|
||||
} else if (info.writesTevReg.test(i)) {
|
||||
fragmentFnPre += fmt::format(FMT_STRING("\n var tevreg{0}: vec4<f32>;"), i - 1);
|
||||
fragmentFnPre += fmt::format("\n var tevreg{0}: vec4<f32>;", i - 1);
|
||||
}
|
||||
}
|
||||
bool addedLightStruct = false;
|
||||
@ -909,8 +910,8 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config, const ShaderInfo& in
|
||||
" dist_att: vec3<f32>,\n"
|
||||
"};";
|
||||
if (UsePerPixelLighting) {
|
||||
vtxOutAttrs += fmt::format(FMT_STRING("\n @location({}) mv_pos: vec3<f32>,"), vtxOutIdx++);
|
||||
vtxOutAttrs += fmt::format(FMT_STRING("\n @location({}) mv_nrm: vec3<f32>,"), vtxOutIdx++);
|
||||
vtxOutAttrs += fmt::format("\n @location({}) mv_pos: vec3<f32>,", vtxOutIdx++);
|
||||
vtxOutAttrs += fmt::format("\n @location({}) mv_nrm: vec3<f32>,", vtxOutIdx++);
|
||||
vtxXfrAttrs += fmt::format(FMT_STRING(R"""(
|
||||
out.mv_pos = mv_pos;
|
||||
out.mv_nrm = mv_nrm;)"""));
|
||||
@ -919,16 +920,16 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config, const ShaderInfo& in
|
||||
}
|
||||
|
||||
if (cc.lightingEnabled && cc.ambSrc == GX_SRC_REG) {
|
||||
uniBufAttrs += fmt::format(FMT_STRING("\n cc{0}_amb: vec4<f32>,"), i);
|
||||
uniBufAttrs += fmt::format("\n cc{0}_amb: vec4<f32>,", i);
|
||||
}
|
||||
if (cc.matSrc == GX_SRC_REG) {
|
||||
uniBufAttrs += fmt::format(FMT_STRING("\n cc{0}_mat: vec4<f32>,"), i);
|
||||
uniBufAttrs += fmt::format("\n cc{0}_mat: vec4<f32>,", i);
|
||||
}
|
||||
if (cca.lightingEnabled && cca.ambSrc == GX_SRC_REG) {
|
||||
uniBufAttrs += fmt::format(FMT_STRING("\n cc{0}a_amb: vec4<f32>,"), i);
|
||||
uniBufAttrs += fmt::format("\n cc{0}a_amb: vec4<f32>,", i);
|
||||
}
|
||||
if (cca.matSrc == GX_SRC_REG) {
|
||||
uniBufAttrs += fmt::format(FMT_STRING("\n cc{0}a_mat: vec4<f32>,"), i);
|
||||
uniBufAttrs += fmt::format("\n cc{0}a_mat: vec4<f32>,", i);
|
||||
}
|
||||
|
||||
// Output vertex color if necessary
|
||||
@ -936,8 +937,8 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config, const ShaderInfo& in
|
||||
if (((cc.lightingEnabled && cc.ambSrc == GX_SRC_VTX) || cc.matSrc == GX_SRC_VTX ||
|
||||
(cca.lightingEnabled && cca.matSrc == GX_SRC_VTX) || cca.matSrc == GX_SRC_VTX)) {
|
||||
if (UsePerPixelLighting) {
|
||||
vtxOutAttrs += fmt::format(FMT_STRING("\n @location({}) clr{}: vec4<f32>,"), vtxOutIdx++, vtxColorIdx);
|
||||
vtxXfrAttrs += fmt::format(FMT_STRING("\n out.clr{} = {};"), vtxColorIdx,
|
||||
vtxOutAttrs += fmt::format("\n @location({}) clr{}: vec4<f32>,", vtxOutIdx++, vtxColorIdx);
|
||||
vtxXfrAttrs += fmt::format("\n out.clr{} = {};", vtxColorIdx,
|
||||
vtx_attr(config, static_cast<GXAttr>(GX_VA_CLR0 + vtxColorIdx)));
|
||||
}
|
||||
usesVtxColor = true;
|
||||
@ -948,21 +949,21 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config, const ShaderInfo& in
|
||||
std::string ambSrc, matSrc, lightAttnFn, lightDiffFn;
|
||||
if (cc.ambSrc == GX_SRC_VTX) {
|
||||
if (UsePerPixelLighting) {
|
||||
ambSrc = fmt::format(FMT_STRING("in.clr{}"), vtxColorIdx);
|
||||
ambSrc = fmt::format("in.clr{}", vtxColorIdx);
|
||||
} else {
|
||||
ambSrc = vtx_attr(config, static_cast<GXAttr>(GX_VA_CLR0 + vtxColorIdx));
|
||||
}
|
||||
} else if (cc.ambSrc == GX_SRC_REG) {
|
||||
ambSrc = fmt::format(FMT_STRING("ubuf.cc{0}_amb"), i);
|
||||
ambSrc = fmt::format("ubuf.cc{0}_amb", i);
|
||||
}
|
||||
if (cc.matSrc == GX_SRC_VTX) {
|
||||
if (UsePerPixelLighting) {
|
||||
matSrc = fmt::format(FMT_STRING("in.clr{}"), vtxColorIdx);
|
||||
matSrc = fmt::format("in.clr{}", vtxColorIdx);
|
||||
} else {
|
||||
matSrc = vtx_attr(config, static_cast<GXAttr>(GX_VA_CLR0 + vtxColorIdx));
|
||||
}
|
||||
} else if (cc.matSrc == GX_SRC_REG) {
|
||||
matSrc = fmt::format(FMT_STRING("ubuf.cc{0}_mat"), i);
|
||||
matSrc = fmt::format("ubuf.cc{0}_mat", i);
|
||||
}
|
||||
GXDiffuseFn diffFn = cc.diffFn;
|
||||
if (cc.attnFn == GX_AF_NONE) {
|
||||
@ -994,10 +995,10 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config, const ShaderInfo& in
|
||||
}
|
||||
std::string outVar, posVar;
|
||||
if (UsePerPixelLighting) {
|
||||
outVar = fmt::format(FMT_STRING("rast{}"), i);
|
||||
outVar = fmt::format("rast{}", i);
|
||||
posVar = "in.mv_pos";
|
||||
} else {
|
||||
outVar = fmt::format(FMT_STRING("out.cc{}"), i);
|
||||
outVar = fmt::format("out.cc{}", i);
|
||||
posVar = "mv_pos";
|
||||
}
|
||||
auto lightFunc = fmt::format(FMT_STRING(R"""(
|
||||
@ -1019,25 +1020,24 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config, const ShaderInfo& in
|
||||
}})"""),
|
||||
i, GX::MaxLights, lightAttnFn, lightDiffFn, matSrc, ambSrc, outVar, posVar);
|
||||
if (UsePerPixelLighting) {
|
||||
fragmentFnPre += fmt::format(FMT_STRING("\n var rast{}: vec4<f32>;"), i);
|
||||
fragmentFnPre += fmt::format("\n var rast{}: vec4<f32>;", i);
|
||||
fragmentFnPre += lightFunc;
|
||||
} else {
|
||||
vtxOutAttrs += fmt::format(FMT_STRING("\n @location({}) cc{}: vec4<f32>,"), vtxOutIdx++, i);
|
||||
vtxOutAttrs += fmt::format("\n @location({}) cc{}: vec4<f32>,", vtxOutIdx++, i);
|
||||
vtxXfrAttrs += lightFunc;
|
||||
fragmentFnPre += fmt::format(FMT_STRING("\n var rast{0} = in.cc{0};"), i);
|
||||
fragmentFnPre += fmt::format("\n var rast{0} = in.cc{0};", i);
|
||||
}
|
||||
} else if (cc.matSrc == GX_SRC_VTX) {
|
||||
if (UsePerPixelLighting) {
|
||||
// Color will already be written to clr{}
|
||||
fragmentFnPre += fmt::format(FMT_STRING("\n var rast{0} = in.clr{0};"), vtxColorIdx);
|
||||
fragmentFnPre += fmt::format("\n var rast{0} = in.clr{0};", vtxColorIdx);
|
||||
} else {
|
||||
vtxOutAttrs += fmt::format(FMT_STRING("\n @location({}) cc{}: vec4<f32>,"), vtxOutIdx++, i);
|
||||
vtxXfrAttrs +=
|
||||
fmt::format(FMT_STRING("\n out.cc{} = {};"), i, vtx_attr(config, GXAttr(GX_VA_CLR0 + vtxColorIdx)));
|
||||
fragmentFnPre += fmt::format(FMT_STRING("\n var rast{0} = in.cc{0};"), i);
|
||||
vtxOutAttrs += fmt::format("\n @location({}) cc{}: vec4<f32>,", vtxOutIdx++, i);
|
||||
vtxXfrAttrs += fmt::format("\n out.cc{} = {};", i, vtx_attr(config, GXAttr(GX_VA_CLR0 + vtxColorIdx)));
|
||||
fragmentFnPre += fmt::format("\n var rast{0} = in.cc{0};", i);
|
||||
}
|
||||
} else {
|
||||
fragmentFnPre += fmt::format(FMT_STRING("\n var rast{0} = ubuf.cc{0}_mat;"), i);
|
||||
fragmentFnPre += fmt::format("\n var rast{0} = ubuf.cc{0}_mat;", i);
|
||||
}
|
||||
|
||||
if (usesVtxColor) {
|
||||
@ -1046,7 +1046,7 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config, const ShaderInfo& in
|
||||
}
|
||||
for (int i = 0; i < info.sampledKColors.size(); ++i) {
|
||||
if (info.sampledKColors.test(i)) {
|
||||
uniBufAttrs += fmt::format(FMT_STRING("\n kcolor{}: vec4<f32>,"), i);
|
||||
uniBufAttrs += fmt::format("\n kcolor{}: vec4<f32>,", i);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < info.sampledTexCoords.size(); ++i) {
|
||||
@ -1054,34 +1054,34 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config, const ShaderInfo& in
|
||||
continue;
|
||||
}
|
||||
const auto& tcg = config.tcgs[i];
|
||||
vtxOutAttrs += fmt::format(FMT_STRING("\n @location({}) tex{}_uv: vec2<f32>,"), vtxOutIdx++, i);
|
||||
vtxOutAttrs += fmt::format("\n @location({}) tex{}_uv: vec2<f32>,", vtxOutIdx++, i);
|
||||
if (tcg.src >= GX_TG_TEX0 && tcg.src <= GX_TG_TEX7) {
|
||||
vtxXfrAttrs += fmt::format(FMT_STRING("\n var tc{} = vec4<f32>({}, 0.0, 1.0);"), i,
|
||||
vtxXfrAttrs += fmt::format("\n var tc{} = vec4<f32>({}, 0.0, 1.0);", i,
|
||||
vtx_attr(config, GXAttr(GX_VA_TEX0 + (tcg.src - GX_TG_TEX0))));
|
||||
} else if (tcg.src == GX_TG_POS) {
|
||||
vtxXfrAttrs += fmt::format(FMT_STRING("\n var tc{} = vec4<f32>(in_pos, 1.0);"), i);
|
||||
vtxXfrAttrs += fmt::format("\n var tc{} = vec4<f32>(in_pos, 1.0);", i);
|
||||
} else if (tcg.src == GX_TG_NRM) {
|
||||
vtxXfrAttrs += fmt::format(FMT_STRING("\n var tc{} = vec4<f32>(in_nrm, 1.0);"), i);
|
||||
vtxXfrAttrs += fmt::format("\n var tc{} = vec4<f32>(in_nrm, 1.0);", i);
|
||||
} else
|
||||
UNLIKELY FATAL("unhandled tcg src {}", static_cast<int>(tcg.src));
|
||||
if (tcg.mtx == GX_IDENTITY) {
|
||||
vtxXfrAttrs += fmt::format(FMT_STRING("\n var tc{0}_tmp = tc{0}.xyz;"), i);
|
||||
vtxXfrAttrs += fmt::format("\n var tc{0}_tmp = tc{0}.xyz;", i);
|
||||
} else {
|
||||
u32 texMtxIdx = (tcg.mtx - GX_TEXMTX0) / 3;
|
||||
vtxXfrAttrs += fmt::format(FMT_STRING("\n var tc{0}_tmp = mul{2}(ubuf.texmtx{1}, tc{0});"), i, texMtxIdx,
|
||||
vtxXfrAttrs += fmt::format("\n var tc{0}_tmp = mul{2}(ubuf.texmtx{1}, tc{0});", i, texMtxIdx,
|
||||
info.texMtxTypes[texMtxIdx] == GX_TG_MTX3x4 ? "4x3" : "4x2");
|
||||
}
|
||||
if (tcg.normalize) {
|
||||
vtxXfrAttrs += fmt::format(FMT_STRING("\n tc{0}_tmp = normalize(tc{0}_tmp);"), i);
|
||||
vtxXfrAttrs += fmt::format("\n tc{0}_tmp = normalize(tc{0}_tmp);", i);
|
||||
}
|
||||
if (tcg.postMtx == GX_PTIDENTITY) {
|
||||
vtxXfrAttrs += fmt::format(FMT_STRING("\n var tc{0}_proj = tc{0}_tmp;"), i);
|
||||
vtxXfrAttrs += fmt::format("\n var tc{0}_proj = tc{0}_tmp;", i);
|
||||
} else {
|
||||
u32 postMtxIdx = (tcg.postMtx - GX_PTTEXMTX0) / 3;
|
||||
vtxXfrAttrs += fmt::format(
|
||||
FMT_STRING("\n var tc{0}_proj = mul4x3(ubuf.postmtx{1}, vec4<f32>(tc{0}_tmp.xyz, 1.0));"), i, postMtxIdx);
|
||||
vtxXfrAttrs +=
|
||||
fmt::format("\n var tc{0}_proj = mul4x3(ubuf.postmtx{1}, vec4<f32>(tc{0}_tmp.xyz, 1.0));", i, postMtxIdx);
|
||||
}
|
||||
vtxXfrAttrs += fmt::format(FMT_STRING("\n out.tex{0}_uv = tc{0}_proj.xy;"), i);
|
||||
vtxXfrAttrs += fmt::format("\n out.tex{0}_uv = tc{0}_proj.xy;", i);
|
||||
}
|
||||
for (int i = 0; i < config.tevStages.size(); ++i) {
|
||||
const auto& stage = config.tevStages[i];
|
||||
@ -1091,7 +1091,7 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config, const ShaderInfo& in
|
||||
|| !info.sampledTextures.test(stage.texMapId)) {
|
||||
continue;
|
||||
}
|
||||
std::string uvIn = fmt::format(FMT_STRING("in.tex{0}_uv"), stage.texCoordId);
|
||||
std::string uvIn = fmt::format("in.tex{0}_uv", static_cast<int>(stage.texCoordId));
|
||||
const auto& texConfig = config.textureConfig[stage.texMapId];
|
||||
if (is_palette_format(texConfig.loadFmt)) {
|
||||
std::string_view suffix;
|
||||
@ -1109,13 +1109,12 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config, const ShaderInfo& in
|
||||
// break;
|
||||
}
|
||||
}
|
||||
fragmentFnPre +=
|
||||
fmt::format(FMT_STRING("\n var sampled{0} = textureSamplePalette{3}(tex{1}, tex{1}_samp, {2}, tlut{1});"),
|
||||
i, stage.texMapId, uvIn, suffix);
|
||||
fragmentFnPre += fmt::format("\n var sampled{0} = textureSamplePalette{3}(tex{1}, tex{1}_samp, {2}, tlut{1});",
|
||||
i, static_cast<int>(stage.texMapId), uvIn, suffix);
|
||||
} else {
|
||||
fragmentFnPre += fmt::format(
|
||||
FMT_STRING("\n var sampled{0} = textureSampleBias(tex{1}, tex{1}_samp, {2}, ubuf.tex{1}_lod);"), i,
|
||||
stage.texMapId, uvIn);
|
||||
fragmentFnPre +=
|
||||
fmt::format("\n var sampled{0} = textureSampleBias(tex{1}, tex{1}_samp, {2}, ubuf.tex{1}_lod);", i,
|
||||
static_cast<int>(stage.texMapId), uvIn);
|
||||
}
|
||||
fragmentFnPre += texture_conversion(texConfig, i, stage.texMapId);
|
||||
}
|
||||
@ -1124,17 +1123,17 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config, const ShaderInfo& in
|
||||
switch (info.texMtxTypes[i]) {
|
||||
DEFAULT_FATAL("unhandled tex mtx type {}", static_cast<int>(info.texMtxTypes[i]));
|
||||
case GX_TG_MTX2x4:
|
||||
uniBufAttrs += fmt::format(FMT_STRING("\n texmtx{}: mtx4x2,"), i);
|
||||
uniBufAttrs += fmt::format("\n texmtx{}: mtx4x2,", i);
|
||||
break;
|
||||
case GX_TG_MTX3x4:
|
||||
uniBufAttrs += fmt::format(FMT_STRING("\n texmtx{}: mtx4x3,"), i);
|
||||
uniBufAttrs += fmt::format("\n texmtx{}: mtx4x3,", i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < info.usesPTTexMtx.size(); ++i) {
|
||||
if (info.usesPTTexMtx.test(i)) {
|
||||
uniBufAttrs += fmt::format(FMT_STRING("\n postmtx{}: mtx4x3,"), i);
|
||||
uniBufAttrs += fmt::format("\n postmtx{}: mtx4x3,", i);
|
||||
}
|
||||
}
|
||||
if (info.usesFog) {
|
||||
@ -1182,7 +1181,7 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config, const ShaderInfo& in
|
||||
if (!info.sampledTextures.test(i)) {
|
||||
continue;
|
||||
}
|
||||
uniBufAttrs += fmt::format(FMT_STRING("\n tex{}_lod: f32,"), i);
|
||||
uniBufAttrs += fmt::format("\n tex{}_lod: f32,", i);
|
||||
|
||||
sampBindings += fmt::format(FMT_STRING("\n@group(1) @binding({})\n"
|
||||
"var tex{}_samp: sampler;"),
|
||||
@ -1215,16 +1214,16 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config, const ShaderInfo& in
|
||||
switch (config.alphaCompare.op) {
|
||||
DEFAULT_FATAL("invalid alpha compare op {}", static_cast<int>(config.alphaCompare.op));
|
||||
case GX_AOP_AND:
|
||||
fragmentFn += fmt::format(FMT_STRING("\n if (!({} && {})) {{ discard; }}"), comp0, comp1);
|
||||
fragmentFn += fmt::format("\n if (!({} && {})) {{ discard; }}", comp0, comp1);
|
||||
break;
|
||||
case GX_AOP_OR:
|
||||
fragmentFn += fmt::format(FMT_STRING("\n if (!({} || {})) {{ discard; }}"), comp0, comp1);
|
||||
fragmentFn += fmt::format("\n if (!({} || {})) {{ discard; }}", comp0, comp1);
|
||||
break;
|
||||
case GX_AOP_XOR:
|
||||
fragmentFn += fmt::format(FMT_STRING("\n if (!({} ^^ {})) {{ discard; }}"), comp0, comp1);
|
||||
fragmentFn += fmt::format("\n if (!({} ^^ {})) {{ discard; }}", comp0, comp1);
|
||||
break;
|
||||
case GX_AOP_XNOR:
|
||||
fragmentFn += fmt::format(FMT_STRING("\n if (({} ^^ {})) {{ discard; }}"), comp0, comp1);
|
||||
fragmentFn += fmt::format("\n if (({} ^^ {})) {{ discard; }}", comp0, comp1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1326,12 +1325,12 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {{{8}{7}
|
||||
uniBufAttrs, sampBindings, texBindings, uniformBindings, vtxOutAttrs,
|
||||
vtxInAttrs, vtxXfrAttrs, fragmentFn, fragmentFnPre, vtxXfrAttrsPre, uniformPre);
|
||||
if (EnableDebugPrints) {
|
||||
Log.report(LOG_INFO, FMT_STRING("Generated shader: {}"), shaderSource);
|
||||
Log.report(LOG_INFO, "Generated shader: {}", shaderSource);
|
||||
}
|
||||
|
||||
wgpu::ShaderModuleWGSLDescriptor wgslDescriptor{};
|
||||
wgslDescriptor.code = shaderSource.c_str();
|
||||
const auto label = fmt::format(FMT_STRING("GX Shader {:x}"), hash);
|
||||
const auto label = fmt::format("GX Shader {:x}", hash);
|
||||
const auto shaderDescriptor = wgpu::ShaderModuleDescriptor{
|
||||
.nextInChain = &wgslDescriptor,
|
||||
.label = label.c_str(),
|
||||
|
@ -83,8 +83,8 @@ TextureHandle new_static_texture_2d(uint32_t width, uint32_t height, uint32_t mi
|
||||
offset += dataSize;
|
||||
}
|
||||
if (data.size() != UINT32_MAX && offset < data.size()) {
|
||||
Log.report(LOG_WARNING, FMT_STRING("new_static_texture_2d[{}]: texture used {} bytes, but given {} bytes"), label,
|
||||
offset, data.size());
|
||||
Log.report(LOG_WARNING, "new_static_texture_2d[{}]: texture used {} bytes, but given {} bytes", label, offset,
|
||||
data.size());
|
||||
}
|
||||
return handle;
|
||||
}
|
||||
@ -106,7 +106,7 @@ TextureHandle new_dynamic_texture_2d(uint32_t width, uint32_t height, uint32_t m
|
||||
.mipLevelCount = mips,
|
||||
.sampleCount = 1,
|
||||
};
|
||||
const auto viewLabel = fmt::format(FMT_STRING("{} view"), label);
|
||||
const auto viewLabel = fmt::format("{} view", label);
|
||||
const wgpu::TextureViewDescriptor textureViewDescriptor{
|
||||
.label = viewLabel.c_str(),
|
||||
.format = wgpuFormat,
|
||||
@ -136,7 +136,7 @@ TextureHandle new_render_texture(uint32_t width, uint32_t height, u32 fmt, const
|
||||
.mipLevelCount = 1,
|
||||
.sampleCount = 1,
|
||||
};
|
||||
const auto viewLabel = fmt::format(FMT_STRING("{} view"), label);
|
||||
const auto viewLabel = fmt::format("{} view", label);
|
||||
const wgpu::TextureViewDescriptor textureViewDescriptor{
|
||||
.label = viewLabel.c_str(),
|
||||
.format = wgpuFormat,
|
||||
@ -196,8 +196,7 @@ void write_texture(const TextureRef& ref, ArrayRef<uint8_t> data) noexcept {
|
||||
offset += dataSize;
|
||||
}
|
||||
if (data.size() != UINT32_MAX && offset < data.size()) {
|
||||
Log.report(LOG_WARNING, FMT_STRING("write_texture: texture used {} bytes, but given {} bytes"), offset,
|
||||
data.size());
|
||||
Log.report(LOG_WARNING, "write_texture: texture used {} bytes, but given {} bytes", offset, data.size());
|
||||
}
|
||||
}
|
||||
} // namespace aurora::gfx
|
||||
|
@ -101,13 +101,13 @@ static std::optional<std::string> remap_controller_layout(std::string mapping) {
|
||||
idx++;
|
||||
}
|
||||
if (entries.contains("rightshoulder") && !entries.contains("leftshoulder")) {
|
||||
Log.report(LOG_INFO, FMT_STRING("Remapping GameCube controller layout"));
|
||||
Log.report(LOG_INFO, "Remapping GameCube controller layout");
|
||||
entries.insert_or_assign("back", entries["rightshoulder"]);
|
||||
// TODO trigger buttons may differ per platform
|
||||
entries.insert_or_assign("leftshoulder", "b11");
|
||||
entries.insert_or_assign("rightshoulder", "b10");
|
||||
} else if (entries.contains("leftshoulder") && entries.contains("rightshoulder") && entries.contains("back")) {
|
||||
Log.report(LOG_INFO, FMT_STRING("Controller has standard layout"));
|
||||
Log.report(LOG_INFO, "Controller has standard layout");
|
||||
#if 0
|
||||
auto a = entries["a"sv];
|
||||
entries.insert_or_assign("a"sv, entries["b"sv]);
|
||||
@ -117,7 +117,7 @@ static std::optional<std::string> remap_controller_layout(std::string mapping) {
|
||||
entries.insert_or_assign("x", entries["y"]);
|
||||
entries.insert_or_assign("y", x);
|
||||
} else {
|
||||
Log.report(LOG_ERROR, FMT_STRING("Controller has unsupported layout: {}"), mapping);
|
||||
Log.report(LOG_ERROR, "Controller has unsupported layout: {}", mapping);
|
||||
return {};
|
||||
}
|
||||
for (auto [k, v] : entries) {
|
||||
@ -139,11 +139,11 @@ SDL_JoystickID add_controller(SDL_JoystickID which) noexcept {
|
||||
SDL_free(mapping);
|
||||
if (newMapping) {
|
||||
if (SDL_AddGamepadMapping(newMapping->c_str()) == -1) {
|
||||
Log.report(LOG_ERROR, FMT_STRING("Failed to update controller mapping: {}"), SDL_GetError());
|
||||
Log.report(LOG_ERROR, "Failed to update controller mapping: {}", SDL_GetError());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Log.report(LOG_ERROR, FMT_STRING("Failed to retrieve mapping for controller"));
|
||||
Log.report(LOG_ERROR, "Failed to retrieve mapping for controller");
|
||||
}
|
||||
}
|
||||
GameController controller;
|
||||
@ -329,7 +329,7 @@ void __PADLoadMapping(aurora::input::GameController* controller) {
|
||||
|
||||
controller->m_mappingLoaded = true;
|
||||
|
||||
auto path = fmt::format(FMT_STRING("{}/{}_{:04X}_{:04X}.controller"), basePath, PADGetName(playerIndex),
|
||||
auto path = fmt::format("{}/{}_{:04X}_{:04X}.controller", basePath, PADGetName(playerIndex),
|
||||
controller->m_vid, controller->m_pid);
|
||||
FILE* file = fopen(path.c_str(), "rb");
|
||||
if (file == nullptr) {
|
||||
@ -339,14 +339,14 @@ void __PADLoadMapping(aurora::input::GameController* controller) {
|
||||
uint32_t magic = 0;
|
||||
fread(&magic, 1, sizeof(uint32_t), file);
|
||||
if (magic != SBIG('CTRL')) {
|
||||
fmt::print(FMT_STRING("Invalid controller mapping magic!\n"));
|
||||
aurora::input::Log.report(LOG_WARNING, "Invalid controller mapping magic!");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t version = 0;
|
||||
fread(&version, 1, sizeof(uint32_t), file);
|
||||
if (version != 1) {
|
||||
fmt::print(FMT_STRING("Invalid controller mapping version!\n"));
|
||||
aurora::input::Log.report(LOG_WARNING, "Invalid controller mapping version!");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -724,7 +724,7 @@ void PADSerializeMappings() {
|
||||
if (!controller.second.m_mappingLoaded) {
|
||||
__PADLoadMapping(&controller.second);
|
||||
}
|
||||
FILE* file = fopen(fmt::format(FMT_STRING("{}/{}_{:04X}_{:04X}.controller"), basePath,
|
||||
FILE* file = fopen(fmt::format("{}/{}_{:04X}_{:04X}.controller", basePath,
|
||||
aurora::input::controller_name(controller.second.m_index), controller.second.m_vid,
|
||||
controller.second.m_pid)
|
||||
.c_str(),
|
||||
|
@ -1,12 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <aurora/aurora.h>
|
||||
#include <fmt/base.h>
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
|
||||
using namespace std::string_view_literals;
|
||||
|
||||
@ -43,7 +42,7 @@ using namespace std::string_view_literals;
|
||||
#endif
|
||||
#define FATAL(msg, ...) \
|
||||
{ \
|
||||
Log.report(LOG_FATAL, FMT_STRING(msg), ##__VA_ARGS__); \
|
||||
Log.report(LOG_FATAL, msg, ##__VA_ARGS__); \
|
||||
unreachable(); \
|
||||
}
|
||||
#define ASSERT(cond, msg, ...) \
|
||||
@ -58,12 +57,12 @@ using namespace std::string_view_literals;
|
||||
#define TRY(cond, msg, ...) \
|
||||
if (!(cond)) \
|
||||
UNLIKELY { \
|
||||
Log.report(LOG_ERROR, FMT_STRING(msg), ##__VA_ARGS__); \
|
||||
Log.report(LOG_ERROR, msg, ##__VA_ARGS__); \
|
||||
return false; \
|
||||
}
|
||||
#define TRY_WARN(cond, msg, ...) \
|
||||
if (!(cond)) \
|
||||
UNLIKELY { Log.report(LOG_WARNING, FMT_STRING(msg), ##__VA_ARGS__); }
|
||||
UNLIKELY { Log.report(LOG_WARNING, msg, ##__VA_ARGS__); }
|
||||
|
||||
namespace aurora {
|
||||
extern AuroraConfig g_config;
|
||||
@ -73,10 +72,10 @@ struct Module {
|
||||
explicit Module(const char* name) noexcept : name(name) {}
|
||||
|
||||
template <typename... T>
|
||||
inline void report(AuroraLogLevel level, fmt::format_string<T...> fmt, T&&... args) noexcept {
|
||||
void report(AuroraLogLevel level, fmt::format_string<T...> fmt, T&&... args) noexcept {
|
||||
auto message = fmt::format(fmt, std::forward<T>(args)...);
|
||||
if (g_config.logCallback != nullptr) {
|
||||
g_config.logCallback(level, message.c_str(), message.size());
|
||||
g_config.logCallback(level, name, message.c_str(), message.size());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -287,7 +287,7 @@ static wgpu::BackendType to_wgpu_backend(AuroraBackend backend) {
|
||||
|
||||
bool initialize(AuroraBackend auroraBackend) {
|
||||
if (!g_instance) {
|
||||
Log.report(LOG_INFO, FMT_STRING("Creating WGPU instance"));
|
||||
Log.report(LOG_INFO, "Creating WGPU instance");
|
||||
wgpu::InstanceDescriptor instanceDescriptor{
|
||||
.capabilities =
|
||||
{
|
||||
@ -301,18 +301,18 @@ bool initialize(AuroraBackend auroraBackend) {
|
||||
#endif
|
||||
g_instance = wgpu::CreateInstance(&instanceDescriptor);
|
||||
if (!g_instance) {
|
||||
Log.report(LOG_ERROR, FMT_STRING("Failed to create WGPU instance"));
|
||||
Log.report(LOG_ERROR, "Failed to create WGPU instance");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
const wgpu::BackendType backend = to_wgpu_backend(auroraBackend);
|
||||
#ifdef EMSCRIPTEN
|
||||
if (backend != wgpu::BackendType::WebGPU) {
|
||||
Log.report(LOG_WARNING, FMT_STRING("Backend type {} unsupported"), magic_enum::enum_name(backend));
|
||||
Log.report(LOG_WARNING, "Backend type {} unsupported", magic_enum::enum_name(backend));
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
Log.report(LOG_INFO, FMT_STRING("Attempting to initialize {}"), magic_enum::enum_name(backend));
|
||||
Log.report(LOG_INFO, "Attempting to initialize {}", magic_enum::enum_name(backend));
|
||||
#if 0
|
||||
// D3D12's debug layer is very slow
|
||||
g_dawnInstance->EnableBackendValidation(backend != WGPUBackendType::D3D12);
|
||||
@ -333,7 +333,7 @@ bool initialize(AuroraBackend auroraBackend) {
|
||||
};
|
||||
g_surface = g_instance.CreateSurface(&surfaceDescriptor);
|
||||
if (!g_surface) {
|
||||
Log.report(LOG_ERROR, FMT_STRING("Failed to create surface"));
|
||||
Log.report(LOG_ERROR, "Failed to create surface");
|
||||
return false;
|
||||
}
|
||||
{
|
||||
@ -348,16 +348,16 @@ bool initialize(AuroraBackend auroraBackend) {
|
||||
if (status == wgpu::RequestAdapterStatus::Success) {
|
||||
g_adapter = std::move(adapter);
|
||||
} else {
|
||||
Log.report(LOG_WARNING, FMT_STRING("Adapter request failed: {}"), message);
|
||||
Log.report(LOG_WARNING, "Adapter request failed: {}", message);
|
||||
}
|
||||
});
|
||||
const auto status = g_instance.WaitAny(future, 5000000000);
|
||||
if (status != wgpu::WaitStatus::Success) {
|
||||
Log.report(LOG_ERROR, FMT_STRING("Failed to create adapter: {}"), magic_enum::enum_name(status));
|
||||
Log.report(LOG_ERROR, "Failed to create adapter: {}", magic_enum::enum_name(status));
|
||||
return false;
|
||||
}
|
||||
if (!g_adapter) {
|
||||
Log.report(LOG_ERROR, FMT_STRING("Failed to create adapter"));
|
||||
Log.report(LOG_ERROR, "Failed to create adapter");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -372,8 +372,9 @@ bool initialize(AuroraBackend auroraBackend) {
|
||||
if (description.IsUndefined()) {
|
||||
description = wgpu::StringView("Unknown");
|
||||
}
|
||||
Log.report(LOG_INFO, FMT_STRING("Graphics adapter information\n API: {}\n Device: {} ({})\n Driver: {}"),
|
||||
backendName, adapterName, magic_enum::enum_name(g_adapterInfo.adapterType), description);
|
||||
Log.report(LOG_INFO, "Graphics adapter information\n API: {}\n Device: {} ({})\n Driver: {}",
|
||||
backendName, adapterName, magic_enum::enum_name(g_adapterInfo.adapterType),
|
||||
description);
|
||||
|
||||
{
|
||||
wgpu::Limits supportedLimits{};
|
||||
@ -433,20 +434,20 @@ bool initialize(AuroraBackend auroraBackend) {
|
||||
deviceDescriptor.SetDeviceLostCallback(
|
||||
wgpu::CallbackMode::AllowSpontaneous,
|
||||
[](const wgpu::Device& device, wgpu::DeviceLostReason reason, wgpu::StringView message) {
|
||||
Log.report(LOG_WARNING, FMT_STRING("Device lost: {}"), message);
|
||||
Log.report(LOG_WARNING, "Device lost: {}", message);
|
||||
});
|
||||
const auto future = g_adapter.RequestDevice(
|
||||
&deviceDescriptor, wgpu::CallbackMode::WaitAnyOnly,
|
||||
[](wgpu::RequestDeviceStatus status, wgpu::Device device, wgpu::StringView message) {
|
||||
if (status == wgpu::RequestDeviceStatus::Success) {
|
||||
g_device = std::move(device);
|
||||
} else {
|
||||
Log.report(LOG_WARNING, "Device request failed: {}", message);
|
||||
}
|
||||
});
|
||||
const auto future =
|
||||
g_adapter.RequestDevice(&deviceDescriptor, wgpu::CallbackMode::WaitAnyOnly,
|
||||
[](wgpu::RequestDeviceStatus status, wgpu::Device device, wgpu::StringView message) {
|
||||
if (status == wgpu::RequestDeviceStatus::Success) {
|
||||
g_device = std::move(device);
|
||||
} else {
|
||||
Log.report(LOG_WARNING, FMT_STRING("Device request failed: {}"), message);
|
||||
}
|
||||
});
|
||||
const auto status = g_instance.WaitAny(future, 5000000000);
|
||||
if (status != wgpu::WaitStatus::Success) {
|
||||
Log.report(LOG_ERROR, FMT_STRING("Failed to create device: {}"), magic_enum::enum_name(status));
|
||||
Log.report(LOG_ERROR, "Failed to create device: {}", magic_enum::enum_name(status));
|
||||
return false;
|
||||
}
|
||||
if (!g_device) {
|
||||
@ -470,7 +471,7 @@ bool initialize(AuroraBackend auroraBackend) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
Log.report(level, FMT_STRING("WebGPU message: {}"), message);
|
||||
Log.report(level, "WebGPU message: {}", message);
|
||||
});
|
||||
}
|
||||
g_queue = g_device.GetQueue();
|
||||
@ -478,15 +479,15 @@ bool initialize(AuroraBackend auroraBackend) {
|
||||
wgpu::SurfaceCapabilities surfaceCapabilities;
|
||||
const wgpu::Status status = g_surface.GetCapabilities(g_adapter, &surfaceCapabilities);
|
||||
if (status != wgpu::Status::Success) {
|
||||
Log.report(LOG_ERROR, FMT_STRING("Failed to get surface capabilities: {}"), magic_enum::enum_name(status));
|
||||
Log.report(LOG_ERROR, "Failed to get surface capabilities: {}", magic_enum::enum_name(status));
|
||||
return false;
|
||||
}
|
||||
if (surfaceCapabilities.formatCount == 0) {
|
||||
Log.report(LOG_ERROR, FMT_STRING("Surface has no formats"));
|
||||
Log.report(LOG_ERROR, "Surface has no formats");
|
||||
return false;
|
||||
}
|
||||
if (surfaceCapabilities.presentModeCount == 0) {
|
||||
Log.report(LOG_ERROR, FMT_STRING("Surface has no present modes"));
|
||||
Log.report(LOG_ERROR, "Surface has no present modes");
|
||||
return false;
|
||||
}
|
||||
auto surfaceFormat = surfaceCapabilities.formats[0];
|
||||
@ -496,7 +497,7 @@ bool initialize(AuroraBackend auroraBackend) {
|
||||
} else if (surfaceFormat == wgpu::TextureFormat::BGRA8UnormSrgb) {
|
||||
surfaceFormat = wgpu::TextureFormat::BGRA8Unorm;
|
||||
}
|
||||
Log.report(LOG_INFO, FMT_STRING("Using surface format {}, present mode {}"), magic_enum::enum_name(surfaceFormat),
|
||||
Log.report(LOG_INFO, "Using surface format {}, present mode {}", magic_enum::enum_name(surfaceFormat),
|
||||
magic_enum::enum_name(presentMode));
|
||||
const auto size = window::get_window_size();
|
||||
g_graphicsConfig = GraphicsConfig{
|
||||
|
@ -3,7 +3,13 @@
|
||||
#include <emscripten.h>
|
||||
#endif
|
||||
|
||||
#include <string_view>
|
||||
|
||||
static inline bool operator==(const wgpu::Extent3D& lhs, const wgpu::Extent3D& rhs) {
|
||||
return lhs.width == rhs.width && lhs.height == rhs.height && lhs.depthOrArrayLayers == rhs.depthOrArrayLayers;
|
||||
}
|
||||
static inline bool operator!=(const wgpu::Extent3D& lhs, const wgpu::Extent3D& rhs) { return !(lhs == rhs); }
|
||||
|
||||
namespace wgpu {
|
||||
inline std::string_view format_as(wgpu::StringView str) { return str; }
|
||||
} // namespace wgpu
|
||||
|
104
lib/window.cpp
104
lib/window.cpp
@ -5,41 +5,69 @@
|
||||
#include "input.hpp"
|
||||
#include "internal.hpp"
|
||||
|
||||
#include <aurora/aurora.h>
|
||||
#include <aurora/event.h>
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_error.h>
|
||||
#include <SDL3/SDL_events.h>
|
||||
#include <SDL3/SDL_properties.h>
|
||||
#include <SDL3/SDL_render.h>
|
||||
#include <SDL3/SDL_surface.h>
|
||||
#include <SDL3/SDL_video.h>
|
||||
#include <SDL3/SDL_init.h>
|
||||
#include <SDL3/SDL_hints.h>
|
||||
#include <SDL3/SDL_stdinc.h>
|
||||
#include <SDL3/SDL_pixels.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
namespace aurora::window {
|
||||
static Module Log("aurora::window");
|
||||
namespace {
|
||||
Module Log("aurora::window");
|
||||
|
||||
static SDL_Window* g_window;
|
||||
static SDL_Renderer* g_renderer;
|
||||
static AuroraWindowSize g_windowSize;
|
||||
static std::vector<AuroraEvent> g_events;
|
||||
SDL_Window* g_window;
|
||||
SDL_Renderer* g_renderer;
|
||||
AuroraWindowSize g_windowSize;
|
||||
std::vector<AuroraEvent> g_events;
|
||||
|
||||
static inline bool operator==(const AuroraWindowSize& lhs, const AuroraWindowSize& rhs) {
|
||||
inline bool operator==(const AuroraWindowSize& lhs, const AuroraWindowSize& rhs) {
|
||||
return lhs.width == rhs.width && lhs.height == rhs.height && lhs.fb_width == rhs.fb_width &&
|
||||
lhs.fb_height == rhs.fb_height && lhs.scale == rhs.scale;
|
||||
}
|
||||
|
||||
static void resize_swapchain(bool force) noexcept {
|
||||
void resize_swapchain() noexcept {
|
||||
const auto size = get_window_size();
|
||||
if (!force && size == g_windowSize) {
|
||||
if (size == g_windowSize) {
|
||||
return;
|
||||
}
|
||||
if (size.scale != g_windowSize.scale) {
|
||||
if (g_windowSize.scale > 0.f) {
|
||||
Log.report(LOG_INFO, FMT_STRING("Display scale changed to {}"), size.scale);
|
||||
Log.report(LOG_INFO, "Display scale changed to {}", size.scale);
|
||||
}
|
||||
}
|
||||
g_windowSize = size;
|
||||
webgpu::resize_swapchain(size.fb_width, size.fb_height);
|
||||
}
|
||||
|
||||
void set_window_icon() noexcept {
|
||||
if (g_config.iconRGBA8 == nullptr) {
|
||||
return;
|
||||
}
|
||||
auto* iconSurface =
|
||||
SDL_CreateSurfaceFrom(static_cast<int>(g_config.iconWidth), static_cast<int>(g_config.iconHeight),
|
||||
SDL_GetPixelFormatForMasks(32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000),
|
||||
g_config.iconRGBA8, static_cast<int>(4 * g_config.iconWidth));
|
||||
ASSERT(iconSurface != nullptr, "Failed to create icon surface: {}", SDL_GetError());
|
||||
TRY_WARN(SDL_SetWindowIcon(g_window, iconSurface), "Failed to set window icon: {}", SDL_GetError());
|
||||
SDL_DestroySurface(iconSurface);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
const AuroraEvent* poll_events() {
|
||||
g_events.clear();
|
||||
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event) != 0) {
|
||||
while (SDL_PollEvent(&event)) {
|
||||
imgui::process_event(event);
|
||||
|
||||
switch (event.type) {
|
||||
@ -65,7 +93,7 @@ const AuroraEvent* poll_events() {
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED: {
|
||||
resize_swapchain(false);
|
||||
resize_swapchain();
|
||||
g_events.push_back(AuroraEvent{
|
||||
.type = AURORA_DISPLAY_SCALE_CHANGED,
|
||||
.windowSize = get_window_size(),
|
||||
@ -73,7 +101,7 @@ const AuroraEvent* poll_events() {
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED: {
|
||||
resize_swapchain(false);
|
||||
resize_swapchain();
|
||||
g_events.push_back(AuroraEvent{
|
||||
.type = AURORA_WINDOW_RESIZED,
|
||||
.windowSize = get_window_size(),
|
||||
@ -100,6 +128,8 @@ const AuroraEvent* poll_events() {
|
||||
g_events.push_back(AuroraEvent{
|
||||
.type = AURORA_EXIT,
|
||||
});
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
g_events.push_back(AuroraEvent{
|
||||
@ -113,21 +143,8 @@ const AuroraEvent* poll_events() {
|
||||
return g_events.data();
|
||||
}
|
||||
|
||||
static void set_window_icon() noexcept {
|
||||
if (g_config.iconRGBA8 == nullptr) {
|
||||
return;
|
||||
}
|
||||
auto* iconSurface =
|
||||
SDL_CreateSurfaceFrom(g_config.iconWidth, g_config.iconHeight,
|
||||
SDL_GetPixelFormatForMasks(32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000),
|
||||
g_config.iconRGBA8, 4 * g_config.iconWidth);
|
||||
ASSERT(iconSurface != nullptr, "Failed to create icon surface: {}", SDL_GetError());
|
||||
TRY_WARN(SDL_SetWindowIcon(g_window, iconSurface), "Failed to set window icon: {}", SDL_GetError());
|
||||
SDL_DestroySurface(iconSurface);
|
||||
}
|
||||
|
||||
bool create_window(AuroraBackend backend) {
|
||||
Uint32 flags = SDL_WINDOW_HIGH_PIXEL_DENSITY;
|
||||
SDL_WindowFlags flags = SDL_WINDOW_HIGH_PIXEL_DENSITY;
|
||||
#if TARGET_OS_IOS || TARGET_OS_TV
|
||||
flags |= SDL_WINDOW_FULLSCREEN;
|
||||
#else
|
||||
@ -157,30 +174,30 @@ bool create_window(AuroraBackend backend) {
|
||||
break;
|
||||
}
|
||||
#ifdef __SWITCH__
|
||||
uint32_t width = 1280;
|
||||
uint32_t height = 720;
|
||||
Sint32 width = 1280;
|
||||
Sint32 height = 720;
|
||||
#else
|
||||
uint32_t width = g_config.windowWidth;
|
||||
uint32_t height = g_config.windowHeight;
|
||||
auto width = static_cast<Sint32>(g_config.windowWidth);
|
||||
auto height = static_cast<Sint32>(g_config.windowHeight);
|
||||
if (width == 0 || height == 0) {
|
||||
width = 1280;
|
||||
height = 960;
|
||||
}
|
||||
|
||||
int32_t x = g_config.windowPosX;
|
||||
int32_t y = g_config.windowPosY;
|
||||
if (x < 0 || y < 0) {
|
||||
x = SDL_WINDOWPOS_UNDEFINED;
|
||||
y = SDL_WINDOWPOS_UNDEFINED;
|
||||
Sint32 posX = g_config.windowPosX;
|
||||
Sint32 posY = g_config.windowPosY;
|
||||
if (posX < 0 || posY < 0) {
|
||||
posX = SDL_WINDOWPOS_UNDEFINED;
|
||||
posY = SDL_WINDOWPOS_UNDEFINED;
|
||||
}
|
||||
|
||||
#endif
|
||||
const auto props = SDL_CreateProperties();
|
||||
TRY(SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, g_config.appName), "Failed to set {}: {}",
|
||||
SDL_PROP_WINDOW_CREATE_TITLE_STRING, SDL_GetError());
|
||||
TRY(SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, x), "Failed to set {}: {}",
|
||||
TRY(SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, posX), "Failed to set {}: {}",
|
||||
SDL_PROP_WINDOW_CREATE_X_NUMBER, SDL_GetError());
|
||||
TRY(SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, y), "Failed to set {}: {}",
|
||||
TRY(SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, posY), "Failed to set {}: {}",
|
||||
SDL_PROP_WINDOW_CREATE_Y_NUMBER, SDL_GetError());
|
||||
TRY(SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, width), "Failed to set {}: {}",
|
||||
SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, SDL_GetError());
|
||||
@ -190,7 +207,7 @@ bool create_window(AuroraBackend backend) {
|
||||
SDL_PROP_WINDOW_CREATE_FLAGS_NUMBER, SDL_GetError());
|
||||
g_window = SDL_CreateWindowWithProperties(props);
|
||||
if (g_window == nullptr) {
|
||||
Log.report(LOG_ERROR, FMT_STRING("Failed to create window: {}"), SDL_GetError());
|
||||
Log.report(LOG_ERROR, "Failed to create window: {}", SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
set_window_icon();
|
||||
@ -208,7 +225,7 @@ bool create_renderer() {
|
||||
"Failed to set {}: {}", SDL_PROP_RENDERER_CREATE_PRESENT_VSYNC_NUMBER, SDL_GetError());
|
||||
g_renderer = SDL_CreateRendererWithProperties(props);
|
||||
if (g_renderer == nullptr) {
|
||||
Log.report(LOG_ERROR, FMT_STRING("Failed to create renderer: {}"), SDL_GetError());
|
||||
Log.report(LOG_ERROR, "Failed to create renderer: {}", SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -260,10 +277,13 @@ void shutdown() {
|
||||
}
|
||||
|
||||
AuroraWindowSize get_window_size() {
|
||||
int width, height, fb_w, fb_h;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
int fb_w = 0;
|
||||
int fb_h = 0;
|
||||
ASSERT(SDL_GetWindowSize(g_window, &width, &height), "Failed to get window size: {}", SDL_GetError());
|
||||
ASSERT(SDL_GetWindowSizeInPixels(g_window, &fb_w, &fb_h), "Failed to get window size in pixels: {}", SDL_GetError());
|
||||
float scale = SDL_GetWindowDisplayScale(g_window);
|
||||
const float scale = SDL_GetWindowDisplayScale(g_window);
|
||||
return {
|
||||
.width = static_cast<uint32_t>(width),
|
||||
.height = static_cast<uint32_t>(height),
|
||||
|
Loading…
x
Reference in New Issue
Block a user