summaryrefslogtreecommitdiff
path: root/src/gpu/gpu.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu/gpu.cc')
-rw-r--r--src/gpu/gpu.cc156
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;