From 72207ea4eeee2f2d402e84f5046defdd57311586 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Beaufort?= Date: Mon, 3 Jun 2024 14:17:47 +0200 Subject: [PATCH] WebGPU: Add uncapturedErrorCallbackInfo to requestDevice descriptor --- src/generated_struct_info32.json | 11 +++++++++-- src/generated_struct_info64.json | 11 +++++++++-- src/library_webgpu.js | 22 ++++++++++++++++++++++ src/struct_info.json | 8 +++++++- system/include/webgpu/webgpu.h | 8 ++++++++ system/include/webgpu/webgpu_cpp.h | 8 ++++++++ system/lib/webgpu/webgpu_cpp.cpp | 14 ++++++++++++++ test/webgpu_basic_rendering.cpp | 11 +++++------ 8 files changed, 82 insertions(+), 11 deletions(-) diff --git a/src/generated_struct_info32.json b/src/generated_struct_info32.json index a3ad41a64e7ab..e209a6a6a238c 100644 --- a/src/generated_struct_info32.json +++ b/src/generated_struct_info32.json @@ -961,7 +961,7 @@ "stencilWriteMask": 52 }, "WGPUDeviceDescriptor": { - "__size__": 36, + "__size__": 48, "defaultQueue": 20, "deviceLostCallback": 28, "deviceLostUserdata": 32, @@ -969,7 +969,8 @@ "nextInChain": 0, "requiredFeatureCount": 8, "requiredFeatures": 12, - "requiredLimits": 16 + "requiredLimits": 16, + "uncapturedErrorCallbackInfo": 36 }, "WGPUExtent3D": { "__size__": 12, @@ -1355,6 +1356,12 @@ "mipLevelCount": 20, "nextInChain": 0 }, + "WGPUUncapturedErrorCallbackInfo": { + "__size__": 12, + "callback": 4, + "nextInChain": 0, + "userdata": 8 + }, "WGPUVertexAttribute": { "__size__": 24, "format": 0, diff --git a/src/generated_struct_info64.json b/src/generated_struct_info64.json index 8a63f6cb4ce0c..b802a0a1201ce 100644 --- a/src/generated_struct_info64.json +++ b/src/generated_struct_info64.json @@ -961,7 +961,7 @@ "stencilWriteMask": 56 }, "WGPUDeviceDescriptor": { - "__size__": 72, + "__size__": 96, "defaultQueue": 40, "deviceLostCallback": 56, "deviceLostUserdata": 64, @@ -969,7 +969,8 @@ "nextInChain": 0, "requiredFeatureCount": 16, "requiredFeatures": 24, - "requiredLimits": 32 + "requiredLimits": 32, + "uncapturedErrorCallbackInfo": 72 }, "WGPUExtent3D": { "__size__": 12, @@ -1355,6 +1356,12 @@ "mipLevelCount": 28, "nextInChain": 0 }, + "WGPUUncapturedErrorCallbackInfo": { + "__size__": 24, + "callback": 8, + "nextInChain": 0, + "userdata": 16 + }, "WGPUVertexAttribute": { "__size__": 24, "format": 0, diff --git a/src/library_webgpu.js b/src/library_webgpu.js index 5a849eb5141a7..d7ac006f2f474 100644 --- a/src/library_webgpu.js +++ b/src/library_webgpu.js @@ -2639,6 +2639,8 @@ var LibraryWebGPU = { var deviceLostCallbackPtr = {{{ makeGetValue('descriptor', C_STRUCTS.WGPUDeviceDescriptor.deviceLostCallback, '*') }}}; var deviceLostUserdataPtr = {{{ makeGetValue('descriptor', C_STRUCTS.WGPUDeviceDescriptor.deviceLostUserdata, '*') }}}; + var uncapturedErrorCallbackPtr = {{{ makeGetValue('descriptor', C_STRUCTS.WGPUDeviceDescriptor.uncapturedErrorCallbackInfo + C_STRUCTS.WGPUUncapturedErrorCallbackInfo.callback, '*') }}}; + var uncapturedErrorUserDataPtr = {{{ makeGetValue('descriptor', C_STRUCTS.WGPUDeviceDescriptor.uncapturedErrorCallbackInfo + C_STRUCTS.WGPUUncapturedErrorCallbackInfo.userdata, '*') }}}; var labelPtr = {{{ makeGetValue('descriptor', C_STRUCTS.WGPUDeviceDescriptor.label, '*') }}}; if (labelPtr) desc["label"] = UTF8ToString(labelPtr); @@ -2656,6 +2658,26 @@ var LibraryWebGPU = { WebGPU.Int_DeviceLostReason[info.reason], info.message, deviceLostUserdataPtr)); }); } + if (uncapturedErrorCallbackPtr) { + device.onuncapturederror = function(ev) { + // This will skip the callback if the runtime is no longer alive. + callUserCallback(() => { + // WGPUErrorType type, const char* message, void* userdata + var Validation = 0x00000001; + var OutOfMemory = 0x00000002; + var type; + #if ASSERTIONS + assert(typeof GPUValidationError != 'undefined'); + assert(typeof GPUOutOfMemoryError != 'undefined'); + #endif + if (ev.error instanceof GPUValidationError) type = Validation; + else if (ev.error instanceof GPUOutOfMemoryError) type = OutOfMemory; + // TODO: Implement GPUInternalError + + WebGPU.errorCallback(uncapturedErrorCallbackPtr, type, ev.error.message, uncapturedErrorUserDataPtr); + }); + }; + } {{{ makeDynCall('vippp', 'callback') }}}({{{ gpu.RequestDeviceStatus.Success }}}, deviceId, 0, userdata); }); }, function(ex) { diff --git a/src/struct_info.json b/src/struct_info.json index f58975e80ef57..fd42cf82c3fc1 100644 --- a/src/struct_info.json +++ b/src/struct_info.json @@ -1557,6 +1557,11 @@ "arrayLayerCount", "aspect" ], + "WGPUUncapturedErrorCallbackInfo": [ + "nextInChain", + "callback", + "userdata" + ], "WGPUVertexAttribute": [ "format", "offset", @@ -1693,7 +1698,8 @@ "requiredLimits", "defaultQueue", "deviceLostCallback", - "deviceLostUserdata" + "deviceLostUserdata", + "uncapturedErrorCallbackInfo" ], "WGPURenderPassDescriptor": [ "nextInChain", diff --git a/system/include/webgpu/webgpu.h b/system/include/webgpu/webgpu.h index 826cc7e477839..53de160abc7aa 100644 --- a/system/include/webgpu/webgpu.h +++ b/system/include/webgpu/webgpu.h @@ -153,6 +153,7 @@ struct WGPUTextureBindingLayout; struct WGPUTextureBindingViewDimensionDescriptor; struct WGPUTextureDataLayout; struct WGPUTextureViewDescriptor; +struct WGPUUncapturedErrorCallbackInfo; struct WGPUVertexAttribute; struct WGPUBindGroupDescriptor; struct WGPUBindGroupLayoutEntry; @@ -1174,6 +1175,12 @@ typedef struct WGPUTextureViewDescriptor { WGPUTextureAspect aspect; } WGPUTextureViewDescriptor WGPU_STRUCTURE_ATTRIBUTE; +typedef struct WGPUUncapturedErrorCallbackInfo { + WGPUChainedStruct const * nextInChain; + WGPUErrorCallback callback; + void * userdata; +} WGPUUncapturedErrorCallbackInfo WGPU_STRUCTURE_ATTRIBUTE; + typedef struct WGPUVertexAttribute { WGPUVertexFormat format; uint64_t offset; @@ -1331,6 +1338,7 @@ typedef struct WGPUDeviceDescriptor { WGPUQueueDescriptor defaultQueue; WGPUDeviceLostCallback deviceLostCallback; void * deviceLostUserdata; + WGPUUncapturedErrorCallbackInfo uncapturedErrorCallbackInfo; } WGPUDeviceDescriptor WGPU_STRUCTURE_ATTRIBUTE; typedef struct WGPURenderPassDescriptor { diff --git a/system/include/webgpu/webgpu_cpp.h b/system/include/webgpu/webgpu_cpp.h index 56836b0429122..59e151919d24b 100644 --- a/system/include/webgpu/webgpu_cpp.h +++ b/system/include/webgpu/webgpu_cpp.h @@ -670,6 +670,7 @@ namespace wgpu { struct TextureBindingViewDimensionDescriptor; struct TextureDataLayout; struct TextureViewDescriptor; + struct UncapturedErrorCallbackInfo; struct VertexAttribute; struct BindGroupDescriptor; struct BindGroupLayoutEntry; @@ -1631,6 +1632,12 @@ namespace wgpu { TextureAspect aspect = TextureAspect::All; }; + struct UncapturedErrorCallbackInfo { + ChainedStruct const * nextInChain = nullptr; + ErrorCallback callback = nullptr; + void * userdata = nullptr; + }; + struct VertexAttribute { VertexFormat format; uint64_t offset; @@ -1788,6 +1795,7 @@ namespace wgpu { QueueDescriptor defaultQueue; DeviceLostCallback deviceLostCallback = nullptr; void * deviceLostUserdata = nullptr; + UncapturedErrorCallbackInfo uncapturedErrorCallbackInfo; }; struct RenderPassDescriptor { diff --git a/system/lib/webgpu/webgpu_cpp.cpp b/system/lib/webgpu/webgpu_cpp.cpp index 13cb4d69441b3..ef965a2fba886 100644 --- a/system/lib/webgpu/webgpu_cpp.cpp +++ b/system/lib/webgpu/webgpu_cpp.cpp @@ -1524,6 +1524,18 @@ template static_assert(offsetof(TextureViewDescriptor, aspect) == offsetof(WGPUTextureViewDescriptor, aspect), "offsetof mismatch for TextureViewDescriptor::aspect"); + // UncapturedErrorCallbackInfo + + static_assert(sizeof(UncapturedErrorCallbackInfo) == sizeof(WGPUUncapturedErrorCallbackInfo), "sizeof mismatch for UncapturedErrorCallbackInfo"); + static_assert(alignof(UncapturedErrorCallbackInfo) == alignof(WGPUUncapturedErrorCallbackInfo), "alignof mismatch for UncapturedErrorCallbackInfo"); + + static_assert(offsetof(UncapturedErrorCallbackInfo, nextInChain) == offsetof(WGPUUncapturedErrorCallbackInfo, nextInChain), + "offsetof mismatch for UncapturedErrorCallbackInfo::nextInChain"); + static_assert(offsetof(UncapturedErrorCallbackInfo, callback) == offsetof(WGPUUncapturedErrorCallbackInfo, callback), + "offsetof mismatch for UncapturedErrorCallbackInfo::callback"); + static_assert(offsetof(UncapturedErrorCallbackInfo, userdata) == offsetof(WGPUUncapturedErrorCallbackInfo, userdata), + "offsetof mismatch for UncapturedErrorCallbackInfo::userdata"); + // VertexAttribute static_assert(sizeof(VertexAttribute) == sizeof(WGPUVertexAttribute), "sizeof mismatch for VertexAttribute"); @@ -1841,6 +1853,8 @@ template "offsetof mismatch for DeviceDescriptor::deviceLostCallback"); static_assert(offsetof(DeviceDescriptor, deviceLostUserdata) == offsetof(WGPUDeviceDescriptor, deviceLostUserdata), "offsetof mismatch for DeviceDescriptor::deviceLostUserdata"); + static_assert(offsetof(DeviceDescriptor, uncapturedErrorCallbackInfo) == offsetof(WGPUDeviceDescriptor, uncapturedErrorCallbackInfo), + "offsetof mismatch for DeviceDescriptor::uncapturedErrorCallbackInfo"); // RenderPassDescriptor diff --git a/test/webgpu_basic_rendering.cpp b/test/webgpu_basic_rendering.cpp index ef7c746bf2b78..24cf40b75fccb 100644 --- a/test/webgpu_basic_rendering.cpp +++ b/test/webgpu_basic_rendering.cpp @@ -54,7 +54,11 @@ void GetAdapter(void (*callback)(wgpu::Adapter)) { } void GetDevice(void (*callback)(wgpu::Device)) { - adapter.RequestDevice(nullptr, [](WGPURequestDeviceStatus status, WGPUDevice cDevice, const char* message, void* userdata) { + wgpu::DeviceDescriptor desc{}; + desc.uncapturedErrorCallbackInfo = {nullptr, [](WGPUErrorType type, char const* message, void*) { + printf("%d: %s\n", type, message); + }, nullptr}; + adapter.RequestDevice(&desc, [](WGPURequestDeviceStatus status, WGPUDevice cDevice, const char* message, void* userdata) { if (message) { printf("RequestDevice: %s\n", message); } @@ -66,11 +70,6 @@ void GetDevice(void (*callback)(wgpu::Device)) { } void init() { - device.SetUncapturedErrorCallback( - [](WGPUErrorType errorType, const char* message, void*) { - printf("%d: %s\n", errorType, message); - }, nullptr); - queue = device.GetQueue(); wgpu::ShaderModule shaderModule{};