From c57e2e6c9f485101ca40a6c701bea46cbf84fa9a Mon Sep 17 00:00:00 2001 From: Sergii Liebodkin Date: Thu, 24 Oct 2024 10:04:08 +0000 Subject: [PATCH] wg_engine: multisampling support Used native hardware MSAA x4 Full multisampling support including custom blend and compositions. Must be verified on web and 4K resolution for performance issues --- src/renderer/wg_engine/tvgWgCommon.cpp | 6 +++--- src/renderer/wg_engine/tvgWgCommon.h | 4 ++-- src/renderer/wg_engine/tvgWgCompositor.cpp | 19 ++++++++++++------- src/renderer/wg_engine/tvgWgCompositor.h | 8 +++++--- src/renderer/wg_engine/tvgWgPipelines.cpp | 5 +++-- src/renderer/wg_engine/tvgWgRenderTarget.cpp | 4 ++++ src/renderer/wg_engine/tvgWgRenderTarget.h | 2 ++ 7 files changed, 31 insertions(+), 17 deletions(-) diff --git a/src/renderer/wg_engine/tvgWgCommon.cpp b/src/renderer/wg_engine/tvgWgCommon.cpp index 616f09bf..67406822 100755 --- a/src/renderer/wg_engine/tvgWgCommon.cpp +++ b/src/renderer/wg_engine/tvgWgCommon.cpp @@ -111,18 +111,18 @@ WGPUTexture WgContext::createTexture(uint32_t width, uint32_t height, WGPUTextur } -WGPUTexture WgContext::createTexStorage(uint32_t width, uint32_t height, WGPUTextureFormat format, uint32_t sc) +WGPUTexture WgContext::createTexStorage(uint32_t width, uint32_t height, WGPUTextureFormat format) { const WGPUTextureDescriptor textureDesc { .usage = WGPUTextureUsage_CopySrc | WGPUTextureUsage_CopyDst | WGPUTextureUsage_TextureBinding | WGPUTextureUsage_StorageBinding | WGPUTextureUsage_RenderAttachment, .dimension = WGPUTextureDimension_2D, .size = { width, height, 1 }, - .format = format, .mipLevelCount = 1, .sampleCount = sc + .format = format, .mipLevelCount = 1, .sampleCount = 1 }; return wgpuDeviceCreateTexture(device, &textureDesc); } -WGPUTexture WgContext::createTexStencil(uint32_t width, uint32_t height, WGPUTextureFormat format, uint32_t sc) +WGPUTexture WgContext::createTexAttachement(uint32_t width, uint32_t height, WGPUTextureFormat format, uint32_t sc) { const WGPUTextureDescriptor textureDesc { .usage = WGPUTextureUsage_RenderAttachment, diff --git a/src/renderer/wg_engine/tvgWgCommon.h b/src/renderer/wg_engine/tvgWgCommon.h index eaf011f6..57cfed11 100755 --- a/src/renderer/wg_engine/tvgWgCommon.h +++ b/src/renderer/wg_engine/tvgWgCommon.h @@ -54,8 +54,8 @@ struct WgContext { // create common objects WGPUSampler createSampler(WGPUFilterMode filter, WGPUMipmapFilterMode mipmapFilter, WGPUAddressMode addrMode); WGPUTexture createTexture(uint32_t width, uint32_t height, WGPUTextureFormat format); - WGPUTexture createTexStorage(uint32_t width, uint32_t height, WGPUTextureFormat format, uint32_t sc = 1); - WGPUTexture createTexStencil(uint32_t width, uint32_t height, WGPUTextureFormat format, uint32_t sc = 1); + WGPUTexture createTexStorage(uint32_t width, uint32_t height, WGPUTextureFormat format); + WGPUTexture createTexAttachement(uint32_t width, uint32_t height, WGPUTextureFormat format, uint32_t sc); WGPUTextureView createTextureView(WGPUTexture texture); bool allocateTexture(WGPUTexture& texture, uint32_t width, uint32_t height, WGPUTextureFormat format, void* data); diff --git a/src/renderer/wg_engine/tvgWgCompositor.cpp b/src/renderer/wg_engine/tvgWgCompositor.cpp index 79aed684..98107c2e 100755 --- a/src/renderer/wg_engine/tvgWgCompositor.cpp +++ b/src/renderer/wg_engine/tvgWgCompositor.cpp @@ -31,8 +31,10 @@ void WgCompositor::initialize(WgContext& context, uint32_t width, uint32_t heigh this->width = width; this->height = height; // allocate global stencil buffer handles - texStencil = context.createTexStencil(width, height, WGPUTextureFormat_Depth24PlusStencil8); - texViewStencil = context.createTextureView(texStencil); + texDepthStencil = context.createTexAttachement(width, height, WGPUTextureFormat_Depth24PlusStencil8, 1); + texViewDepthStencil = context.createTextureView(texDepthStencil); + texDepthStencilMS = context.createTexAttachement(width, height, WGPUTextureFormat_Depth24PlusStencil8, 4); + texViewDepthStencilMS = context.createTextureView(texDepthStencilMS); // allocate global view matrix handles WgShaderTypeMat4x4f viewMat(width, height); context.allocateBufferUniform(bufferViewMat, &viewMat, sizeof(viewMat)); @@ -65,8 +67,10 @@ void WgCompositor::release(WgContext& context) context.pipelines->layouts.releaseBindGroup(bindGroupViewMat); context.releaseBuffer(bufferViewMat); // release global stencil buffer handles - context.releaseTextureView(texViewStencil); - context.releaseTexture(texStencil); + context.releaseTextureView(texViewDepthStencilMS); + context.releaseTexture(texDepthStencilMS); + context.releaseTextureView(texViewDepthStencil); + context.releaseTexture(texDepthStencil); height = 0; width = 0; pipelines = nullptr; @@ -91,15 +95,16 @@ void WgCompositor::beginRenderPass(WGPUCommandEncoder commandEncoder, WgRenderSt this->currentTarget = target; this->commandEncoder = commandEncoder; const WGPURenderPassDepthStencilAttachment depthStencilAttachment{ - .view = texViewStencil, + .view = texViewDepthStencilMS, .depthLoadOp = WGPULoadOp_Load, .depthStoreOp = WGPUStoreOp_Discard, .depthClearValue = 1.0f, .stencilLoadOp = WGPULoadOp_Load, .stencilStoreOp = WGPUStoreOp_Discard, .stencilClearValue = 0 }; //WGPURenderPassDepthStencilAttachment depthStencilAttachment{ .view = texViewStencil, .depthClearValue = 1.0f, .stencilLoadOp = WGPULoadOp_Clear, .stencilStoreOp = WGPUStoreOp_Discard }; WGPURenderPassColorAttachment colorAttachment{}; - colorAttachment.view = target->texView, + colorAttachment.view = target->texViewMS, colorAttachment.loadOp = clear ? WGPULoadOp_Clear : WGPULoadOp_Load, colorAttachment.storeOp = WGPUStoreOp_Store; + colorAttachment.resolveTarget = target->texView; #ifdef __EMSCRIPTEN__ colorAttachment.depthSlice = WGPU_DEPTH_SLICE_UNDEFINED; #endif @@ -204,7 +209,7 @@ void WgCompositor::composeScene(WgContext& context, WgRenderStorage* src, WgRend void WgCompositor::blit(WgContext& context, WGPUCommandEncoder encoder, WgRenderStorage* src, WGPUTextureView dstView) { const WGPURenderPassDepthStencilAttachment depthStencilAttachment{ - .view = texViewStencil, + .view = texViewDepthStencil, .depthLoadOp = WGPULoadOp_Load, .depthStoreOp = WGPUStoreOp_Discard, .stencilLoadOp = WGPULoadOp_Load, .stencilStoreOp = WGPUStoreOp_Discard }; diff --git a/src/renderer/wg_engine/tvgWgCompositor.h b/src/renderer/wg_engine/tvgWgCompositor.h index dd5d467a..715e8331 100755 --- a/src/renderer/wg_engine/tvgWgCompositor.h +++ b/src/renderer/wg_engine/tvgWgCompositor.h @@ -37,9 +37,11 @@ class WgCompositor private: // pipelines (external handle, do not release) WgPipelines* pipelines{}; - // global stencil buffer handles - WGPUTexture texStencil{}; - WGPUTextureView texViewStencil{}; + // global stencil/depth buffer handles + WGPUTexture texDepthStencil{}; + WGPUTextureView texViewDepthStencil{}; + WGPUTexture texDepthStencilMS{}; + WGPUTextureView texViewDepthStencilMS{}; // global view matrix handles WGPUBuffer bufferViewMat{}; WGPUBindGroup bindGroupViewMat{}; diff --git a/src/renderer/wg_engine/tvgWgPipelines.cpp b/src/renderer/wg_engine/tvgWgPipelines.cpp index c1630f73..0a7edc73 100755 --- a/src/renderer/wg_engine/tvgWgPipelines.cpp +++ b/src/renderer/wg_engine/tvgWgPipelines.cpp @@ -146,7 +146,8 @@ void WgPipelines::initialize(WgContext& context) const WGPUVertexBufferLayout vertexBufferLayoutTex { .arrayStride = 8, .stepMode = WGPUVertexStepMode_Vertex, .attributeCount = 1, .attributes = vertexAttributesTex }; const WGPUVertexBufferLayout vertexBufferLayoutsShape[] { vertexBufferLayoutPos }; const WGPUVertexBufferLayout vertexBufferLayoutsImage[] { vertexBufferLayoutPos, vertexBufferLayoutTex }; - const WGPUMultisampleState multisampleState { .count = 1, .mask = 0xFFFFFFFF, .alphaToCoverageEnabled = false }; + const WGPUMultisampleState multisampleState { .count = 4, .mask = 0xFFFFFFFF, .alphaToCoverageEnabled = false }; + const WGPUMultisampleState multisampleStateX1 { .count = 1, .mask = 0xFFFFFFFF, .alphaToCoverageEnabled = false }; const WGPUTextureFormat offscreenTargetFormat = WGPUTextureFormat_RGBA8Unorm; // blend states @@ -452,7 +453,7 @@ void WgPipelines::initialize(WgContext& context) WGPUColorWriteMask_All, context.preferredFormat, WGPUCompareFunction_Always, WGPUStencilOperation_Zero, WGPUCompareFunction_Always, WGPUStencilOperation_Zero, - WGPUCompareFunction_Always, false, multisampleState, blendStateSrc); + WGPUCompareFunction_Always, false, multisampleStateX1, blendStateSrc); } void WgPipelines::releaseGraphicHandles(WgContext& context) diff --git a/src/renderer/wg_engine/tvgWgRenderTarget.cpp b/src/renderer/wg_engine/tvgWgRenderTarget.cpp index 14a1710f..999eac91 100755 --- a/src/renderer/wg_engine/tvgWgRenderTarget.cpp +++ b/src/renderer/wg_engine/tvgWgRenderTarget.cpp @@ -27,7 +27,9 @@ void WgRenderStorage::initialize(WgContext& context, uint32_t width, uint32_t he this->width = width; this->height = height; texture = context.createTexStorage(width, height, WGPUTextureFormat_RGBA8Unorm); + textureMS = context.createTexAttachement(width, height, WGPUTextureFormat_RGBA8Unorm, 4); texView = context.createTextureView(texture); + texViewMS = context.createTextureView(textureMS); bindGroupRead = context.pipelines->layouts.createBindGroupStrorage1RO(texView); bindGroupWrite = context.pipelines->layouts.createBindGroupStrorage1WO(texView); bindGroupTexure = context.pipelines->layouts.createBindGroupTexSampled(context.samplerNearestRepeat, texView); @@ -39,6 +41,8 @@ void WgRenderStorage::release(WgContext& context) context.pipelines->layouts.releaseBindGroup(bindGroupTexure); context.pipelines->layouts.releaseBindGroup(bindGroupWrite); context.pipelines->layouts.releaseBindGroup(bindGroupRead); + context.releaseTextureView(texViewMS); + context.releaseTexture(textureMS); context.releaseTextureView(texView); context.releaseTexture(texture); height = 0; diff --git a/src/renderer/wg_engine/tvgWgRenderTarget.h b/src/renderer/wg_engine/tvgWgRenderTarget.h index 332d616b..3c9e9538 100755 --- a/src/renderer/wg_engine/tvgWgRenderTarget.h +++ b/src/renderer/wg_engine/tvgWgRenderTarget.h @@ -28,7 +28,9 @@ struct WgRenderStorage { WGPUTexture texture{}; + WGPUTexture textureMS{}; WGPUTextureView texView{}; + WGPUTextureView texViewMS{}; WGPUBindGroup bindGroupRead{}; WGPUBindGroup bindGroupWrite{}; WGPUBindGroup bindGroupTexure{};