diff --git a/Source/Engine/GraphicsDevice/WebGPU/GPUContextWebGPU.cpp b/Source/Engine/GraphicsDevice/WebGPU/GPUContextWebGPU.cpp index fec3cc243..9e24286aa 100644 --- a/Source/Engine/GraphicsDevice/WebGPU/GPUContextWebGPU.cpp +++ b/Source/Engine/GraphicsDevice/WebGPU/GPUContextWebGPU.cpp @@ -686,27 +686,26 @@ void GPUContextWebGPU::ManualClear(const PendingClear& clear) { renderPassDesc.depthStencilAttachment = &depthStencilAttachment; depthStencilAttachment = WGPU_RENDER_PASS_DEPTH_STENCIL_ATTACHMENT_INIT; - depthStencilAttachment.view = clear.View->View; + depthStencilAttachment.view = clear.View->ViewRender; depthStencilAttachment.depthLoadOp = WGPULoadOp_Clear; depthStencilAttachment.depthStoreOp = WGPUStoreOp_Store; depthStencilAttachment.depthClearValue = clear.Depth; depthStencilAttachment.stencilClearValue = clear.Stencil; + if (clear.View->HasStencil) + { + depthStencilAttachment.stencilLoadOp = WGPULoadOp_Clear; + depthStencilAttachment.stencilStoreOp = WGPUStoreOp_Store; + } } else { renderPassDesc.colorAttachmentCount = 1; renderPassDesc.colorAttachments = &colorAttachment; colorAttachment = WGPU_RENDER_PASS_COLOR_ATTACHMENT_INIT; - colorAttachment.view = clear.View->View; + colorAttachment.view = clear.View->ViewRender; colorAttachment.depthSlice = clear.View->DepthSlice; colorAttachment.loadOp = WGPULoadOp_Clear; colorAttachment.storeOp = WGPUStoreOp_Store; - if (clear.View->HasStencil) - { - depthStencilAttachment.stencilLoadOp = WGPULoadOp_Clear; - depthStencilAttachment.stencilStoreOp = WGPUStoreOp_Store; - depthStencilAttachment.stencilClearValue = clear.Stencil; - } colorAttachment.clearValue = { clear.RGBA[0], clear.RGBA[1], clear.RGBA[2], clear.RGBA[3] }; } auto renderPass = wgpuCommandEncoderBeginRenderPass(Encoder, &renderPassDesc); @@ -805,11 +804,11 @@ void GPUContextWebGPU::FlushRenderPass() auto& colorAttachment = colorAttachments[i]; colorAttachment = WGPU_RENDER_PASS_COLOR_ATTACHMENT_INIT; auto renderTarget = _renderTargets[i]; - colorAttachment.view = renderTarget->View; + colorAttachment.view = renderTarget->ViewRender; colorAttachment.depthSlice = renderTarget->DepthSlice; colorAttachment.loadOp = WGPULoadOp_Load; colorAttachment.storeOp = WGPUStoreOp_Store; - if (FindClear(_depthStencil, clear)) + if (FindClear(renderTarget, clear)) { colorAttachment.loadOp = WGPULoadOp_Clear; colorAttachment.clearValue = { clear.RGBA[0], clear.RGBA[1], clear.RGBA[2], clear.RGBA[3] }; @@ -820,7 +819,7 @@ void GPUContextWebGPU::FlushRenderPass() if (_depthStencil) { renderPassDesc.depthStencilAttachment = &depthStencilAttachment; - depthStencilAttachment.view = _depthStencil->View; + depthStencilAttachment.view = _depthStencil->ViewRender; depthStencilAttachment.depthLoadOp = WGPULoadOp_Load; depthStencilAttachment.depthStoreOp = _depthStencil->ReadOnly ? WGPUStoreOp_Discard : WGPUStoreOp_Store; depthStencilAttachment.depthReadOnly = _depthStencil->ReadOnly; diff --git a/Source/Engine/GraphicsDevice/WebGPU/GPUTextureWebGPU.cpp b/Source/Engine/GraphicsDevice/WebGPU/GPUTextureWebGPU.cpp index 97eaba742..46a5a3682 100644 --- a/Source/Engine/GraphicsDevice/WebGPU/GPUTextureWebGPU.cpp +++ b/Source/Engine/GraphicsDevice/WebGPU/GPUTextureWebGPU.cpp @@ -7,6 +7,31 @@ #include "Engine/Core/Log.h" #include "Engine/Graphics/PixelFormatExtensions.h" +bool HasStencil(WGPUTextureFormat format) +{ + switch (format) + { + case WGPUTextureFormat_Depth24PlusStencil8: + case WGPUTextureFormat_Depth32FloatStencil8: + return true; + default: + return false; + } +} + +WGPUTextureFormat DropStencil(WGPUTextureFormat format) +{ + switch (format) + { + case WGPUTextureFormat_Depth24PlusStencil8: + return WGPUTextureFormat_Depth24Plus; + case WGPUTextureFormat_Depth32FloatStencil8: + return WGPUTextureFormat_Depth32Float; + default: + return format; + } +} + void GPUTextureViewWebGPU::Create(WGPUTexture texture, WGPUTextureViewDescriptor const* desc) { if (View) @@ -17,13 +42,31 @@ void GPUTextureViewWebGPU::Create(WGPUTexture texture, WGPUTextureViewDescriptor { #if GPU_ENABLE_RESOURCE_NAMING LOG(Error, "Failed to create a view for texture '{}'", GetParent() ? GetParent()->GetName() : StringView::Empty); +#else + LOG(Error, "Failed to create a view for texture"); #endif } + ViewRender = View; + + // Depth-stencil textures expose depth-only when binding to shaders (unless via custom _handleStencil view) so make separate ViewRender for rendering with all components + if (desc && desc->aspect == WGPUTextureAspect_All && ::HasStencil(desc->format)) + { + auto depthOnlyDesc = *desc; + depthOnlyDesc.aspect = WGPUTextureAspect_DepthOnly; + depthOnlyDesc.format = DropStencil(depthOnlyDesc.format); + View = wgpuTextureCreateView(texture, &depthOnlyDesc); + } + Format = desc ? desc->format : wgpuTextureGetFormat(texture); } void GPUTextureViewWebGPU::Release() { + if (View != ViewRender) + { + wgpuTextureViewRelease(ViewRender); + ViewRender = nullptr; + } if (View) { wgpuTextureViewRelease(View); @@ -64,7 +107,7 @@ bool GPUTextureWebGPU::OnInit() textureDesc.dimension = WGPUTextureDimension_3D; break; case TextureDimensions::CubeTexture: - _viewDimension = IsArray() ? WGPUTextureViewDimension_CubeArray : WGPUTextureViewDimension_Cube; + _viewDimension = _desc.ArraySize > 6 ? WGPUTextureViewDimension_CubeArray : WGPUTextureViewDimension_Cube; textureDesc.dimension = WGPUTextureDimension_2D; textureDesc.size.depthOrArrayLayers *= 6; // Each cubemap uses 6 array slices break; diff --git a/Source/Engine/GraphicsDevice/WebGPU/GPUTextureWebGPU.h b/Source/Engine/GraphicsDevice/WebGPU/GPUTextureWebGPU.h index 732aa113c..44d4beaad 100644 --- a/Source/Engine/GraphicsDevice/WebGPU/GPUTextureWebGPU.h +++ b/Source/Engine/GraphicsDevice/WebGPU/GPUTextureWebGPU.h @@ -31,6 +31,8 @@ public: WGPUTexture Texture = nullptr; // Handle to the WebGPU texture view object. WGPUTextureView View = nullptr; + // Handle to the WebGPU texture view object for render passes (contains all views). + WGPUTextureView ViewRender = nullptr; bool HasStencil = false; bool ReadOnly = false; uint32 DepthSlice = WGPU_DEPTH_SLICE_UNDEFINED; diff --git a/Source/Engine/GraphicsDevice/WebGPU/RenderToolsWebGPU.cpp b/Source/Engine/GraphicsDevice/WebGPU/RenderToolsWebGPU.cpp index ca9e86af3..3dbf3f489 100644 --- a/Source/Engine/GraphicsDevice/WebGPU/RenderToolsWebGPU.cpp +++ b/Source/Engine/GraphicsDevice/WebGPU/RenderToolsWebGPU.cpp @@ -238,4 +238,55 @@ PixelFormat RenderToolsWebGPU::ToPixelFormat(WGPUTextureFormat format) } } +PixelFormat RenderToolsWebGPU::ToPixelFormat(WGPUVertexFormat format) +{ + switch (format) + { + // @formatter:off + case WGPUVertexFormat_Uint8: return PixelFormat::R8_UInt; + case WGPUVertexFormat_Uint8x2: return PixelFormat::R8G8_UInt; + case WGPUVertexFormat_Uint8x4: return PixelFormat::R8G8B8A8_UInt; + case WGPUVertexFormat_Sint8: return PixelFormat::R8_SInt; + case WGPUVertexFormat_Sint8x2: return PixelFormat::R8G8_SInt; + case WGPUVertexFormat_Sint8x4: return PixelFormat::R8G8B8A8_SInt; + case WGPUVertexFormat_Unorm8: return PixelFormat::R8_UNorm; + case WGPUVertexFormat_Unorm8x2: return PixelFormat::R8G8_UNorm; + case WGPUVertexFormat_Unorm8x4: return PixelFormat::R8G8B8A8_UNorm; + case WGPUVertexFormat_Snorm8: return PixelFormat::R8_SNorm; + case WGPUVertexFormat_Snorm8x2: return PixelFormat::R8G8_SNorm; + case WGPUVertexFormat_Snorm8x4: return PixelFormat::R8G8B8A8_SNorm; + case WGPUVertexFormat_Uint16: return PixelFormat::R16_UInt; + case WGPUVertexFormat_Uint16x2: return PixelFormat::R16G16_UInt; + case WGPUVertexFormat_Uint16x4: return PixelFormat::R16G16B16A16_UInt; + case WGPUVertexFormat_Sint16: return PixelFormat::R16_SInt; + case WGPUVertexFormat_Sint16x2: return PixelFormat::R16G16_SInt; + case WGPUVertexFormat_Sint16x4: return PixelFormat::R16G16B16A16_SInt; + case WGPUVertexFormat_Unorm16: return PixelFormat::R16_UNorm; + case WGPUVertexFormat_Unorm16x2: return PixelFormat::R16G16_UNorm; + case WGPUVertexFormat_Unorm16x4: return PixelFormat::R16G16B16A16_UNorm; + case WGPUVertexFormat_Snorm16: return PixelFormat::R16_SNorm; + case WGPUVertexFormat_Snorm16x2: return PixelFormat::R16G16_SNorm; + case WGPUVertexFormat_Snorm16x4: return PixelFormat::R16G16B16A16_SNorm; + case WGPUVertexFormat_Float16: return PixelFormat::R16_Float; + case WGPUVertexFormat_Float16x2: return PixelFormat::R16G16_Float; + case WGPUVertexFormat_Float16x4: return PixelFormat::R16G16B16A16_Float; + case WGPUVertexFormat_Float32: return PixelFormat::R32_Float; + case WGPUVertexFormat_Float32x2: return PixelFormat::R32G32_Float; + case WGPUVertexFormat_Float32x3: return PixelFormat::R32G32B32_Float; + case WGPUVertexFormat_Float32x4: return PixelFormat::R32G32B32A32_Float; + case WGPUVertexFormat_Uint32: return PixelFormat::R32_UInt; + case WGPUVertexFormat_Uint32x2: return PixelFormat::R32G32_UInt; + case WGPUVertexFormat_Uint32x3: return PixelFormat::R32G32B32_UInt; + case WGPUVertexFormat_Uint32x4: return PixelFormat::R32G32B32A32_UInt; + case WGPUVertexFormat_Sint32: return PixelFormat::R32_SInt; + case WGPUVertexFormat_Sint32x2: return PixelFormat::R32G32_SInt; + case WGPUVertexFormat_Sint32x3: return PixelFormat::R32G32B32_SInt; + case WGPUVertexFormat_Sint32x4: return PixelFormat::R32G32B32A32_SInt; + case WGPUVertexFormat_Unorm10_10_10_2: return PixelFormat::R10G10B10A2_UNorm; + case WGPUVertexFormat_Unorm8x4BGRA: return PixelFormat::B8G8R8A8_UNorm; + default: return PixelFormat::Unknown; + // @formatter:on + } +} + #endif diff --git a/Source/Engine/GraphicsDevice/WebGPU/RenderToolsWebGPU.h b/Source/Engine/GraphicsDevice/WebGPU/RenderToolsWebGPU.h index 6a0e374a0..88824af63 100644 --- a/Source/Engine/GraphicsDevice/WebGPU/RenderToolsWebGPU.h +++ b/Source/Engine/GraphicsDevice/WebGPU/RenderToolsWebGPU.h @@ -69,6 +69,7 @@ public: static WGPUVertexFormat ToVertexFormat(PixelFormat format); static WGPUTextureFormat ToTextureFormat(PixelFormat format); static PixelFormat ToPixelFormat(WGPUTextureFormat format); + static PixelFormat ToPixelFormat(WGPUVertexFormat format); }; #endif