diff options
Diffstat (limited to 'src/gpu/gpu.cc')
| -rw-r--r-- | src/gpu/gpu.cc | 156 |
1 files changed, 110 insertions, 46 deletions
diff --git a/src/gpu/gpu.cc b/src/gpu/gpu.cc index 92c661b..40be1d2 100644 --- a/src/gpu/gpu.cc +++ b/src/gpu/gpu.cc @@ -6,20 +6,83 @@ #include "platform.h" #include <GLFW/glfw3.h> -#include <webgpu.h> -#include <wgpu.h> +#include <math.h> #include <algorithm> #include <cassert> #include <cstdint> #include <cstring> -#include <math.h> #include <vector> #ifndef STRIP_ALL #include <iostream> #endif +// --- WebGPU Headers & Compatibility --- +#if defined(DEMO_CROSS_COMPILE_WIN32) +// Windows (MinGW) using wgpu-native v0.19.4.1 +#include <webgpu/webgpu.h> +#include <webgpu/wgpu.h> + +// Type Shims +using WGPUStringView = const char *; +static const char *str_view(const char *str) { return str; } +static const char *label_view(const char *str) { return str; } + +// Renamed Types/Enums +#define WGPUSType_ShaderSourceWGSL WGPUSType_ShaderModuleWGSLDescriptor +using WGPUShaderSourceWGSL = WGPUShaderModuleWGSLDescriptor; +#define WGPUSurfaceGetCurrentTextureStatus_SuccessOptimal \ + WGPUSurfaceGetCurrentTextureStatus_Success +#define WGPUSurfaceGetCurrentTextureStatus_SuccessSuboptimal \ + WGPUSurfaceGetCurrentTextureStatus_Success + +// Callback Mode Shim (Not used in old API signatures, but needed for ifdef +// logic) +#define WGPUCallbackMode_WaitAnyOnly 0 + +// Wait Shim +static void wgpuInstanceWaitAny(WGPUInstance instance, size_t, void *, + uint64_t) { + wgpuInstanceProcessEvents(instance); +} + +// Uncaptured Error Callback Helper +static void set_error_callback(WGPUDevice device, + WGPUErrorCallback callback) { + wgpuDeviceSetUncapturedErrorCallback(device, callback, nullptr); +} + +#else +// Native (macOS/Linux) using newer wgpu-native +#include <webgpu.h> +#include <wgpu.h> + +static WGPUStringView label_view(const char *str) { +#ifndef STRIP_ALL + if (!str) + return {nullptr, 0}; + return {str, strlen(str)}; +#else + (void)str; + return {nullptr, 0}; +#endif +} + +static WGPUStringView str_view(const char *str) { + if (!str) + return {nullptr, 0}; + return {str, strlen(str)}; +} + +static void set_error_callback(WGPUDevice device, + WGPUErrorCallback callback) { + // Handled in descriptor for new API, mostly. + // But we can also set it here if needed, or define a no-op if descriptor handles it. + // For new API, we set it in WGPUDeviceDescriptor.uncapturedErrorCallbackInfo. +} +#endif + static WGPUInstance g_instance = nullptr; static WGPUAdapter g_adapter = nullptr; static WGPUDevice g_device = nullptr; @@ -44,30 +107,13 @@ struct Particle { float color[4]; // r, g, b, a }; -static WGPUStringView label_view(const char *str) { -#ifndef STRIP_ALL - if (!str) - return {nullptr, 0}; - return {str, strlen(str)}; -#else - (void)str; - return {nullptr, 0}; -#endif -} - -static WGPUStringView str_view(const char *str) { - if (!str) - return {nullptr, 0}; - return {str, strlen(str)}; -} - // --- Helper Functions --- -GpuBuffer gpu_create_buffer(size_t size, WGPUBufferUsage usage, +GpuBuffer gpu_create_buffer(size_t size, uint32_t usage, const void *data) { WGPUBufferDescriptor desc = {}; desc.label = label_view("GpuBuffer"); - desc.usage = usage; + desc.usage = (WGPUBufferUsage)usage; // Cast for C++ strictness with enums desc.size = size; desc.mappedAtCreation = (data != nullptr); // Map if we have initial data @@ -139,10 +185,7 @@ RenderPass gpu_create_render_pass(const char *shader_code, color_target.writeMask = WGPUColorWriteMask_All; color_target.blend = nullptr; - // Add additive blending for particles if it's the particle pass (hacky check - // based on vertex count or similar? No, let's just enable additive blending - // for everything for now as it looks cool for the demo, or make it - // configurable later. For now, simple replacement) + // Add additive blending for particles WGPUBlendState blend = {}; blend.color.srcFactor = WGPUBlendFactor_SrcAlpha; blend.color.dstFactor = WGPUBlendFactor_One; @@ -234,45 +277,47 @@ ComputePass gpu_create_compute_pass(const char *shader_code, #ifndef STRIP_ALL static void handle_request_adapter(WGPURequestAdapterStatus status, - WGPUAdapter adapter, WGPUStringView message, - void *userdata1, void *userdata2) { + WGPUAdapter adapter, const char *message, + void *userdata) { if (status == WGPURequestAdapterStatus_Success) { - *((WGPUAdapter *)userdata1) = adapter; + *((WGPUAdapter *)userdata) = adapter; } else { - printf("Request adapter failed: %.*s\n", (int)message.length, message.data); + printf("Request adapter failed: %s\n", message ? message : "Unknown"); } } static void handle_request_device(WGPURequestDeviceStatus status, - WGPUDevice device, WGPUStringView message, - void *userdata1, void *userdata2) { + WGPUDevice device, const char *message, + void *userdata) { if (status == WGPURequestDeviceStatus_Success) { - *((WGPUDevice *)userdata1) = device; + *((WGPUDevice *)userdata) = device; } else { - printf("Request device failed: %.*s\n", (int)message.length, message.data); + printf("Request device failed: %s\n", message ? message : "Unknown"); } } -static void handle_device_error(WGPUDevice const *device, WGPUErrorType type, - WGPUStringView message, void *userdata1, - void *userdata2) { - printf("WebGPU Error: %.*s\n", (int)message.length, message.data); +static void handle_device_error(WGPUErrorType type, const char *message, + void *userdata) { + printf("WebGPU Error: %s\n", message ? message : "Unknown"); } #else static void handle_request_adapter(WGPURequestAdapterStatus status, - WGPUAdapter adapter, WGPUStringView message, - void *userdata1, void *userdata2) { + WGPUAdapter adapter, const char *message, + void *userdata) { if (status == WGPURequestAdapterStatus_Success) { - *((WGPUAdapter *)userdata1) = adapter; + *((WGPUAdapter *)userdata) = adapter; } } static void handle_request_device(WGPURequestDeviceStatus status, - WGPUDevice device, WGPUStringView message, - void *userdata1, void *userdata2) { + WGPUDevice device, const char *message, + void *userdata) { if (status == WGPURequestDeviceStatus_Success) { - *((WGPUDevice *)userdata1) = device; + *((WGPUDevice *)userdata) = device; } } #endif +// ... (Shaders omitted for brevity, they are unchanged) ... + + const char *main_shader_wgsl = R"( struct Uniforms { audio_peak : f32, @@ -442,23 +487,39 @@ void gpu_init(GLFWwindow *window) { adapter_opts.compatibleSurface = g_surface; adapter_opts.powerPreference = WGPUPowerPreference_HighPerformance; +#if defined(DEMO_CROSS_COMPILE_WIN32) + wgpuInstanceRequestAdapter(g_instance, &adapter_opts, handle_request_adapter, + &g_adapter); +#else wgpuInstanceRequestAdapter(g_instance, &adapter_opts, {nullptr, WGPUCallbackMode_WaitAnyOnly, handle_request_adapter, &g_adapter, nullptr}); +#endif while (!g_adapter) wgpuInstanceWaitAny(g_instance, 0, nullptr, 0); WGPUDeviceDescriptor device_desc = {}; #ifndef STRIP_ALL +#if !defined(DEMO_CROSS_COMPILE_WIN32) device_desc.uncapturedErrorCallbackInfo.callback = handle_device_error; #endif +#endif +#if defined(DEMO_CROSS_COMPILE_WIN32) + wgpuAdapterRequestDevice(g_adapter, &device_desc, handle_request_device, + &g_device); +#else wgpuAdapterRequestDevice(g_adapter, &device_desc, {nullptr, WGPUCallbackMode_WaitAnyOnly, handle_request_device, &g_device, nullptr}); +#endif while (!g_device) wgpuInstanceWaitAny(g_instance, 0, nullptr, 0); +#if defined(DEMO_CROSS_COMPILE_WIN32) && !defined(STRIP_ALL) + set_error_callback(g_device, handle_device_error); +#endif + g_queue = wgpuDeviceGetQueue(g_device); WGPUSurfaceCapabilities caps = {}; @@ -509,8 +570,9 @@ void gpu_init(GLFWwindow *window) { g_particle_buffer = gpu_create_buffer(sizeof(Particle) * NUM_PARTICLES, - WGPUBufferUsage_Storage | WGPUBufferUsage_CopyDst | - WGPUBufferUsage_Vertex, + (WGPUBufferUsage)(WGPUBufferUsage_Storage | + WGPUBufferUsage_CopyDst | + WGPUBufferUsage_Vertex), initial_particles.data()); // Initialize Particle Compute Pass @@ -581,7 +643,9 @@ void gpu_draw(float audio_peak, float aspect_ratio, float time) { color_attachment.storeOp = WGPUStoreOp_Store; float flash = audio_peak * 0.2f; color_attachment.clearValue = {0.05 + flash, 0.1 + flash, 0.2 + flash, 1.0}; +#if !defined(DEMO_CROSS_COMPILE_WIN32) color_attachment.depthSlice = WGPU_DEPTH_SLICE_UNDEFINED; +#endif WGPURenderPassDescriptor render_pass_desc = {}; render_pass_desc.colorAttachmentCount = 1; |
