mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 13:43:43 +00:00
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
This commit is contained in:
parent
bace4e3e9e
commit
c57e2e6c9f
7 changed files with 31 additions and 17 deletions
|
@ -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 {
|
const WGPUTextureDescriptor textureDesc {
|
||||||
.usage = WGPUTextureUsage_CopySrc | WGPUTextureUsage_CopyDst | WGPUTextureUsage_TextureBinding | WGPUTextureUsage_StorageBinding | WGPUTextureUsage_RenderAttachment,
|
.usage = WGPUTextureUsage_CopySrc | WGPUTextureUsage_CopyDst | WGPUTextureUsage_TextureBinding | WGPUTextureUsage_StorageBinding | WGPUTextureUsage_RenderAttachment,
|
||||||
.dimension = WGPUTextureDimension_2D, .size = { width, height, 1 },
|
.dimension = WGPUTextureDimension_2D, .size = { width, height, 1 },
|
||||||
.format = format, .mipLevelCount = 1, .sampleCount = sc
|
.format = format, .mipLevelCount = 1, .sampleCount = 1
|
||||||
};
|
};
|
||||||
return wgpuDeviceCreateTexture(device, &textureDesc);
|
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 {
|
const WGPUTextureDescriptor textureDesc {
|
||||||
.usage = WGPUTextureUsage_RenderAttachment,
|
.usage = WGPUTextureUsage_RenderAttachment,
|
||||||
|
|
|
@ -54,8 +54,8 @@ struct WgContext {
|
||||||
// create common objects
|
// create common objects
|
||||||
WGPUSampler createSampler(WGPUFilterMode filter, WGPUMipmapFilterMode mipmapFilter, WGPUAddressMode addrMode);
|
WGPUSampler createSampler(WGPUFilterMode filter, WGPUMipmapFilterMode mipmapFilter, WGPUAddressMode addrMode);
|
||||||
WGPUTexture createTexture(uint32_t width, uint32_t height, WGPUTextureFormat format);
|
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 createTexStorage(uint32_t width, uint32_t height, WGPUTextureFormat format);
|
||||||
WGPUTexture createTexStencil(uint32_t width, uint32_t height, WGPUTextureFormat format, uint32_t sc = 1);
|
WGPUTexture createTexAttachement(uint32_t width, uint32_t height, WGPUTextureFormat format, uint32_t sc);
|
||||||
WGPUTextureView createTextureView(WGPUTexture texture);
|
WGPUTextureView createTextureView(WGPUTexture texture);
|
||||||
bool allocateTexture(WGPUTexture& texture, uint32_t width, uint32_t height, WGPUTextureFormat format, void* data);
|
bool allocateTexture(WGPUTexture& texture, uint32_t width, uint32_t height, WGPUTextureFormat format, void* data);
|
||||||
|
|
||||||
|
|
|
@ -31,8 +31,10 @@ void WgCompositor::initialize(WgContext& context, uint32_t width, uint32_t heigh
|
||||||
this->width = width;
|
this->width = width;
|
||||||
this->height = height;
|
this->height = height;
|
||||||
// allocate global stencil buffer handles
|
// allocate global stencil buffer handles
|
||||||
texStencil = context.createTexStencil(width, height, WGPUTextureFormat_Depth24PlusStencil8);
|
texDepthStencil = context.createTexAttachement(width, height, WGPUTextureFormat_Depth24PlusStencil8, 1);
|
||||||
texViewStencil = context.createTextureView(texStencil);
|
texViewDepthStencil = context.createTextureView(texDepthStencil);
|
||||||
|
texDepthStencilMS = context.createTexAttachement(width, height, WGPUTextureFormat_Depth24PlusStencil8, 4);
|
||||||
|
texViewDepthStencilMS = context.createTextureView(texDepthStencilMS);
|
||||||
// allocate global view matrix handles
|
// allocate global view matrix handles
|
||||||
WgShaderTypeMat4x4f viewMat(width, height);
|
WgShaderTypeMat4x4f viewMat(width, height);
|
||||||
context.allocateBufferUniform(bufferViewMat, &viewMat, sizeof(viewMat));
|
context.allocateBufferUniform(bufferViewMat, &viewMat, sizeof(viewMat));
|
||||||
|
@ -65,8 +67,10 @@ void WgCompositor::release(WgContext& context)
|
||||||
context.pipelines->layouts.releaseBindGroup(bindGroupViewMat);
|
context.pipelines->layouts.releaseBindGroup(bindGroupViewMat);
|
||||||
context.releaseBuffer(bufferViewMat);
|
context.releaseBuffer(bufferViewMat);
|
||||||
// release global stencil buffer handles
|
// release global stencil buffer handles
|
||||||
context.releaseTextureView(texViewStencil);
|
context.releaseTextureView(texViewDepthStencilMS);
|
||||||
context.releaseTexture(texStencil);
|
context.releaseTexture(texDepthStencilMS);
|
||||||
|
context.releaseTextureView(texViewDepthStencil);
|
||||||
|
context.releaseTexture(texDepthStencil);
|
||||||
height = 0;
|
height = 0;
|
||||||
width = 0;
|
width = 0;
|
||||||
pipelines = nullptr;
|
pipelines = nullptr;
|
||||||
|
@ -91,15 +95,16 @@ void WgCompositor::beginRenderPass(WGPUCommandEncoder commandEncoder, WgRenderSt
|
||||||
this->currentTarget = target;
|
this->currentTarget = target;
|
||||||
this->commandEncoder = commandEncoder;
|
this->commandEncoder = commandEncoder;
|
||||||
const WGPURenderPassDepthStencilAttachment depthStencilAttachment{
|
const WGPURenderPassDepthStencilAttachment depthStencilAttachment{
|
||||||
.view = texViewStencil,
|
.view = texViewDepthStencilMS,
|
||||||
.depthLoadOp = WGPULoadOp_Load, .depthStoreOp = WGPUStoreOp_Discard, .depthClearValue = 1.0f,
|
.depthLoadOp = WGPULoadOp_Load, .depthStoreOp = WGPUStoreOp_Discard, .depthClearValue = 1.0f,
|
||||||
.stencilLoadOp = WGPULoadOp_Load, .stencilStoreOp = WGPUStoreOp_Discard, .stencilClearValue = 0
|
.stencilLoadOp = WGPULoadOp_Load, .stencilStoreOp = WGPUStoreOp_Discard, .stencilClearValue = 0
|
||||||
};
|
};
|
||||||
//WGPURenderPassDepthStencilAttachment depthStencilAttachment{ .view = texViewStencil, .depthClearValue = 1.0f, .stencilLoadOp = WGPULoadOp_Clear, .stencilStoreOp = WGPUStoreOp_Discard };
|
//WGPURenderPassDepthStencilAttachment depthStencilAttachment{ .view = texViewStencil, .depthClearValue = 1.0f, .stencilLoadOp = WGPULoadOp_Clear, .stencilStoreOp = WGPUStoreOp_Discard };
|
||||||
WGPURenderPassColorAttachment colorAttachment{};
|
WGPURenderPassColorAttachment colorAttachment{};
|
||||||
colorAttachment.view = target->texView,
|
colorAttachment.view = target->texViewMS,
|
||||||
colorAttachment.loadOp = clear ? WGPULoadOp_Clear : WGPULoadOp_Load,
|
colorAttachment.loadOp = clear ? WGPULoadOp_Clear : WGPULoadOp_Load,
|
||||||
colorAttachment.storeOp = WGPUStoreOp_Store;
|
colorAttachment.storeOp = WGPUStoreOp_Store;
|
||||||
|
colorAttachment.resolveTarget = target->texView;
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
colorAttachment.depthSlice = WGPU_DEPTH_SLICE_UNDEFINED;
|
colorAttachment.depthSlice = WGPU_DEPTH_SLICE_UNDEFINED;
|
||||||
#endif
|
#endif
|
||||||
|
@ -204,7 +209,7 @@ void WgCompositor::composeScene(WgContext& context, WgRenderStorage* src, WgRend
|
||||||
|
|
||||||
void WgCompositor::blit(WgContext& context, WGPUCommandEncoder encoder, WgRenderStorage* src, WGPUTextureView dstView) {
|
void WgCompositor::blit(WgContext& context, WGPUCommandEncoder encoder, WgRenderStorage* src, WGPUTextureView dstView) {
|
||||||
const WGPURenderPassDepthStencilAttachment depthStencilAttachment{
|
const WGPURenderPassDepthStencilAttachment depthStencilAttachment{
|
||||||
.view = texViewStencil,
|
.view = texViewDepthStencil,
|
||||||
.depthLoadOp = WGPULoadOp_Load, .depthStoreOp = WGPUStoreOp_Discard,
|
.depthLoadOp = WGPULoadOp_Load, .depthStoreOp = WGPUStoreOp_Discard,
|
||||||
.stencilLoadOp = WGPULoadOp_Load, .stencilStoreOp = WGPUStoreOp_Discard
|
.stencilLoadOp = WGPULoadOp_Load, .stencilStoreOp = WGPUStoreOp_Discard
|
||||||
};
|
};
|
||||||
|
|
|
@ -37,9 +37,11 @@ class WgCompositor
|
||||||
private:
|
private:
|
||||||
// pipelines (external handle, do not release)
|
// pipelines (external handle, do not release)
|
||||||
WgPipelines* pipelines{};
|
WgPipelines* pipelines{};
|
||||||
// global stencil buffer handles
|
// global stencil/depth buffer handles
|
||||||
WGPUTexture texStencil{};
|
WGPUTexture texDepthStencil{};
|
||||||
WGPUTextureView texViewStencil{};
|
WGPUTextureView texViewDepthStencil{};
|
||||||
|
WGPUTexture texDepthStencilMS{};
|
||||||
|
WGPUTextureView texViewDepthStencilMS{};
|
||||||
// global view matrix handles
|
// global view matrix handles
|
||||||
WGPUBuffer bufferViewMat{};
|
WGPUBuffer bufferViewMat{};
|
||||||
WGPUBindGroup bindGroupViewMat{};
|
WGPUBindGroup bindGroupViewMat{};
|
||||||
|
|
|
@ -146,7 +146,8 @@ void WgPipelines::initialize(WgContext& context)
|
||||||
const WGPUVertexBufferLayout vertexBufferLayoutTex { .arrayStride = 8, .stepMode = WGPUVertexStepMode_Vertex, .attributeCount = 1, .attributes = vertexAttributesTex };
|
const WGPUVertexBufferLayout vertexBufferLayoutTex { .arrayStride = 8, .stepMode = WGPUVertexStepMode_Vertex, .attributeCount = 1, .attributes = vertexAttributesTex };
|
||||||
const WGPUVertexBufferLayout vertexBufferLayoutsShape[] { vertexBufferLayoutPos };
|
const WGPUVertexBufferLayout vertexBufferLayoutsShape[] { vertexBufferLayoutPos };
|
||||||
const WGPUVertexBufferLayout vertexBufferLayoutsImage[] { vertexBufferLayoutPos, vertexBufferLayoutTex };
|
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;
|
const WGPUTextureFormat offscreenTargetFormat = WGPUTextureFormat_RGBA8Unorm;
|
||||||
|
|
||||||
// blend states
|
// blend states
|
||||||
|
@ -452,7 +453,7 @@ void WgPipelines::initialize(WgContext& context)
|
||||||
WGPUColorWriteMask_All, context.preferredFormat,
|
WGPUColorWriteMask_All, context.preferredFormat,
|
||||||
WGPUCompareFunction_Always, WGPUStencilOperation_Zero,
|
WGPUCompareFunction_Always, WGPUStencilOperation_Zero,
|
||||||
WGPUCompareFunction_Always, WGPUStencilOperation_Zero,
|
WGPUCompareFunction_Always, WGPUStencilOperation_Zero,
|
||||||
WGPUCompareFunction_Always, false, multisampleState, blendStateSrc);
|
WGPUCompareFunction_Always, false, multisampleStateX1, blendStateSrc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WgPipelines::releaseGraphicHandles(WgContext& context)
|
void WgPipelines::releaseGraphicHandles(WgContext& context)
|
||||||
|
|
|
@ -27,7 +27,9 @@ void WgRenderStorage::initialize(WgContext& context, uint32_t width, uint32_t he
|
||||||
this->width = width;
|
this->width = width;
|
||||||
this->height = height;
|
this->height = height;
|
||||||
texture = context.createTexStorage(width, height, WGPUTextureFormat_RGBA8Unorm);
|
texture = context.createTexStorage(width, height, WGPUTextureFormat_RGBA8Unorm);
|
||||||
|
textureMS = context.createTexAttachement(width, height, WGPUTextureFormat_RGBA8Unorm, 4);
|
||||||
texView = context.createTextureView(texture);
|
texView = context.createTextureView(texture);
|
||||||
|
texViewMS = context.createTextureView(textureMS);
|
||||||
bindGroupRead = context.pipelines->layouts.createBindGroupStrorage1RO(texView);
|
bindGroupRead = context.pipelines->layouts.createBindGroupStrorage1RO(texView);
|
||||||
bindGroupWrite = context.pipelines->layouts.createBindGroupStrorage1WO(texView);
|
bindGroupWrite = context.pipelines->layouts.createBindGroupStrorage1WO(texView);
|
||||||
bindGroupTexure = context.pipelines->layouts.createBindGroupTexSampled(context.samplerNearestRepeat, 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(bindGroupTexure);
|
||||||
context.pipelines->layouts.releaseBindGroup(bindGroupWrite);
|
context.pipelines->layouts.releaseBindGroup(bindGroupWrite);
|
||||||
context.pipelines->layouts.releaseBindGroup(bindGroupRead);
|
context.pipelines->layouts.releaseBindGroup(bindGroupRead);
|
||||||
|
context.releaseTextureView(texViewMS);
|
||||||
|
context.releaseTexture(textureMS);
|
||||||
context.releaseTextureView(texView);
|
context.releaseTextureView(texView);
|
||||||
context.releaseTexture(texture);
|
context.releaseTexture(texture);
|
||||||
height = 0;
|
height = 0;
|
||||||
|
|
|
@ -28,7 +28,9 @@
|
||||||
|
|
||||||
struct WgRenderStorage {
|
struct WgRenderStorage {
|
||||||
WGPUTexture texture{};
|
WGPUTexture texture{};
|
||||||
|
WGPUTexture textureMS{};
|
||||||
WGPUTextureView texView{};
|
WGPUTextureView texView{};
|
||||||
|
WGPUTextureView texViewMS{};
|
||||||
WGPUBindGroup bindGroupRead{};
|
WGPUBindGroup bindGroupRead{};
|
||||||
WGPUBindGroup bindGroupWrite{};
|
WGPUBindGroup bindGroupWrite{};
|
||||||
WGPUBindGroup bindGroupTexure{};
|
WGPUBindGroup bindGroupTexure{};
|
||||||
|
|
Loading…
Add table
Reference in a new issue