Fix depth stencil view format when binding to shader to use depth-only aspect but still render to both
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user