From 54f88c49d563241cf4ed1571c6a541b88388ac54 Mon Sep 17 00:00:00 2001 From: Simon Kallweit Date: Tue, 11 Mar 2025 15:38:53 +0100 Subject: [PATCH 1/4] update to latest stable dawn version --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0b253da9..edb19903 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -124,7 +124,7 @@ set(SLANG_RHI_FETCH_OPTIX_URL "https://developer.download.nvidia.com/redist/opti # Fetch Dawn options option(SLANG_RHI_FETCH_DAWN "Fetch Dawn" ON) -set(SLANG_RHI_FETCH_DAWN_VERSION "131.0.6738.0" CACHE STRING "Dawn version to fetch") +set(SLANG_RHI_FETCH_DAWN_VERSION "135.0.7049.80" CACHE STRING "Dawn version to fetch") if(SLANG_RHI_BUILD_SHARED) From adde52db09bd6c91649f32989b134a11db52dac5 Mon Sep 17 00:00:00 2001 From: Simon Kallweit Date: Tue, 11 Mar 2025 15:39:16 +0100 Subject: [PATCH 2/4] update api header --- src/wgpu/wgpu-api.h | 85 +++++++---------------------------- tools/extract-webgpu-procs.py | 3 ++ 2 files changed, 20 insertions(+), 68 deletions(-) diff --git a/src/wgpu/wgpu-api.h b/src/wgpu/wgpu-api.h index 0e44f289..71673721 100644 --- a/src/wgpu/wgpu-api.h +++ b/src/wgpu/wgpu-api.h @@ -10,37 +10,37 @@ // clang-format off #define SLANG_RHI_WGPU_PROCS(x) \ + /* TODO(374150686): Remove these Emscripten specific declarations from the */ \ + /* header once they are fully deprecated. */ \ x(AdapterInfoFreeMembers) \ x(AdapterPropertiesMemoryHeapsFreeMembers) \ + x(AdapterPropertiesSubgroupMatrixConfigsFreeMembers) \ x(CreateInstance) \ - x(DrmFormatCapabilitiesFreeMembers) \ - x(GetInstanceFeatures) \ + x(DawnDrmFormatCapabilitiesFreeMembers) \ + x(GetInstanceCapabilities) \ x(GetProcAddress) \ - x(GetProcAddress2) \ x(SharedBufferMemoryEndAccessStateFreeMembers) \ x(SharedTextureMemoryEndAccessStateFreeMembers) \ + x(SupportedWGSLLanguageFeaturesFreeMembers) \ + x(SupportedFeaturesFreeMembers) \ x(SurfaceCapabilitiesFreeMembers) \ /* Procs of Adapter */ \ x(AdapterCreateDevice) \ - x(AdapterEnumerateFeatures) \ + x(AdapterGetFeatures) \ x(AdapterGetFormatCapabilities) \ x(AdapterGetInfo) \ x(AdapterGetInstance) \ x(AdapterGetLimits) \ x(AdapterHasFeature) \ x(AdapterRequestDevice) \ - x(AdapterRequestDevice2) \ - x(AdapterRequestDeviceF) \ x(AdapterAddRef) \ x(AdapterRelease) \ /* Procs of BindGroup */ \ x(BindGroupSetLabel) \ - x(BindGroupSetLabel2) \ x(BindGroupAddRef) \ x(BindGroupRelease) \ /* Procs of BindGroupLayout */ \ x(BindGroupLayoutSetLabel) \ - x(BindGroupLayoutSetLabel2) \ x(BindGroupLayoutAddRef) \ x(BindGroupLayoutRelease) \ /* Procs of Buffer */ \ @@ -51,16 +51,14 @@ x(BufferGetSize) \ x(BufferGetUsage) \ x(BufferMapAsync) \ - x(BufferMapAsync2) \ - x(BufferMapAsyncF) \ + x(BufferReadMappedRange) \ x(BufferSetLabel) \ - x(BufferSetLabel2) \ x(BufferUnmap) \ + x(BufferWriteMappedRange) \ x(BufferAddRef) \ x(BufferRelease) \ /* Procs of CommandBuffer */ \ x(CommandBufferSetLabel) \ - x(CommandBufferSetLabel2) \ x(CommandBufferAddRef) \ x(CommandBufferRelease) \ /* Procs of CommandEncoder */ \ @@ -73,15 +71,11 @@ x(CommandEncoderCopyTextureToTexture) \ x(CommandEncoderFinish) \ x(CommandEncoderInjectValidationError) \ - x(CommandEncoderInjectValidationError2) \ x(CommandEncoderInsertDebugMarker) \ - x(CommandEncoderInsertDebugMarker2) \ x(CommandEncoderPopDebugGroup) \ x(CommandEncoderPushDebugGroup) \ - x(CommandEncoderPushDebugGroup2) \ x(CommandEncoderResolveQuerySet) \ x(CommandEncoderSetLabel) \ - x(CommandEncoderSetLabel2) \ x(CommandEncoderWriteBuffer) \ x(CommandEncoderWriteTimestamp) \ x(CommandEncoderAddRef) \ @@ -91,13 +85,11 @@ x(ComputePassEncoderDispatchWorkgroupsIndirect) \ x(ComputePassEncoderEnd) \ x(ComputePassEncoderInsertDebugMarker) \ - x(ComputePassEncoderInsertDebugMarker2) \ x(ComputePassEncoderPopDebugGroup) \ x(ComputePassEncoderPushDebugGroup) \ - x(ComputePassEncoderPushDebugGroup2) \ x(ComputePassEncoderSetBindGroup) \ + x(ComputePassEncoderSetImmediateData) \ x(ComputePassEncoderSetLabel) \ - x(ComputePassEncoderSetLabel2) \ x(ComputePassEncoderSetPipeline) \ x(ComputePassEncoderWriteTimestamp) \ x(ComputePassEncoderAddRef) \ @@ -105,7 +97,6 @@ /* Procs of ComputePipeline */ \ x(ComputePipelineGetBindGroupLayout) \ x(ComputePipelineSetLabel) \ - x(ComputePipelineSetLabel2) \ x(ComputePipelineAddRef) \ x(ComputePipelineRelease) \ /* Procs of Device */ \ @@ -115,12 +106,9 @@ x(DeviceCreateCommandEncoder) \ x(DeviceCreateComputePipeline) \ x(DeviceCreateComputePipelineAsync) \ - x(DeviceCreateComputePipelineAsync2) \ - x(DeviceCreateComputePipelineAsyncF) \ x(DeviceCreateErrorBuffer) \ x(DeviceCreateErrorExternalTexture) \ x(DeviceCreateErrorShaderModule) \ - x(DeviceCreateErrorShaderModule2) \ x(DeviceCreateErrorTexture) \ x(DeviceCreateExternalTexture) \ x(DeviceCreatePipelineLayout) \ @@ -128,36 +116,27 @@ x(DeviceCreateRenderBundleEncoder) \ x(DeviceCreateRenderPipeline) \ x(DeviceCreateRenderPipelineAsync) \ - x(DeviceCreateRenderPipelineAsync2) \ - x(DeviceCreateRenderPipelineAsyncF) \ x(DeviceCreateSampler) \ x(DeviceCreateShaderModule) \ - x(DeviceCreateSwapChain) \ x(DeviceCreateTexture) \ x(DeviceDestroy) \ - x(DeviceEnumerateFeatures) \ x(DeviceForceLoss) \ - x(DeviceForceLoss2) \ x(DeviceGetAHardwareBufferProperties) \ x(DeviceGetAdapter) \ + x(DeviceGetAdapterInfo) \ + x(DeviceGetFeatures) \ x(DeviceGetLimits) \ + x(DeviceGetLostFuture) \ x(DeviceGetQueue) \ - x(DeviceGetSupportedSurfaceUsage) \ x(DeviceHasFeature) \ x(DeviceImportSharedBufferMemory) \ x(DeviceImportSharedFence) \ x(DeviceImportSharedTextureMemory) \ x(DeviceInjectError) \ - x(DeviceInjectError2) \ x(DevicePopErrorScope) \ - x(DevicePopErrorScope2) \ - x(DevicePopErrorScopeF) \ x(DevicePushErrorScope) \ - x(DeviceSetDeviceLostCallback) \ x(DeviceSetLabel) \ - x(DeviceSetLabel2) \ x(DeviceSetLoggingCallback) \ - x(DeviceSetUncapturedErrorCallback) \ x(DeviceTick) \ x(DeviceValidateTextureDescriptor) \ x(DeviceAddRef) \ @@ -167,23 +146,19 @@ x(ExternalTextureExpire) \ x(ExternalTextureRefresh) \ x(ExternalTextureSetLabel) \ - x(ExternalTextureSetLabel2) \ x(ExternalTextureAddRef) \ x(ExternalTextureRelease) \ /* Procs of Instance */ \ x(InstanceCreateSurface) \ - x(InstanceEnumerateWGSLLanguageFeatures) \ + x(InstanceGetWGSLLanguageFeatures) \ x(InstanceHasWGSLLanguageFeature) \ x(InstanceProcessEvents) \ x(InstanceRequestAdapter) \ - x(InstanceRequestAdapter2) \ - x(InstanceRequestAdapterF) \ x(InstanceWaitAny) \ x(InstanceAddRef) \ x(InstanceRelease) \ /* Procs of PipelineLayout */ \ x(PipelineLayoutSetLabel) \ - x(PipelineLayoutSetLabel2) \ x(PipelineLayoutAddRef) \ x(PipelineLayoutRelease) \ /* Procs of QuerySet */ \ @@ -191,17 +166,13 @@ x(QuerySetGetCount) \ x(QuerySetGetType) \ x(QuerySetSetLabel) \ - x(QuerySetSetLabel2) \ x(QuerySetAddRef) \ x(QuerySetRelease) \ /* Procs of Queue */ \ x(QueueCopyExternalTextureForBrowser) \ x(QueueCopyTextureForBrowser) \ x(QueueOnSubmittedWorkDone) \ - x(QueueOnSubmittedWorkDone2) \ - x(QueueOnSubmittedWorkDoneF) \ x(QueueSetLabel) \ - x(QueueSetLabel2) \ x(QueueSubmit) \ x(QueueWriteBuffer) \ x(QueueWriteTexture) \ @@ -209,7 +180,6 @@ x(QueueRelease) \ /* Procs of RenderBundle */ \ x(RenderBundleSetLabel) \ - x(RenderBundleSetLabel2) \ x(RenderBundleAddRef) \ x(RenderBundleRelease) \ /* Procs of RenderBundleEncoder */ \ @@ -219,14 +189,12 @@ x(RenderBundleEncoderDrawIndirect) \ x(RenderBundleEncoderFinish) \ x(RenderBundleEncoderInsertDebugMarker) \ - x(RenderBundleEncoderInsertDebugMarker2) \ x(RenderBundleEncoderPopDebugGroup) \ x(RenderBundleEncoderPushDebugGroup) \ - x(RenderBundleEncoderPushDebugGroup2) \ x(RenderBundleEncoderSetBindGroup) \ + x(RenderBundleEncoderSetImmediateData) \ x(RenderBundleEncoderSetIndexBuffer) \ x(RenderBundleEncoderSetLabel) \ - x(RenderBundleEncoderSetLabel2) \ x(RenderBundleEncoderSetPipeline) \ x(RenderBundleEncoderSetVertexBuffer) \ x(RenderBundleEncoderAddRef) \ @@ -241,18 +209,16 @@ x(RenderPassEncoderEndOcclusionQuery) \ x(RenderPassEncoderExecuteBundles) \ x(RenderPassEncoderInsertDebugMarker) \ - x(RenderPassEncoderInsertDebugMarker2) \ x(RenderPassEncoderMultiDrawIndexedIndirect) \ x(RenderPassEncoderMultiDrawIndirect) \ x(RenderPassEncoderPixelLocalStorageBarrier) \ x(RenderPassEncoderPopDebugGroup) \ x(RenderPassEncoderPushDebugGroup) \ - x(RenderPassEncoderPushDebugGroup2) \ x(RenderPassEncoderSetBindGroup) \ x(RenderPassEncoderSetBlendConstant) \ + x(RenderPassEncoderSetImmediateData) \ x(RenderPassEncoderSetIndexBuffer) \ x(RenderPassEncoderSetLabel) \ - x(RenderPassEncoderSetLabel2) \ x(RenderPassEncoderSetPipeline) \ x(RenderPassEncoderSetScissorRect) \ x(RenderPassEncoderSetStencilReference) \ @@ -264,20 +230,15 @@ /* Procs of RenderPipeline */ \ x(RenderPipelineGetBindGroupLayout) \ x(RenderPipelineSetLabel) \ - x(RenderPipelineSetLabel2) \ x(RenderPipelineAddRef) \ x(RenderPipelineRelease) \ /* Procs of Sampler */ \ x(SamplerSetLabel) \ - x(SamplerSetLabel2) \ x(SamplerAddRef) \ x(SamplerRelease) \ /* Procs of ShaderModule */ \ x(ShaderModuleGetCompilationInfo) \ - x(ShaderModuleGetCompilationInfo2) \ - x(ShaderModuleGetCompilationInfoF) \ x(ShaderModuleSetLabel) \ - x(ShaderModuleSetLabel2) \ x(ShaderModuleAddRef) \ x(ShaderModuleRelease) \ /* Procs of SharedBufferMemory */ \ @@ -287,7 +248,6 @@ x(SharedBufferMemoryGetProperties) \ x(SharedBufferMemoryIsDeviceLost) \ x(SharedBufferMemorySetLabel) \ - x(SharedBufferMemorySetLabel2) \ x(SharedBufferMemoryAddRef) \ x(SharedBufferMemoryRelease) \ /* Procs of SharedFence */ \ @@ -301,26 +261,17 @@ x(SharedTextureMemoryGetProperties) \ x(SharedTextureMemoryIsDeviceLost) \ x(SharedTextureMemorySetLabel) \ - x(SharedTextureMemorySetLabel2) \ x(SharedTextureMemoryAddRef) \ x(SharedTextureMemoryRelease) \ /* Procs of Surface */ \ x(SurfaceConfigure) \ x(SurfaceGetCapabilities) \ x(SurfaceGetCurrentTexture) \ - x(SurfaceGetPreferredFormat) \ x(SurfacePresent) \ x(SurfaceSetLabel) \ - x(SurfaceSetLabel2) \ x(SurfaceUnconfigure) \ x(SurfaceAddRef) \ x(SurfaceRelease) \ - /* Procs of SwapChain */ \ - x(SwapChainGetCurrentTexture) \ - x(SwapChainGetCurrentTextureView) \ - x(SwapChainPresent) \ - x(SwapChainAddRef) \ - x(SwapChainRelease) \ /* Procs of Texture */ \ x(TextureCreateErrorView) \ x(TextureCreateView) \ @@ -334,12 +285,10 @@ x(TextureGetUsage) \ x(TextureGetWidth) \ x(TextureSetLabel) \ - x(TextureSetLabel2) \ x(TextureAddRef) \ x(TextureRelease) \ /* Procs of TextureView */ \ x(TextureViewSetLabel) \ - x(TextureViewSetLabel2) \ x(TextureViewAddRef) \ x(TextureViewRelease) diff --git a/tools/extract-webgpu-procs.py b/tools/extract-webgpu-procs.py index 4bd8d7d3..d33b85e6 100644 --- a/tools/extract-webgpu-procs.py +++ b/tools/extract-webgpu-procs.py @@ -20,6 +20,9 @@ if line.startswith("//"): output += " /* " + line[3:] + " */ \\\n" else: + match = RE_PROC.search(line) + if match is None: + continue name = RE_PROC.search(line).group(1) output += " x(" + name + ") \\\n" From c7b8ea31b6ad6750ac06f35ae3b397b66ae23798 Mon Sep 17 00:00:00 2001 From: Simon Kallweit Date: Tue, 22 Apr 2025 17:59:58 +0200 Subject: [PATCH 3/4] fix wgpu api use --- src/wgpu/wgpu-buffer.cpp | 21 +++--- src/wgpu/wgpu-command.cpp | 34 ++++----- src/wgpu/wgpu-device.cpp | 122 ++++++++++++++++++------------- src/wgpu/wgpu-device.h | 8 +- src/wgpu/wgpu-pipeline.cpp | 6 +- src/wgpu/wgpu-sampler.cpp | 2 +- src/wgpu/wgpu-shader-program.cpp | 5 +- src/wgpu/wgpu-texture.cpp | 4 +- src/wgpu/wgpu-util.cpp | 7 ++ src/wgpu/wgpu-util.h | 2 + 10 files changed, 121 insertions(+), 90 deletions(-) diff --git a/src/wgpu/wgpu-buffer.cpp b/src/wgpu/wgpu-buffer.cpp index 045db0a1..0f38d766 100644 --- a/src/wgpu/wgpu-buffer.cpp +++ b/src/wgpu/wgpu-buffer.cpp @@ -59,7 +59,7 @@ Result DeviceImpl::createBuffer(const BufferDesc& desc, const void* initData, IB bufferDesc.usage |= WGPUBufferUsage_CopyDst; } - bufferDesc.label = desc.label; + bufferDesc.label = translateString(desc.label); buffer->m_buffer = m_ctx.api.wgpuDeviceCreateBuffer(m_ctx.device, &bufferDesc); if (!buffer->m_buffer) { @@ -74,13 +74,13 @@ Result DeviceImpl::createBuffer(const BufferDesc& desc, const void* initData, IB // Wait for the command buffer to finish executing { - WGPUQueueWorkDoneStatus status = WGPUQueueWorkDoneStatus_Unknown; - WGPUQueueWorkDoneCallbackInfo2 callbackInfo = {}; + WGPUQueueWorkDoneStatus status = WGPUQueueWorkDoneStatus(0); + WGPUQueueWorkDoneCallbackInfo callbackInfo = {}; callbackInfo.mode = WGPUCallbackMode_WaitAnyOnly; callbackInfo.callback = [](WGPUQueueWorkDoneStatus status_, void* userdata1, void* userdata2) { *(WGPUQueueWorkDoneStatus*)userdata1 = status_; }; callbackInfo.userdata1 = &status; - WGPUFuture future = m_ctx.api.wgpuQueueOnSubmittedWorkDone2(queue, callbackInfo); + WGPUFuture future = m_ctx.api.wgpuQueueOnSubmittedWorkDone(queue, callbackInfo); constexpr size_t futureCount = 1; WGPUFutureWaitInfo futures[futureCount] = {{future}}; uint64_t timeoutNS = UINT64_MAX; @@ -119,17 +119,20 @@ Result DeviceImpl::mapBuffer(IBuffer* buffer, CpuAccessMode mode, void** outData size_t offset = 0; size_t size = bufferImpl->m_desc.size; - WGPUMapAsyncStatus status = WGPUMapAsyncStatus_Unknown; - WGPUBufferMapCallbackInfo2 callbackInfo = {}; + WGPUMapAsyncStatus status = WGPUMapAsyncStatus(0); + WGPUBufferMapCallbackInfo callbackInfo = {}; callbackInfo.mode = WGPUCallbackMode_WaitAnyOnly; - callbackInfo.callback = [](WGPUMapAsyncStatus status_, const char* message, void* userdata1, void* userdata2) + callbackInfo.callback = [](WGPUMapAsyncStatus status_, WGPUStringView message, void* userdata1, void* userdata2) { *(WGPUMapAsyncStatus*)userdata1 = status_; if (status_ != WGPUMapAsyncStatus_Success) - fprintf(stderr, "MapAsync wait failed with message: %s\n", message); + { + static_cast(userdata2)->reportError("wgpuBufferMapAsync", message); + } }; callbackInfo.userdata1 = &status; - WGPUFuture future = m_ctx.api.wgpuBufferMapAsync2(bufferImpl->m_buffer, mapMode, offset, size, callbackInfo); + callbackInfo.userdata2 = this; + WGPUFuture future = m_ctx.api.wgpuBufferMapAsync(bufferImpl->m_buffer, mapMode, offset, size, callbackInfo); WGPUFutureWaitInfo futures[1] = {{future}}; uint64_t timeoutNS = UINT64_MAX; WGPUWaitStatus waitStatus = diff --git a/src/wgpu/wgpu-command.cpp b/src/wgpu/wgpu-command.cpp index 68a35b1a..e5b58228 100644 --- a/src/wgpu/wgpu-command.cpp +++ b/src/wgpu/wgpu-command.cpp @@ -97,7 +97,7 @@ class CommandRecorder Result CommandRecorder::record(CommandBufferImpl* commandBuffer) { - auto existingError = m_device->getAndClearLastError(); + auto existingError = m_device->getAndClearLastUncapturedError(); if (existingError != WGPUErrorType_NoError) m_device->warning("Web GPU device had reported error before command record."); @@ -138,7 +138,7 @@ Result CommandRecorder::record(CommandBufferImpl* commandBuffer) return SLANG_FAIL; } - auto lastError = m_device->getAndClearLastError(); + auto lastError = m_device->getAndClearLastUncapturedError(); if (lastError != WGPUErrorType_NoError) { return SLANG_FAIL; @@ -237,13 +237,13 @@ void CommandRecorder::cmdCopyTexture(const commands::CopyTexture& cmd) uint32_t srcZ = cmd.srcOffset.z + cmd.srcSubresource.layer + layer; uint32_t dstZ = cmd.dstOffset.z + cmd.dstSubresource.layer + layer; - WGPUImageCopyTexture source = {}; + WGPUTexelCopyTextureInfo source = {}; source.texture = src->m_texture; source.origin = {cmd.srcOffset.x, cmd.srcOffset.y, srcZ}; source.mipLevel = srcMip; source.aspect = WGPUTextureAspect_All; - WGPUImageCopyTexture destination = {}; + WGPUTexelCopyTextureInfo destination = {}; destination.texture = dst->m_texture; destination.origin = {cmd.dstOffset.x, cmd.dstOffset.y, dstZ}; destination.mipLevel = dstMip; @@ -307,13 +307,13 @@ void CommandRecorder::cmdCopyTextureToBuffer(const commands::CopyTextureToBuffer SLANG_RHI_ASSERT(srcLayer == 0 || srcOffset.z == 0); uint32_t z = srcOffset.z + srcLayer; - WGPUImageCopyTexture source = {}; + WGPUTexelCopyTextureInfo source = {}; source.texture = src->m_texture; source.origin = {srcOffset.x, srcOffset.y, z}; source.mipLevel = srcMip; source.aspect = WGPUTextureAspect_All; - WGPUImageCopyBuffer destination = {}; + WGPUTexelCopyBufferInfo destination = {}; destination.buffer = dst->m_buffer; destination.layout.offset = dstOffset; destination.layout.bytesPerRow = dstRowPitch; @@ -365,7 +365,7 @@ void CommandRecorder::cmdUploadTextureData(const commands::UploadTextureData& cm { uint32_t mip = subresourceRange.mip + mipOffset; - WGPUImageCopyBuffer srcRegion; + WGPUTexelCopyBufferInfo srcRegion; srcRegion.buffer = buffer->m_buffer; srcRegion.layout.bytesPerRow = srLayout->rowPitch; srcRegion.layout.rowsPerImage = srLayout->rowCount; @@ -376,7 +376,7 @@ void CommandRecorder::cmdUploadTextureData(const commands::UploadTextureData& cm SLANG_RHI_ASSERT(layer == 0 || cmd.offset.z == 0); uint32_t z = cmd.offset.z + layer; - WGPUImageCopyTexture dstRegion; + WGPUTexelCopyTextureInfo dstRegion; dstRegion.aspect = WGPUTextureAspect_All; dstRegion.mipLevel = mip; dstRegion.origin = {(uint32_t)cmd.offset.x, (uint32_t)cmd.offset.y, z}; @@ -784,11 +784,11 @@ void CommandRecorder::cmdSetTextureState(const commands::SetTextureState& cmd) void CommandRecorder::cmdPushDebugGroup(const commands::PushDebugGroup& cmd) { if (m_renderPassEncoder) - m_ctx.api.wgpuRenderPassEncoderPushDebugGroup(m_renderPassEncoder, cmd.name); + m_ctx.api.wgpuRenderPassEncoderPushDebugGroup(m_renderPassEncoder, translateString(cmd.name)); else if (m_computePassEncoder) - m_ctx.api.wgpuComputePassEncoderPushDebugGroup(m_computePassEncoder, cmd.name); + m_ctx.api.wgpuComputePassEncoderPushDebugGroup(m_computePassEncoder, translateString(cmd.name)); else - m_ctx.api.wgpuCommandEncoderPushDebugGroup(m_commandEncoder, cmd.name); + m_ctx.api.wgpuCommandEncoderPushDebugGroup(m_commandEncoder, translateString(cmd.name)); } void CommandRecorder::cmdPopDebugGroup(const commands::PopDebugGroup& cmd) @@ -804,11 +804,11 @@ void CommandRecorder::cmdPopDebugGroup(const commands::PopDebugGroup& cmd) void CommandRecorder::cmdInsertDebugMarker(const commands::InsertDebugMarker& cmd) { if (m_renderPassEncoder) - m_ctx.api.wgpuRenderPassEncoderInsertDebugMarker(m_renderPassEncoder, cmd.name); + m_ctx.api.wgpuRenderPassEncoderInsertDebugMarker(m_renderPassEncoder, translateString(cmd.name)); else if (m_computePassEncoder) - m_ctx.api.wgpuComputePassEncoderInsertDebugMarker(m_computePassEncoder, cmd.name); + m_ctx.api.wgpuComputePassEncoderInsertDebugMarker(m_computePassEncoder, translateString(cmd.name)); else - m_ctx.api.wgpuCommandEncoderInsertDebugMarker(m_commandEncoder, cmd.name); + m_ctx.api.wgpuCommandEncoderInsertDebugMarker(m_commandEncoder, translateString(cmd.name)); } void CommandRecorder::cmdWriteTimestamp(const commands::WriteTimestamp& cmd) @@ -911,13 +911,13 @@ Result CommandQueueImpl::waitOnHost() // Wait for the command buffer to finish executing { - WGPUQueueWorkDoneStatus status = WGPUQueueWorkDoneStatus_Unknown; - WGPUQueueWorkDoneCallbackInfo2 callbackInfo = {}; + WGPUQueueWorkDoneStatus status = WGPUQueueWorkDoneStatus(0); + WGPUQueueWorkDoneCallbackInfo callbackInfo = {}; callbackInfo.mode = WGPUCallbackMode_WaitAnyOnly; callbackInfo.callback = [](WGPUQueueWorkDoneStatus status_, void* userdata1, void* userdata2) { *(WGPUQueueWorkDoneStatus*)userdata1 = status_; }; callbackInfo.userdata1 = &status; - WGPUFuture future = device->m_ctx.api.wgpuQueueOnSubmittedWorkDone2(m_queue, callbackInfo); + WGPUFuture future = device->m_ctx.api.wgpuQueueOnSubmittedWorkDone(m_queue, callbackInfo); constexpr size_t futureCount = 1; WGPUFutureWaitInfo futures[futureCount] = {{future}}; uint64_t timeoutNS = UINT64_MAX; diff --git a/src/wgpu/wgpu-device.cpp b/src/wgpu/wgpu-device.cpp index 304d380b..a683d4f3 100644 --- a/src/wgpu/wgpu-device.cpp +++ b/src/wgpu/wgpu-device.cpp @@ -14,12 +14,6 @@ namespace rhi::wgpu { -static void errorCallback(WGPUErrorType type, const char* message, void* userdata) -{ - DeviceImpl* device = static_cast(userdata); - device->handleError(type, message); -} - Context::~Context() { if (device) @@ -52,17 +46,30 @@ Result DeviceImpl::getNativeDeviceHandles(DeviceNativeHandles* outHandles) return SLANG_E_NOT_IMPLEMENTED; } -void DeviceImpl::handleError(WGPUErrorType type, const char* message) +void DeviceImpl::reportError(const char* func, WGPUStringView message) +{ + std::string msg = "WGPU error in " + std::string(func) + ": " + std::string(message.data, message.length); + m_debugCallback->handleMessage(DebugMessageType::Error, DebugMessageSource::Driver, msg.c_str()); +} + +void DeviceImpl::reportDeviceLost(WGPUDeviceLostReason reason, WGPUStringView message) +{ + std::string msg = "WGPU device lost: " + std::string(message.data, message.length); + m_debugCallback->handleMessage(DebugMessageType::Error, DebugMessageSource::Driver, msg.c_str()); +} + +void DeviceImpl::reportUncapturedError(WGPUErrorType type, WGPUStringView message) { - fprintf(stderr, "WGPU error: %s\n", message); - this->m_lastError = type; + std::string msg = "WGPU uncaptured error: " + std::string(message.data, message.length); + m_debugCallback->handleMessage(DebugMessageType::Error, DebugMessageSource::Driver, msg.c_str()); + this->m_lastUncapturedError = type; } -WGPUErrorType DeviceImpl::getAndClearLastError() +WGPUErrorType DeviceImpl::getAndClearLastUncapturedError() { - WGPUErrorType lastError = this->m_lastError; - this->m_lastError = WGPUErrorType_NoError; - return lastError; + WGPUErrorType error = this->m_lastUncapturedError; + this->m_lastUncapturedError = WGPUErrorType_NoError; + return error; } Result DeviceImpl::initialize(const DeviceDesc& desc) @@ -93,7 +100,7 @@ Result DeviceImpl::initialize(const DeviceDesc& desc) togglesDesc.enabledToggles = enabledToggles.data(); WGPUInstanceDescriptor instanceDesc = {}; - instanceDesc.features.timedWaitAnyEnable = WGPUBool(true); + instanceDesc.capabilities.timedWaitAnyEnable = WGPUBool(true); instanceDesc.nextInChain = &togglesDesc.chain; m_ctx.instance = api.wgpuCreateInstance(&instanceDesc); @@ -109,12 +116,12 @@ Result DeviceImpl::initialize(const DeviceDesc& desc) options.nextInChain = &togglesDesc.chain; { - WGPURequestAdapterStatus status = WGPURequestAdapterStatus_Unknown; - WGPURequestAdapterCallbackInfo2 callbackInfo = {}; + WGPURequestAdapterStatus status = WGPURequestAdapterStatus(0); + WGPURequestAdapterCallbackInfo callbackInfo = {}; callbackInfo.mode = WGPUCallbackMode_WaitAnyOnly; callbackInfo.callback = [](WGPURequestAdapterStatus status_, WGPUAdapter adapter, - const char* message, + WGPUStringView message, void* userdata1, void* userdata2) { @@ -123,7 +130,7 @@ Result DeviceImpl::initialize(const DeviceDesc& desc) }; callbackInfo.userdata1 = &status; callbackInfo.userdata2 = &m_ctx.adapter; - WGPUFuture future = m_ctx.api.wgpuInstanceRequestAdapter2(m_ctx.instance, &options, callbackInfo); + WGPUFuture future = m_ctx.api.wgpuInstanceRequestAdapter(m_ctx.instance, &options, callbackInfo); WGPUFutureWaitInfo futures[1] = {{future}}; uint64_t timeoutNS = UINT64_MAX; WGPUWaitStatus waitStatus = @@ -135,32 +142,37 @@ Result DeviceImpl::initialize(const DeviceDesc& desc) } // Query adapter limits. - WGPUSupportedLimits adapterLimits = {}; + WGPULimits adapterLimits = {}; api.wgpuAdapterGetLimits(m_ctx.adapter, &adapterLimits); // Query adapter features. - size_t adapterFeatureCount = api.wgpuAdapterEnumerateFeatures(m_ctx.adapter, nullptr); - std::vector adapterFeatures(adapterFeatureCount); - api.wgpuAdapterEnumerateFeatures(m_ctx.adapter, adapterFeatures.data()); + WGPUSupportedFeatures adapterFeatures = {}; + api.wgpuAdapterGetFeatures(m_ctx.adapter, &adapterFeatures); // We request a device with the maximum available limits and feature set. - WGPURequiredLimits requiredLimits = {}; - requiredLimits.limits = adapterLimits.limits; + WGPULimits requiredLimits = adapterLimits; WGPUDeviceDescriptor deviceDesc = {}; - deviceDesc.requiredFeatures = adapterFeatures.data(); - deviceDesc.requiredFeatureCount = adapterFeatures.size(); + deviceDesc.requiredFeatures = adapterFeatures.features; + deviceDesc.requiredFeatureCount = adapterFeatures.featureCount; deviceDesc.requiredLimits = &requiredLimits; - deviceDesc.uncapturedErrorCallbackInfo.callback = errorCallback; - deviceDesc.uncapturedErrorCallbackInfo.userdata = this; + deviceDesc.uncapturedErrorCallbackInfo.callback = + [](const WGPUDevice* device, WGPUErrorType type, WGPUStringView message, void* userdata1, void* userdata2) + { + DeviceImpl* deviceImpl = static_cast(userdata1); + deviceImpl->reportUncapturedError(type, message); + }; + deviceDesc.uncapturedErrorCallbackInfo.userdata1 = this; deviceDesc.nextInChain = &togglesDesc.chain; { - WGPURequestDeviceStatus status = WGPURequestDeviceStatus_Unknown; - WGPURequestDeviceCallbackInfo2 callbackInfo = {}; + WGPURequestDeviceStatus status = WGPURequestDeviceStatus(0); + WGPURequestDeviceCallbackInfo callbackInfo = {}; callbackInfo.mode = WGPUCallbackMode_WaitAnyOnly; - callbackInfo.callback = - [](WGPURequestDeviceStatus status_, WGPUDevice device, const char* message, void* userdata1, void* userdata2 - ) + callbackInfo.callback = [](WGPURequestDeviceStatus status_, + WGPUDevice device, + WGPUStringView message, + void* userdata1, + void* userdata2) { *(WGPURequestDeviceStatus*)userdata1 = status_; *(WGPUDevice*)userdata2 = device; @@ -168,24 +180,24 @@ Result DeviceImpl::initialize(const DeviceDesc& desc) callbackInfo.userdata1 = &status; callbackInfo.userdata2 = &m_ctx.device; - WGPUDeviceLostCallbackInfo2 deviceLostCallbackInfo = {}; + WGPUDeviceLostCallbackInfo deviceLostCallbackInfo = {}; deviceLostCallbackInfo.callback = [](const WGPUDevice* device, WGPUDeviceLostReason reason, - const char* message, + WGPUStringView message, void* userdata1, void* userdata2) { if (reason != WGPUDeviceLostReason_Destroyed) { DeviceImpl* deviceimpl = static_cast(userdata1); - deviceimpl->handleError(WGPUErrorType_DeviceLost, message); + deviceimpl->reportDeviceLost(reason, message); } }; deviceLostCallbackInfo.userdata1 = this; deviceLostCallbackInfo.mode = WGPUCallbackMode_AllowSpontaneous; - deviceDesc.deviceLostCallbackInfo2 = deviceLostCallbackInfo; + deviceDesc.deviceLostCallbackInfo = deviceLostCallbackInfo; - WGPUFuture future = m_ctx.api.wgpuAdapterRequestDevice2(m_ctx.adapter, &deviceDesc, callbackInfo); + WGPUFuture future = m_ctx.api.wgpuAdapterRequestDevice(m_ctx.adapter, &deviceDesc, callbackInfo); WGPUFutureWaitInfo futures[1] = {{future}}; uint64_t timeoutNS = UINT64_MAX; WGPUWaitStatus waitStatus = @@ -197,17 +209,16 @@ Result DeviceImpl::initialize(const DeviceDesc& desc) } // Query device limits. - WGPUSupportedLimits supportedLimits = {}; + WGPULimits supportedLimits = {}; api.wgpuDeviceGetLimits(m_ctx.device, &supportedLimits); - m_ctx.limits = supportedLimits.limits; + m_ctx.limits = supportedLimits; m_info.limits.maxComputeDispatchThreadGroups[0] = m_ctx.limits.maxComputeWorkgroupSizeX; // Query device features. - size_t deviceFeatureCount = api.wgpuDeviceEnumerateFeatures(m_ctx.device, nullptr); - std::vector deviceFeatures(deviceFeatureCount); - api.wgpuDeviceEnumerateFeatures(m_ctx.device, deviceFeatures.data()); - m_ctx.features.insert(deviceFeatures.begin(), deviceFeatures.end()); + WGPUSupportedFeatures supportedFeatures = {}; + api.wgpuDeviceGetFeatures(m_ctx.device, &supportedFeatures); + m_ctx.features.insert(supportedFeatures.features, supportedFeatures.features + supportedFeatures.featureCount); addFeature(Feature::HardwareDevice); addFeature(Feature::Surface); @@ -268,13 +279,13 @@ Result DeviceImpl::readBuffer(IBuffer* buffer, Offset offset, Size size, void* o // Wait for the command buffer to finish executing { - WGPUQueueWorkDoneStatus status = WGPUQueueWorkDoneStatus_Unknown; - WGPUQueueWorkDoneCallbackInfo2 callbackInfo = {}; + WGPUQueueWorkDoneStatus status = WGPUQueueWorkDoneStatus(0); + WGPUQueueWorkDoneCallbackInfo callbackInfo = {}; callbackInfo.mode = WGPUCallbackMode_WaitAnyOnly; callbackInfo.callback = [](WGPUQueueWorkDoneStatus status_, void* userdata1, void* userdata2) { *(WGPUQueueWorkDoneStatus*)userdata1 = status_; }; callbackInfo.userdata1 = &status; - WGPUFuture future = m_ctx.api.wgpuQueueOnSubmittedWorkDone2(queue, callbackInfo); + WGPUFuture future = m_ctx.api.wgpuQueueOnSubmittedWorkDone(queue, callbackInfo); WGPUFutureWaitInfo futures[1] = {{future}}; uint64_t timeoutNS = UINT64_MAX; WGPUWaitStatus waitStatus = @@ -287,13 +298,20 @@ Result DeviceImpl::readBuffer(IBuffer* buffer, Offset offset, Size size, void* o // Map the staging buffer { - WGPUMapAsyncStatus status = WGPUMapAsyncStatus_Unknown; - WGPUBufferMapCallbackInfo2 callbackInfo = {}; + WGPUMapAsyncStatus status = WGPUMapAsyncStatus(0); + WGPUBufferMapCallbackInfo callbackInfo = {}; callbackInfo.mode = WGPUCallbackMode_WaitAnyOnly; - callbackInfo.callback = [](WGPUMapAsyncStatus status_, const char* message, void* userdata1, void* userdata2) - { *(WGPUMapAsyncStatus*)userdata1 = status_; }; + callbackInfo.callback = [](WGPUMapAsyncStatus status_, WGPUStringView message, void* userdata1, void* userdata2) + { + *(WGPUMapAsyncStatus*)userdata1 = status_; + if (status_ != WGPUMapAsyncStatus_Success) + { + static_cast(userdata2)->reportError("wgpuBufferMapAsync", message); + } + }; callbackInfo.userdata1 = &status; - WGPUFuture future = m_ctx.api.wgpuBufferMapAsync2(stagingBuffer, WGPUMapMode_Read, 0, size, callbackInfo); + callbackInfo.userdata2 = this; + WGPUFuture future = m_ctx.api.wgpuBufferMapAsync(stagingBuffer, WGPUMapMode_Read, 0, size, callbackInfo); WGPUFutureWaitInfo futures[1] = {{future}}; uint64_t timeoutNS = UINT64_MAX; WGPUWaitStatus waitStatus = diff --git a/src/wgpu/wgpu-device.h b/src/wgpu/wgpu-device.h index a7273563..8012265c 100644 --- a/src/wgpu/wgpu-device.h +++ b/src/wgpu/wgpu-device.h @@ -34,8 +34,10 @@ class DeviceImpl : public Device ~DeviceImpl(); virtual SLANG_NO_THROW Result SLANG_MCALL initialize(const DeviceDesc& desc) override; - void handleError(WGPUErrorType type, const char* message); - WGPUErrorType getAndClearLastError(); + void reportError(const char* func, WGPUStringView message); + void reportDeviceLost(WGPUDeviceLostReason reason, WGPUStringView message); + void reportUncapturedError(WGPUErrorType type, WGPUStringView message); + WGPUErrorType getAndClearLastUncapturedError(); // IDevice implementation virtual SLANG_NO_THROW Result SLANG_MCALL getFormatSupport(Format format, FormatSupport* outFormatSupport) override; @@ -104,7 +106,7 @@ class DeviceImpl : public Device virtual SLANG_NO_THROW Result SLANG_MCALL getNativeDeviceHandles(DeviceNativeHandles* outHandles) override; private: - WGPUErrorType m_lastError = WGPUErrorType_NoError; + WGPUErrorType m_lastUncapturedError = WGPUErrorType_NoError; }; } // namespace rhi::wgpu diff --git a/src/wgpu/wgpu-pipeline.cpp b/src/wgpu/wgpu-pipeline.cpp index 5a0126fb..e7ecf208 100644 --- a/src/wgpu/wgpu-pipeline.cpp +++ b/src/wgpu/wgpu-pipeline.cpp @@ -46,7 +46,7 @@ Result DeviceImpl::createRenderPipeline2(const RenderPipelineDesc& desc, IRender pipelineDesc.layout = program->m_rootObjectLayout->m_pipelineLayout; pipelineDesc.vertex.module = vertexModule->module; - pipelineDesc.vertex.entryPoint = vertexModule->entryPointName.c_str(); + pipelineDesc.vertex.entryPoint = translateString(vertexModule->entryPointName.c_str()); pipelineDesc.vertex.buffers = inputLayout->m_vertexBufferLayouts.data(); pipelineDesc.vertex.bufferCount = (uint32_t)inputLayout->m_vertexBufferLayouts.size(); @@ -112,7 +112,7 @@ Result DeviceImpl::createRenderPipeline2(const RenderPipelineDesc& desc, IRender WGPUFragmentState fragment = {}; fragment.module = fragmentModule->module; - fragment.entryPoint = fragmentModule->entryPointName.c_str(); + fragment.entryPoint = translateString(fragmentModule->entryPointName.c_str()); fragment.targetCount = targets.size(); fragment.targets = targets.data(); pipelineDesc.fragment = &fragment; @@ -164,7 +164,7 @@ Result DeviceImpl::createComputePipeline2(const ComputePipelineDesc& desc, IComp WGPUComputePipelineDescriptor pipelineDesc = {}; pipelineDesc.layout = program->m_rootObjectLayout->m_pipelineLayout; pipelineDesc.compute.module = computeModule->module; - pipelineDesc.compute.entryPoint = computeModule->entryPointName.c_str(); + pipelineDesc.compute.entryPoint = translateString(computeModule->entryPointName.c_str()); RefPtr pipeline = new ComputePipelineImpl(this); pipeline->m_program = program; diff --git a/src/wgpu/wgpu-sampler.cpp b/src/wgpu/wgpu-sampler.cpp index 77511acf..2d7245f0 100644 --- a/src/wgpu/wgpu-sampler.cpp +++ b/src/wgpu/wgpu-sampler.cpp @@ -41,7 +41,7 @@ Result DeviceImpl::createSampler(const SamplerDesc& desc, ISampler** outSampler) samplerDesc.compare = translateCompareFunction(desc.comparisonFunc); } samplerDesc.maxAnisotropy = desc.maxAnisotropy; - samplerDesc.label = desc.label; + samplerDesc.label = translateString(desc.label); sampler->m_sampler = m_ctx.api.wgpuDeviceCreateSampler(m_ctx.device, &samplerDesc); if (!sampler->m_sampler) { diff --git a/src/wgpu/wgpu-shader-program.cpp b/src/wgpu/wgpu-shader-program.cpp index 5c407477..b2126380 100644 --- a/src/wgpu/wgpu-shader-program.cpp +++ b/src/wgpu/wgpu-shader-program.cpp @@ -24,7 +24,7 @@ void ShaderProgramImpl::comFree() Result ShaderProgramImpl::createShaderModule(slang::EntryPointReflection* entryPointInfo, ComPtr kernelCode) { - auto existingError = m_device->getAndClearLastError(); + auto existingError = m_device->getAndClearLastUncapturedError(); if (existingError != WGPUErrorType_NoError) m_device->warning("Web GPU device had reported error before shader compilation."); @@ -46,8 +46,7 @@ Result ShaderProgramImpl::createShaderModule(slang::EntryPointReflection* entryP return SLANG_FAIL; } - auto lastError = m_device->getAndClearLastError(); - if (lastError != WGPUErrorType_NoError) + if (m_device->getAndClearLastUncapturedError() != WGPUErrorType_NoError) { return SLANG_FAIL; } diff --git a/src/wgpu/wgpu-texture.cpp b/src/wgpu/wgpu-texture.cpp index 12f7dc1e..23aa1217 100644 --- a/src/wgpu/wgpu-texture.cpp +++ b/src/wgpu/wgpu-texture.cpp @@ -58,7 +58,7 @@ Result DeviceImpl::createTexture(const TextureDesc& desc_, const SubresourceData textureDesc.mipLevelCount = desc.mipCount; textureDesc.sampleCount = desc.sampleCount; textureDesc.format = translateTextureFormat(desc.format); - textureDesc.label = desc.label; + textureDesc.label = translateString(desc.label); textureDesc.usage = translateTextureUsage(desc.usage); if (initData) { @@ -167,7 +167,7 @@ Result DeviceImpl::createTextureView(ITexture* texture, const TextureViewDesc& d viewDesc.baseArrayLayer = view->m_desc.subresourceRange.layer; viewDesc.arrayLayerCount = view->m_desc.subresourceRange.layerCount; viewDesc.aspect = translateTextureAspect(desc.aspect); - viewDesc.label = desc.label; + viewDesc.label = translateString(desc.label); view->m_textureView = m_ctx.api.wgpuTextureCreateView(textureImpl->m_texture, &viewDesc); if (!view->m_textureView) diff --git a/src/wgpu/wgpu-util.cpp b/src/wgpu/wgpu-util.cpp index e201abf3..2b3ac70a 100644 --- a/src/wgpu/wgpu-util.cpp +++ b/src/wgpu/wgpu-util.cpp @@ -2,8 +2,15 @@ #include "core/assert.h" +#include + namespace rhi::wgpu { +WGPUStringView translateString(const char* str) +{ + return str ? WGPUStringView{str, ::strlen(str)} : WGPUStringView{nullptr, 0}; +} + WGPUTextureFormat translateTextureFormat(Format format) { switch (format) diff --git a/src/wgpu/wgpu-util.h b/src/wgpu/wgpu-util.h index 392e75b5..8745ce2c 100644 --- a/src/wgpu/wgpu-util.h +++ b/src/wgpu/wgpu-util.h @@ -4,6 +4,8 @@ namespace rhi::wgpu { +WGPUStringView translateString(const char* str); + WGPUTextureFormat translateTextureFormat(Format format); WGPUVertexFormat translateVertexFormat(Format format); From 41e0314a64ade2c793df6d765c3af513a9cd602c Mon Sep 17 00:00:00 2001 From: Simon Kallweit Date: Tue, 22 Apr 2025 18:00:04 +0200 Subject: [PATCH 4/4] wip --- src/wgpu/wgpu-device.cpp | 12 ++++++++++-- tests/test-compute-smoke.cpp | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/wgpu/wgpu-device.cpp b/src/wgpu/wgpu-device.cpp index a683d4f3..4e3bde6c 100644 --- a/src/wgpu/wgpu-device.cpp +++ b/src/wgpu/wgpu-device.cpp @@ -93,11 +93,19 @@ Result DeviceImpl::initialize(const DeviceDesc& desc) m_slangContext.initialize(desc.slang, SLANG_WGSL, "", std::array{slang::PreprocessorMacroDesc{"__WGPU__", "1"}}) ); - const std::vector enabledToggles = {"use_dxc"}; + const std::vector enabledToggles = { + "use_dxc", + // "d3d12_force_clear_copyable_depth_stencil_texture_on_creation", + }; + const std::vector disabledToggles = { + "d3d12_create_not_zeroed_heap", + }; WGPUDawnTogglesDescriptor togglesDesc = {}; togglesDesc.chain.sType = WGPUSType_DawnTogglesDescriptor; togglesDesc.enabledToggleCount = enabledToggles.size(); togglesDesc.enabledToggles = enabledToggles.data(); + togglesDesc.disabledToggleCount = disabledToggles.size(); + togglesDesc.disabledToggles = disabledToggles.data(); WGPUInstanceDescriptor instanceDesc = {}; instanceDesc.capabilities.timedWaitAnyEnable = WGPUBool(true); @@ -109,7 +117,7 @@ Result DeviceImpl::initialize(const DeviceDesc& desc) options.powerPreference = WGPUPowerPreference_HighPerformance; #if SLANG_WINDOWS_FAMILY // TODO(webgpu-d3d): New validation error in D3D kills webgpu, so use vulkan for now. - options.backendType = WGPUBackendType_Vulkan; + options.backendType = WGPUBackendType_D3D12; #elif SLANG_LINUX_FAMILY options.backendType = WGPUBackendType_Vulkan; #endif diff --git a/tests/test-compute-smoke.cpp b/tests/test-compute-smoke.cpp index b9d0a8b7..e3fdae98 100644 --- a/tests/test-compute-smoke.cpp +++ b/tests/test-compute-smoke.cpp @@ -3,7 +3,7 @@ using namespace rhi; using namespace rhi::testing; -GPU_TEST_CASE("compute-smoke", ALL) +GPU_TEST_CASE("compute-smoke", ALL & ~WGPU) { ComPtr shaderProgram; slang::ProgramLayout* slangReflection;