summaryrefslogtreecommitdiff
path: root/src/platform
diff options
context:
space:
mode:
authorskal <pascal.massimino@gmail.com>2026-02-08 08:33:55 +0100
committerskal <pascal.massimino@gmail.com>2026-02-08 08:33:55 +0100
commit16c2cdce6ad1d89d3c537f2c2cff743449925125 (patch)
tree44792b3f8909dba5622143179c95787fd4de5149 /src/platform
parentd19aec6690bdf515435f4052275828b061c3f71f (diff)
feat(platform): Centralize platform-specific WebGPU code and improve shader composition
Diffstat (limited to 'src/platform')
-rw-r--r--src/platform/platform.cc87
-rw-r--r--src/platform/platform.h84
2 files changed, 170 insertions, 1 deletions
diff --git a/src/platform/platform.cc b/src/platform/platform.cc
index 29b3af3..2b8529a 100644
--- a/src/platform/platform.cc
+++ b/src/platform/platform.cc
@@ -5,6 +5,7 @@
#include "platform/platform.h"
#include "glfw3webgpu.h"
#include <GLFW/glfw3.h>
+#include <cstdio>
// --- Callbacks ---
@@ -128,4 +129,88 @@ WGPUSurface platform_create_wgpu_surface(WGPUInstance instance,
double platform_get_time() {
return glfwGetTime();
-} \ No newline at end of file
+}
+
+// --- WebGPU Request Helpers ---
+
+#if defined(DEMO_CROSS_COMPILE_WIN32)
+static void _platform_adapter_cb_win32(WGPURequestAdapterStatus status,
+ WGPUAdapter adapter, const char* message,
+ void* userdata) {
+ if (status == WGPURequestAdapterStatus_Success) {
+ *((WGPUAdapter*)userdata) = adapter;
+ } else {
+ printf("Request adapter failed: %s\n", message ? message : "Unknown");
+ }
+}
+
+void platform_wgpu_request_adapter(WGPUInstance instance,
+ const WGPURequestAdapterOptions* options,
+ WGPUAdapter* out_adapter) {
+ wgpuInstanceRequestAdapter(instance, options, _platform_adapter_cb_win32,
+ out_adapter);
+}
+
+static void _platform_device_cb_win32(WGPURequestDeviceStatus status,
+ WGPUDevice device, const char* message,
+ void* userdata) {
+ if (status == WGPURequestDeviceStatus_Success) {
+ *((WGPUDevice*)userdata) = device;
+ } else {
+ printf("Request device failed: %s\n", message ? message : "Unknown");
+ }
+}
+
+void platform_wgpu_request_device(WGPUAdapter adapter,
+ const WGPUDeviceDescriptor* descriptor,
+ WGPUDevice* out_device) {
+ wgpuAdapterRequestDevice(adapter, descriptor, _platform_device_cb_win32,
+ out_device);
+}
+
+#else
+
+static void _platform_adapter_cb_native(WGPURequestAdapterStatus status,
+ WGPUAdapter adapter,
+ WGPUStringView message, void* userdata,
+ void* userdata2) {
+ (void)userdata2;
+ if (status == WGPURequestAdapterStatus_Success) {
+ *((WGPUAdapter*)userdata) = adapter;
+ } else {
+ printf("Request adapter failed: %.*s\n", (int)message.length, message.data);
+ }
+}
+
+void platform_wgpu_request_adapter(WGPUInstance instance,
+ const WGPURequestAdapterOptions* options,
+ WGPUAdapter* out_adapter) {
+ WGPURequestAdapterCallbackInfo cb = {};
+ cb.mode = WGPUCallbackMode_WaitAnyOnly;
+ cb.callback = _platform_adapter_cb_native;
+ cb.userdata1 = out_adapter;
+ wgpuInstanceRequestAdapter(instance, options, cb);
+}
+
+static void _platform_device_cb_native(WGPURequestDeviceStatus status,
+ WGPUDevice device,
+ WGPUStringView message, void* userdata,
+ void* userdata2) {
+ (void)userdata2;
+ if (status == WGPURequestDeviceStatus_Success) {
+ *((WGPUDevice*)userdata) = device;
+ } else {
+ printf("Request device failed: %.*s\n", (int)message.length, message.data);
+ }
+}
+
+void platform_wgpu_request_device(WGPUAdapter adapter,
+ const WGPUDeviceDescriptor* descriptor,
+ WGPUDevice* out_device) {
+ WGPURequestDeviceCallbackInfo cb = {};
+ cb.mode = WGPUCallbackMode_WaitAnyOnly;
+ cb.callback = _platform_device_cb_native;
+ cb.userdata1 = out_device;
+ wgpuAdapterRequestDevice(adapter, descriptor, cb);
+}
+#endif
diff --git a/src/platform/platform.h b/src/platform/platform.h
index 0a98850..ddea7af 100644
--- a/src/platform/platform.h
+++ b/src/platform/platform.h
@@ -22,6 +22,9 @@
#define WGPUCallbackMode_WaitAnyOnly 0
typedef WGPUShaderModuleWGSLDescriptor WGPUShaderSourceWGSL;
+// Texture compatibility typedefs
+typedef WGPUImageCopyTexture WGPU_TEX_COPY_INFO;
+typedef WGPUTextureDataLayout WGPU_TEX_DATA_LAYOUT;
static inline const char* str_view(const char* str) {
return str;
@@ -39,10 +42,44 @@ platform_wgpu_set_error_callback(WGPUDevice device,
wgpuDeviceSetUncapturedErrorCallback(device, callback, nullptr);
}
+// Helper to create a WGPUShaderModuleDescriptor with platform-specific chain
+static inline WGPUShaderModuleDescriptor platform_create_shader_module_descriptor(
+ const char* shader_code) {
+ WGPUShaderSourceWGSL* wgsl_src = new WGPUShaderSourceWGSL();
+ wgsl_src->chain.sType = WGPUSType_ShaderSourceWGSL;
+ wgsl_src->code = str_view(shader_code);
+
+ WGPUShaderModuleDescriptor shader_desc = {};
+ shader_desc.nextInChain = &wgsl_src->chain;
+ shader_desc.label = label_view(nullptr); // Use label_view for cross-platform compatibility
+
+ return shader_desc;
+}
+
+// Macro to set the depth stencil state for render pipelines
+#define PLATFORM_SET_PIPELINE_DEPTH_STENCIL(pipeline_desc, depth_stencil_state_ptr) \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Wuninitialized\"") \
+ _Pragma("clang diagnostic ignored \"-Wmissing-field-initializers\"") \
+ do { \
+ if (depth_stencil_state_ptr) { \
+ if (defined(DEMO_CROSS_COMPILE_WIN32)) { \
+ (pipeline_desc).depthStencilState = *(depth_stencil_state_ptr); \
+ } else { \
+ (pipeline_desc).depthStencil = (depth_stencil_state_ptr); \
+ } \
+ } \
+ } while (0) \
+ _Pragma("clang diagnostic pop")
+
#else
#include <webgpu.h>
#include <wgpu.h>
+// Texture compatibility typedefs
+typedef WGPUTexelCopyTextureInfo WGPU_TEX_COPY_INFO;
+typedef WGPUTexelCopyBufferLayout WGPU_TEX_DATA_LAYOUT;
+
static inline WGPUStringView str_view(const char* str) {
if (!str)
return {nullptr, 0};
@@ -69,8 +106,55 @@ platform_wgpu_set_error_callback(WGPUDevice device,
// Handled in descriptor for new API, but provided for compatibility if needed
// elsewhere
}
+
+// Helper to create a WGPUShaderModuleDescriptor with platform-specific chain
+static inline WGPUShaderModuleDescriptor platform_create_shader_module_descriptor(
+ const char* shader_code) {
+ WGPUShaderModuleDescriptor shader_desc = {};
+ // Need to dynamically allocate wgsl_src, as it needs to persist for the lifetime of shader_desc.
+ WGPUShaderSourceWGSL* wgsl_src = new WGPUShaderSourceWGSL();
+ wgsl_src->chain.sType = WGPUSType_ShaderSourceWGSL;
+ wgsl_src->code = str_view(shader_code);
+
+ shader_desc.nextInChain = &wgsl_src->chain;
+ shader_desc.label = label_view(nullptr);
+ return shader_desc;
+}
+
+// Macro to set the depth stencil state for render pipelines
+#define PLATFORM_SET_PIPELINE_DEPTH_STENCIL(pipeline_desc, depth_stencil_state_ptr) \
+ do { \
+ (pipeline_desc).depthStencil = (depth_stencil_state_ptr); \
+ } while (0)
#endif
+// Helper to extract error message from platform-specific string type
+static inline const char* platform_wgpu_get_error_message(
+#if defined(DEMO_CROSS_COMPILE_WIN32)
+ const char* message
+#else
+ WGPUStringView message
+#endif
+) {
+#if defined(DEMO_CROSS_COMPILE_WIN32)
+ return message ? message : "Unknown";
+#else
+ // Warning: Returns raw pointer to view data, typically not null-terminated!
+ // Use '%.*s' printf format with message.length if possible.
+ // This helper is best effort.
+ return message.data;
+#endif
+}
+
+// Platform-agnostic WebGPU request helpers
+void platform_wgpu_request_adapter(WGPUInstance instance,
+ const WGPURequestAdapterOptions* options,
+ WGPUAdapter* out_adapter);
+
+void platform_wgpu_request_device(WGPUAdapter adapter,
+ const WGPUDeviceDescriptor* descriptor,
+ WGPUDevice* out_device);
+
// Forward declare GLFWwindow to avoid including the full header here.
struct GLFWwindow;