diff --git a/src/renderer/wg_engine/tvgWgBindGroups.cpp b/src/renderer/wg_engine/tvgWgBindGroups.cpp index e25e4181..20cab5d4 100644 --- a/src/renderer/wg_engine/tvgWgBindGroups.cpp +++ b/src/renderer/wg_engine/tvgWgBindGroups.cpp @@ -103,9 +103,15 @@ WGPUBindGroup WgBindGroupLayouts::createBindGroupStrorage3RO(WGPUTextureView tex WGPUBindGroup WgBindGroupLayouts::createBindGroupBuffer1Un(WGPUBuffer buff) +{ + return createBindGroupBuffer1Un(buff, 0, wgpuBufferGetSize(buff)); +} + + +WGPUBindGroup WgBindGroupLayouts::createBindGroupBuffer1Un(WGPUBuffer buff, uint64_t offset, uint64_t size) { const WGPUBindGroupEntry bindGroupEntrys[] = { - { .binding = 0, .buffer = buff, .size = wgpuBufferGetSize(buff) } + { .binding = 0, .buffer = buff, .offset = offset, .size = size } }; const WGPUBindGroupDescriptor bindGroupDesc { .layout = layoutBuffer1Un, .entryCount = 1, .entries = bindGroupEntrys }; return wgpuDeviceCreateBindGroup(device, &bindGroupDesc); diff --git a/src/renderer/wg_engine/tvgWgBindGroups.h b/src/renderer/wg_engine/tvgWgBindGroups.h index 9bab0e77..ac959700 100644 --- a/src/renderer/wg_engine/tvgWgBindGroups.h +++ b/src/renderer/wg_engine/tvgWgBindGroups.h @@ -49,6 +49,7 @@ public: WGPUBindGroup createBindGroupStrorage2RO(WGPUTextureView texView0, WGPUTextureView texView1); WGPUBindGroup createBindGroupStrorage3RO(WGPUTextureView texView0, WGPUTextureView texView1, WGPUTextureView texView2); WGPUBindGroup createBindGroupBuffer1Un(WGPUBuffer buff); + WGPUBindGroup createBindGroupBuffer1Un(WGPUBuffer buff, uint64_t offset, uint64_t size); WGPUBindGroup createBindGroupBuffer2Un(WGPUBuffer buff0, WGPUBuffer buff1); WGPUBindGroup createBindGroupBuffer3Un(WGPUBuffer buff0, WGPUBuffer buff1, WGPUBuffer buff2); void releaseBindGroup(WGPUBindGroup& bindGroup); diff --git a/src/renderer/wg_engine/tvgWgCompositor.cpp b/src/renderer/wg_engine/tvgWgCompositor.cpp index 071fd3a0..44629e06 100644 --- a/src/renderer/wg_engine/tvgWgCompositor.cpp +++ b/src/renderer/wg_engine/tvgWgCompositor.cpp @@ -28,7 +28,7 @@ void WgCompositor::initialize(WgContext& context, uint32_t width, uint32_t heigh { // pipelines (external handle, do not release) pipelines.initialize(context); - stageBuffer.initialize(context); + stageBufferGeometry.initialize(context); // initialize opacity pool initPools(context); // allocate global view matrix handles @@ -64,7 +64,8 @@ void WgCompositor::release(WgContext& context) context.layouts.releaseBindGroup(bindGroupViewMat); context.releaseBuffer(bufferViewMat); // release stage buffer - stageBuffer.release(context); + stageBufferPaint.release(context); + stageBufferGeometry.release(context); // release pipelines pipelines.release(context); } @@ -190,27 +191,31 @@ void WgCompositor::endRenderPass() void WgCompositor::reset(WgContext& context) { - stageBuffer.clear(); + stageBufferGeometry.clear(); + stageBufferPaint.clear(); } void WgCompositor::flush(WgContext& context) { - stageBuffer.append(&meshDataBlit); - stageBuffer.flush(context); + stageBufferGeometry.append(&meshDataBlit); + stageBufferGeometry.flush(context); + stageBufferPaint.flush(context); } void WgCompositor::requestShape(WgRenderDataShape* renderData) { - stageBuffer.append(renderData); + stageBufferGeometry.append(renderData); + renderData->bindGroupPaintInd = stageBufferPaint.append(renderData->paintSettings); // TODO: expand for fill settings } void WgCompositor::requestImage(WgRenderDataPicture* renderData) { - stageBuffer.append(renderData); + stageBufferGeometry.append(renderData); + renderData->bindGroupPaintInd = stageBufferPaint.append(renderData->paintSettings); // TODO: expand for fill settings } @@ -332,8 +337,8 @@ void WgCompositor::drawMesh(WgContext& context, WgMeshData* meshData) uint64_t icount = meshData->ibuffer.count; uint64_t vsize = meshData->vbuffer.count * sizeof(Point); uint64_t isize = icount * sizeof(uint32_t); - wgpuRenderPassEncoderSetVertexBuffer(renderPassEncoder, 0, stageBuffer.vbuffer_gpu, meshData->voffset, vsize); - wgpuRenderPassEncoderSetIndexBuffer(renderPassEncoder, stageBuffer.ibuffer_gpu, WGPUIndexFormat_Uint32, meshData->ioffset, isize); + wgpuRenderPassEncoderSetVertexBuffer(renderPassEncoder, 0, stageBufferGeometry.vbuffer_gpu, meshData->voffset, vsize); + wgpuRenderPassEncoderSetIndexBuffer(renderPassEncoder, stageBufferGeometry.ibuffer_gpu, WGPUIndexFormat_Uint32, meshData->ioffset, isize); wgpuRenderPassEncoderDrawIndexed(renderPassEncoder, icount, 1, 0, 0, 0); }; @@ -345,7 +350,7 @@ void WgCompositor::drawMeshFan(WgContext& context, WgMeshData* meshData) uint64_t icount = (meshData->vbuffer.count - 2) * 3; uint64_t vsize = meshData->vbuffer.count * sizeof(Point); uint64_t isize = icount * sizeof(uint32_t); - wgpuRenderPassEncoderSetVertexBuffer(renderPassEncoder, 0, stageBuffer.vbuffer_gpu, meshData->voffset, vsize); + wgpuRenderPassEncoderSetVertexBuffer(renderPassEncoder, 0, stageBufferGeometry.vbuffer_gpu, meshData->voffset, vsize); wgpuRenderPassEncoderSetIndexBuffer(renderPassEncoder, context.bufferIndexFan, WGPUIndexFormat_Uint32, 0, isize); wgpuRenderPassEncoderDrawIndexed(renderPassEncoder, icount, 1, 0, 0, 0); }; @@ -358,9 +363,9 @@ void WgCompositor::drawMeshImage(WgContext& context, WgMeshData* meshData) uint64_t icount = meshData->ibuffer.count; uint64_t vsize = meshData->vbuffer.count * sizeof(Point); uint64_t isize = icount * sizeof(uint32_t); - wgpuRenderPassEncoderSetVertexBuffer(renderPassEncoder, 0, stageBuffer.vbuffer_gpu, meshData->voffset, vsize); - wgpuRenderPassEncoderSetVertexBuffer(renderPassEncoder, 1, stageBuffer.vbuffer_gpu, meshData->toffset, vsize); - wgpuRenderPassEncoderSetIndexBuffer(renderPassEncoder, stageBuffer.ibuffer_gpu, WGPUIndexFormat_Uint32, meshData->ioffset, isize); + wgpuRenderPassEncoderSetVertexBuffer(renderPassEncoder, 0, stageBufferGeometry.vbuffer_gpu, meshData->voffset, vsize); + wgpuRenderPassEncoderSetVertexBuffer(renderPassEncoder, 1, stageBufferGeometry.vbuffer_gpu, meshData->toffset, vsize); + wgpuRenderPassEncoderSetIndexBuffer(renderPassEncoder, stageBufferGeometry.ibuffer_gpu, WGPUIndexFormat_Uint32, meshData->ioffset, isize); wgpuRenderPassEncoderDrawIndexed(renderPassEncoder, icount, 1, 0, 0, 0); }; @@ -376,7 +381,7 @@ void WgCompositor::drawShape(WgContext& context, WgRenderDataShape* renderData) WGPURenderPipeline stencilPipeline = (renderData->fillRule == FillRule::NonZero) ? pipelines.nonzero : pipelines.evenodd; wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); - wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr); + wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, stageBufferPaint[renderData->bindGroupPaintInd], 0, nullptr); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, stencilPipeline); // draw to stencil (first pass) ARRAY_FOREACH(p, renderData->meshGroupShapes.meshes) @@ -384,7 +389,7 @@ void WgCompositor::drawShape(WgContext& context, WgRenderDataShape* renderData) // setup fill rules wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); - wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr); + wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, stageBufferPaint[renderData->bindGroupPaintInd], 0, nullptr); WgRenderSettings& settings = renderData->renderSettingsShape; if (settings.fillType == WgRenderSettingsType::Solid) { wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, settings.bindGroupSolid, 0, nullptr); @@ -418,7 +423,7 @@ void WgCompositor::blendShape(WgContext& context, WgRenderDataShape* renderData, WGPURenderPipeline stencilPipeline = (renderData->fillRule == FillRule::NonZero) ? pipelines.nonzero : pipelines.evenodd; wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); - wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr); + wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, stageBufferPaint[renderData->bindGroupPaintInd], 0, nullptr); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, stencilPipeline); // draw to stencil (first pass) ARRAY_FOREACH(p, renderData->meshGroupShapes.meshes) @@ -426,7 +431,7 @@ void WgCompositor::blendShape(WgContext& context, WgRenderDataShape* renderData, // setup fill rules wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); - wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr); + wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, stageBufferPaint[renderData->bindGroupPaintInd], 0, nullptr); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 3, targetTemp0.bindGroupTexure, 0, nullptr); uint32_t blendMethodInd = (uint32_t)blendMethod; WgRenderSettings& settings = renderData->renderSettingsShape; @@ -457,7 +462,7 @@ void WgCompositor::clipShape(WgContext& context, WgRenderDataShape* renderData) WGPURenderPipeline stencilPipeline = (renderData->fillRule == FillRule::NonZero) ? pipelines.nonzero : pipelines.evenodd; wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); - wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr); + wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, stageBufferPaint[renderData->bindGroupPaintInd], 0, nullptr); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, stencilPipeline); // draw to stencil (first pass) ARRAY_FOREACH(p, renderData->meshGroupShapes.meshes) @@ -470,7 +475,7 @@ void WgCompositor::clipShape(WgContext& context, WgRenderDataShape* renderData) // setup fill rules wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); - wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr); + wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, stageBufferPaint[renderData->bindGroupPaintInd], 0, nullptr); WgRenderSettings& settings = renderData->renderSettingsShape; if (settings.fillType == WgRenderSettingsType::Solid) { wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, settings.bindGroupSolid, 0, nullptr); @@ -500,14 +505,14 @@ void WgCompositor::drawStrokes(WgContext& context, WgRenderDataShape* renderData // setup stencil rules wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 255); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); - wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr); + wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, stageBufferPaint[renderData->bindGroupPaintInd], 0, nullptr); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.direct); // draw to stencil (first pass) drawMesh(context, renderData->meshGroupStrokes.meshes[i]); // setup fill rules wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); - wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr); + wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, stageBufferPaint[renderData->bindGroupPaintInd], 0, nullptr); WgRenderSettings& settings = renderData->renderSettingsStroke; if (settings.fillType == WgRenderSettingsType::Solid) { wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, settings.bindGroupSolid, 0, nullptr); @@ -543,14 +548,14 @@ void WgCompositor::blendStrokes(WgContext& context, WgRenderDataShape* renderDat // setup stencil rules wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 255); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); - wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr); + wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, stageBufferPaint[renderData->bindGroupPaintInd], 0, nullptr); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.direct); // draw to stencil (first pass) drawMesh(context, renderData->meshGroupStrokes.meshes[i]); // setup fill rules wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); - wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr); + wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, stageBufferPaint[renderData->bindGroupPaintInd], 0, nullptr); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 3, targetTemp0.bindGroupTexure, 0, nullptr); uint32_t blendMethodInd = (uint32_t)blendMethod; WgRenderSettings& settings = renderData->renderSettingsStroke; @@ -584,7 +589,7 @@ void WgCompositor::clipStrokes(WgContext& context, WgRenderDataShape* renderData // setup stencil rules wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 255); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); - wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr); + wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, stageBufferPaint[renderData->bindGroupPaintInd], 0, nullptr); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.direct); // draw to stencil (first pass) drawMesh(context, renderData->meshGroupStrokes.meshes[i]); @@ -596,7 +601,7 @@ void WgCompositor::clipStrokes(WgContext& context, WgRenderDataShape* renderData // setup fill rules wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); - wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr); + wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, stageBufferPaint[renderData->bindGroupPaintInd], 0, nullptr); WgRenderSettings& settings = renderData->renderSettingsStroke; if (settings.fillType == WgRenderSettingsType::Solid) { wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, settings.bindGroupSolid, 0, nullptr); @@ -623,13 +628,13 @@ void WgCompositor::drawImage(WgContext& context, WgRenderDataPicture* renderData // draw stencil wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 255); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); - wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr); + wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, stageBufferPaint[renderData->bindGroupPaintInd], 0, nullptr); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.direct); drawMeshImage(context, &renderData->meshData); // draw image wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); - wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr); + wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, stageBufferPaint[renderData->bindGroupPaintInd], 0, nullptr); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, renderData->bindGroupPicture, 0, nullptr); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.image); drawMeshImage(context, &renderData->meshData); @@ -650,14 +655,14 @@ void WgCompositor::blendImage(WgContext& context, WgRenderDataPicture* renderDat // setup stencil rules wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 255); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); - wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr); + wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, stageBufferPaint[renderData->bindGroupPaintInd], 0, nullptr); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.direct); drawMeshImage(context, &renderData->meshData); // blend image uint32_t blendMethodInd = (uint32_t)blendMethod; wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); - wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr); + wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, stageBufferPaint[renderData->bindGroupPaintInd], 0, nullptr); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, renderData->bindGroupPicture, 0, nullptr); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 3, targetTemp0.bindGroupTexure, 0, nullptr); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.image_blend[blendMethodInd]); @@ -674,7 +679,7 @@ void WgCompositor::clipImage(WgContext& context, WgRenderDataPicture* renderData // setup stencil rules wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 255); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); - wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr); + wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, stageBufferPaint[renderData->bindGroupPaintInd], 0, nullptr); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.direct); drawMeshImage(context, &renderData->meshData); // merge depth and stencil buffer @@ -685,7 +690,7 @@ void WgCompositor::clipImage(WgContext& context, WgRenderDataPicture* renderData // draw image wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); - wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr); + wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, stageBufferPaint[renderData->bindGroupPaintInd], 0, nullptr); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, renderData->bindGroupPicture, 0, nullptr); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.image); drawMeshImage(context, &renderData->meshData); @@ -734,7 +739,7 @@ void WgCompositor::blendScene(WgContext& context, WgRenderTarget* scene, WgCompo void WgCompositor::markupClipPath(WgContext& context, WgRenderDataShape* renderData) { wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); - wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr); + wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, stageBufferPaint[renderData->bindGroupPaintInd], 0, nullptr); // markup stencil if (renderData->meshGroupStrokes.meshes.count > 0) { wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 255); @@ -765,7 +770,7 @@ void WgCompositor::renderClipPath(WgContext& context, WgRenderDataPaint* paint) // copy stencil to depth wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); - wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData0->bindGroupPaint, 0, nullptr); + wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, stageBufferPaint[renderData0->bindGroupPaintInd], 0, nullptr); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, bindGroupOpacities[128], 0, nullptr); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.copy_stencil_to_depth); drawMeshFan(context, &renderData0->meshDataBBox); @@ -777,31 +782,31 @@ void WgCompositor::renderClipPath(WgContext& context, WgRenderDataPaint* paint) markupClipPath(context, renderData); // copy stencil to depth (clear stencil) wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0); - wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr); + wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, stageBufferPaint[renderData->bindGroupPaintInd], 0, nullptr); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, bindGroupOpacities[190], 0, nullptr); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.copy_stencil_to_depth_interm); drawMeshFan(context, &renderData->meshDataBBox); // copy depth to stencil wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 1); - wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr); + wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, stageBufferPaint[renderData->bindGroupPaintInd], 0, nullptr); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, bindGroupOpacities[190], 0, nullptr); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.copy_depth_to_stencil); drawMeshFan(context, &renderData->meshDataBBox); // clear depth current (keep stencil) wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0); - wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr); + wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, stageBufferPaint[renderData->bindGroupPaintInd], 0, nullptr); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, bindGroupOpacities[255], 0, nullptr); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.clear_depth); drawMeshFan(context, &renderData->meshDataBBox); // clear depth original (keep stencil) wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0); - wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData0->bindGroupPaint, 0, nullptr); + wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, stageBufferPaint[renderData0->bindGroupPaintInd], 0, nullptr); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, bindGroupOpacities[255], 0, nullptr); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.clear_depth); drawMeshFan(context, &renderData0->meshDataBBox); // copy stencil to depth (clear stencil) wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0); - wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr); + wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, stageBufferPaint[renderData->bindGroupPaintInd], 0, nullptr); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, bindGroupOpacities[128], 0, nullptr); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.copy_stencil_to_depth); drawMeshFan(context, &renderData->meshDataBBox); @@ -822,7 +827,7 @@ void WgCompositor::clearClipPath(WgContext& context, WgRenderDataPaint* paint) // set transformations wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); - wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr); + wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, stageBufferPaint[renderData->bindGroupPaintInd], 0, nullptr); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, bindGroupOpacities[255], 0, nullptr); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.clear_depth); drawMeshFan(context, &renderData->meshDataBBox); diff --git a/src/renderer/wg_engine/tvgWgCompositor.h b/src/renderer/wg_engine/tvgWgCompositor.h index 648248d9..b04069c4 100644 --- a/src/renderer/wg_engine/tvgWgCompositor.h +++ b/src/renderer/wg_engine/tvgWgCompositor.h @@ -39,7 +39,8 @@ private: // pipelines WgPipelines pipelines{}; // stage buffers - WgRenderDataStageBuffer stageBuffer{}; + WgStageBufferGeometry stageBufferGeometry{}; + WgStageBufferUniform stageBufferPaint; // global stencil/depth buffer handles WGPUTexture texDepthStencil{}; WGPUTextureView texViewDepthStencil{}; diff --git a/src/renderer/wg_engine/tvgWgPipelines.cpp b/src/renderer/wg_engine/tvgWgPipelines.cpp index 4466cbbc..c8c8918b 100644 --- a/src/renderer/wg_engine/tvgWgPipelines.cpp +++ b/src/renderer/wg_engine/tvgWgPipelines.cpp @@ -167,17 +167,17 @@ void WgPipelines::initialize(WgContext& context) const WgBindGroupLayouts& layouts = context.layouts; // bind group layouts helpers - const WGPUBindGroupLayout bindGroupLayoutsStencil[] { layouts.layoutBuffer1Un, layouts.layoutBuffer2Un }; - const WGPUBindGroupLayout bindGroupLayoutsDepth[] { layouts.layoutBuffer1Un, layouts.layoutBuffer2Un, layouts.layoutBuffer1Un }; + const WGPUBindGroupLayout bindGroupLayoutsStencil[] { layouts.layoutBuffer1Un, layouts.layoutBuffer1Un }; + const WGPUBindGroupLayout bindGroupLayoutsDepth[] { layouts.layoutBuffer1Un, layouts.layoutBuffer1Un, layouts.layoutBuffer1Un }; // bind group layouts normal blend - const WGPUBindGroupLayout bindGroupLayoutsSolid[] { layouts.layoutBuffer1Un, layouts.layoutBuffer2Un, layouts.layoutBuffer1Un }; - const WGPUBindGroupLayout bindGroupLayoutsGradient[] { layouts.layoutBuffer1Un, layouts.layoutBuffer2Un, layouts.layoutTexSampledBuff2Un }; - const WGPUBindGroupLayout bindGroupLayoutsImage[] { layouts.layoutBuffer1Un, layouts.layoutBuffer2Un, layouts.layoutTexSampled }; + const WGPUBindGroupLayout bindGroupLayoutsSolid[] { layouts.layoutBuffer1Un, layouts.layoutBuffer1Un, layouts.layoutBuffer1Un }; + const WGPUBindGroupLayout bindGroupLayoutsGradient[] { layouts.layoutBuffer1Un, layouts.layoutBuffer1Un, layouts.layoutTexSampledBuff2Un }; + const WGPUBindGroupLayout bindGroupLayoutsImage[] { layouts.layoutBuffer1Un, layouts.layoutBuffer1Un, layouts.layoutTexSampled }; const WGPUBindGroupLayout bindGroupLayoutsScene[] { layouts.layoutTexSampled, layouts.layoutBuffer1Un }; // bind group layouts custom blend - const WGPUBindGroupLayout bindGroupLayoutsSolidBlend[] { layouts.layoutBuffer1Un, layouts.layoutBuffer2Un, layouts.layoutBuffer1Un, layouts.layoutTexSampled }; - const WGPUBindGroupLayout bindGroupLayoutsGradientBlend[] { layouts.layoutBuffer1Un, layouts.layoutBuffer2Un, layouts.layoutTexSampledBuff2Un, layouts.layoutTexSampled }; - const WGPUBindGroupLayout bindGroupLayoutsImageBlend[] { layouts.layoutBuffer1Un, layouts.layoutBuffer2Un, layouts.layoutTexSampled, layouts.layoutTexSampled }; + const WGPUBindGroupLayout bindGroupLayoutsSolidBlend[] { layouts.layoutBuffer1Un, layouts.layoutBuffer1Un, layouts.layoutBuffer1Un, layouts.layoutTexSampled }; + const WGPUBindGroupLayout bindGroupLayoutsGradientBlend[] { layouts.layoutBuffer1Un, layouts.layoutBuffer1Un, layouts.layoutTexSampledBuff2Un, layouts.layoutTexSampled }; + const WGPUBindGroupLayout bindGroupLayoutsImageBlend[] { layouts.layoutBuffer1Un, layouts.layoutBuffer1Un, layouts.layoutTexSampled, layouts.layoutTexSampled }; const WGPUBindGroupLayout bindGroupLayoutsSceneBlend[] { layouts.layoutTexSampled, layouts.layoutTexSampled, layouts.layoutBuffer1Un }; // bind group layouts scene compose const WGPUBindGroupLayout bindGroupLayoutsSceneCompose[] { layouts.layoutTexSampled, layouts.layoutTexSampled }; diff --git a/src/renderer/wg_engine/tvgWgRenderData.cpp b/src/renderer/wg_engine/tvgWgRenderData.cpp index f6eea81e..eb7bd52d 100644 --- a/src/renderer/wg_engine/tvgWgRenderData.cpp +++ b/src/renderer/wg_engine/tvgWgRenderData.cpp @@ -284,23 +284,14 @@ void WgRenderSettings::release(WgContext& context) void WgRenderDataPaint::release(WgContext& context) { - context.layouts.releaseBindGroup(bindGroupPaint); - context.releaseBuffer(bufferModelMat); - context.releaseBuffer(bufferBlendSettings); clips.clear(); }; void WgRenderDataPaint::update(WgContext& context, const tvg::Matrix& transform, tvg::ColorSpace cs, uint8_t opacity) { - WgShaderTypeMat4x4f modelMat(transform); - WgShaderTypeVec4f blendSettings(cs, opacity); - bool bufferModelMatChanged = context.allocateBufferUniform(bufferModelMat, &modelMat, sizeof(modelMat)); - bool bufferBlendSettingsChanged = context.allocateBufferUniform(bufferBlendSettings, &blendSettings, sizeof(blendSettings)); - if (bufferModelMatChanged || bufferBlendSettingsChanged) { - context.layouts.releaseBindGroup(bindGroupPaint); - bindGroupPaint = context.layouts.createBindGroupBuffer2Un(bufferModelMat, bufferBlendSettings); - } + paintSettings.modelMat.update(transform); + paintSettings.blendSettings.update(cs, opacity); } @@ -676,10 +667,10 @@ void WgRenderDataEffectParamsPool::release(WgContext& context) } //*********************************************************************** -// WgRenderDataStageBuffer +// WgStageBufferGeometry //*********************************************************************** -void WgRenderDataStageBuffer::append(WgMeshData* meshData) +void WgStageBufferGeometry::append(WgMeshData* meshData) { assert(meshData); uint32_t vsize = meshData->vbuffer.count * sizeof(meshData->vbuffer[0]); @@ -712,13 +703,13 @@ void WgRenderDataStageBuffer::append(WgMeshData* meshData) } -void WgRenderDataStageBuffer::append(WgMeshDataGroup* meshDataGroup) +void WgStageBufferGeometry::append(WgMeshDataGroup* meshDataGroup) { ARRAY_FOREACH(p, meshDataGroup->meshes) append(*p); } -void WgRenderDataStageBuffer::append(WgRenderDataShape* renderDataShape) +void WgStageBufferGeometry::append(WgRenderDataShape* renderDataShape) { append(&renderDataShape->meshGroupShapes); append(&renderDataShape->meshGroupShapesBBox); @@ -730,7 +721,7 @@ void WgRenderDataStageBuffer::append(WgRenderDataShape* renderDataShape) } -void WgRenderDataStageBuffer::append(WgRenderDataPicture* renderDataPicture) +void WgStageBufferGeometry::append(WgRenderDataPicture* renderDataPicture) { append(&renderDataPicture->meshData); ARRAY_FOREACH(p, renderDataPicture->clips) @@ -738,28 +729,28 @@ void WgRenderDataStageBuffer::append(WgRenderDataPicture* renderDataPicture) } -void WgRenderDataStageBuffer::release(WgContext& context) +void WgStageBufferGeometry::release(WgContext& context) { context.releaseBuffer(vbuffer_gpu); context.releaseBuffer(ibuffer_gpu); } -void WgRenderDataStageBuffer::clear() +void WgStageBufferGeometry::clear() { vbuffer.clear(); ibuffer.clear(); } -void WgRenderDataStageBuffer::flush(WgContext& context) +void WgStageBufferGeometry::flush(WgContext& context) { context.allocateBufferVertex(vbuffer_gpu, (float *)vbuffer.data, vbuffer.count); context.allocateBufferIndex(ibuffer_gpu, (uint32_t *)ibuffer.data, ibuffer.count); } -void WgRenderDataStageBuffer::bind(WGPURenderPassEncoder renderPass, size_t voffset, size_t toffset) +void WgStageBufferGeometry::bind(WGPURenderPassEncoder renderPass, size_t voffset, size_t toffset) { wgpuRenderPassEncoderSetVertexBuffer(renderPass, 0, vbuffer_gpu, voffset, vbuffer.count - voffset); wgpuRenderPassEncoderSetVertexBuffer(renderPass, 1, vbuffer_gpu, toffset, vbuffer.count - toffset); diff --git a/src/renderer/wg_engine/tvgWgRenderData.h b/src/renderer/wg_engine/tvgWgRenderData.h index ba3805a2..7d5b14b7 100644 --- a/src/renderer/wg_engine/tvgWgRenderData.h +++ b/src/renderer/wg_engine/tvgWgRenderData.h @@ -94,9 +94,8 @@ struct WgRenderSettings struct WgRenderDataPaint { - WGPUBuffer bufferModelMat{}; - WGPUBuffer bufferBlendSettings{}; - WGPUBindGroup bindGroupPaint{}; + WgShaderTypePaintSettings paintSettings; + uint32_t bindGroupPaintInd{}; RenderRegion viewport{}; BBox aabb{{},{}}; float opacity{}; @@ -221,7 +220,7 @@ public: void release(WgContext& context); }; -class WgRenderDataStageBuffer { +class WgStageBufferGeometry { private: Array vbuffer; Array ibuffer; @@ -240,4 +239,50 @@ public: void bind(WGPURenderPassEncoder renderPass, size_t voffset, size_t toffset); }; +// typed uniform stage buffer with related bind groups handling +template +class WgStageBufferUniform { +private: + Array ubuffer; + WGPUBuffer ubuffer_gpu{}; + Array bbuffer; +public: + // append uniform data to cpu staged buffer and return related bind group index + uint32_t append(const T& value) { + ubuffer.push(value); + return ubuffer.count - 1; + } + + void flush(WgContext& context) { + // flush data to gpu buffer from cpu memory including reserved data to prevent future gpu buffer reallocations + bool bufferChanged = context.allocateBufferUniform(ubuffer_gpu, (void*)ubuffer.data, ubuffer.reserved*sizeof(T)); + // if gpu buffer handle was changed we must to remove all created binding groups + if (bufferChanged) releaseBindGroups(context); + // allocate bind groups for all new data items + for (uint32_t i = bbuffer.count; i < ubuffer.count; i++) + bbuffer.push(context.layouts.createBindGroupBuffer1Un(ubuffer_gpu, i*sizeof(T), sizeof(T))); + assert(bbuffer.count >= ubuffer.count); + } + + // please, use index that was returned from append method + WGPUBindGroup operator[](const uint32_t index) const { + return bbuffer[index]; + } + + void clear() { + ubuffer.clear(); + } + + void release(WgContext& context) { + context.releaseBuffer(ubuffer_gpu); + releaseBindGroups(context); + } + + void releaseBindGroups(WgContext& context) { + ARRAY_FOREACH(p, bbuffer) + context.layouts.releaseBindGroup(*p); + bbuffer.clear(); + } +}; + #endif // _TVG_WG_RENDER_DATA_H_ diff --git a/src/renderer/wg_engine/tvgWgShaderSrc.cpp b/src/renderer/wg_engine/tvgWgShaderSrc.cpp index 53fa134a..052bbe9a 100644 --- a/src/renderer/wg_engine/tvgWgShaderSrc.cpp +++ b/src/renderer/wg_engine/tvgWgShaderSrc.cpp @@ -32,14 +32,15 @@ const char* cShaderSrc_Stencil = R"( struct VertexInput { @location(0) position: vec2f }; struct VertexOutput { @builtin(position) position: vec4f }; +struct PaintSettings { modelMat : mat4x4f, blendSettings: vec4f }; @group(0) @binding(0) var uViewMat : mat4x4f; -@group(1) @binding(0) var uModelMat : mat4x4f; +@group(1) @binding(0) var uPaintSettings : PaintSettings; @vertex fn vs_main(in: VertexInput) -> VertexOutput { var out: VertexOutput; - out.position = uViewMat * uModelMat * vec4f(in.position.xy, 0.0, 1.0); + out.position = uViewMat * uPaintSettings.modelMat * vec4f(in.position.xy, 0.0, 1.0); return out; } @@ -56,15 +57,16 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4f { const char* cShaderSrc_Depth = R"( struct VertexInput { @location(0) position: vec2f }; struct VertexOutput { @builtin(position) position: vec4f }; +struct PaintSettings { modelMat : mat4x4f, blendSettings: vec4f }; @group(0) @binding(0) var uViewMat : mat4x4f; -@group(1) @binding(0) var uModelMat : mat4x4f; +@group(1) @binding(0) var uPaintSettings : PaintSettings; @group(2) @binding(0) var uDepth : f32; @vertex fn vs_main(in: VertexInput) -> VertexOutput { var out: VertexOutput; - out.position = uViewMat * uModelMat * vec4f(in.position.xy, 0.0, 1.0); + out.position = uViewMat * uPaintSettings.modelMat * vec4f(in.position.xy, 0.0, 1.0); out.position.z = uDepth; return out; } @@ -82,23 +84,23 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4f { const char* cShaderSrc_Solid = R"( struct VertexInput { @location(0) position: vec2f }; struct VertexOutput { @builtin(position) position: vec4f }; +struct PaintSettings { modelMat : mat4x4f, blendSettings: vec4f }; @group(0) @binding(0) var uViewMat : mat4x4f; -@group(1) @binding(0) var uModelMat : mat4x4f; -@group(1) @binding(1) var uBlendSettings : vec4f; +@group(1) @binding(0) var uPaintSettings : PaintSettings; @group(2) @binding(0) var uSolidColor : vec4f; @vertex fn vs_main(in: VertexInput) -> VertexOutput { var out: VertexOutput; - out.position = uViewMat * uModelMat * vec4f(in.position.xy, 0.0, 1.0); + out.position = uViewMat * uPaintSettings.modelMat * vec4f(in.position.xy, 0.0, 1.0); return out; } @fragment fn fs_main(in: VertexOutput) -> @location(0) vec4f { let Sc = uSolidColor; - let So = uBlendSettings.a; + let So = uPaintSettings.blendSettings.a; return vec4f(Sc.rgb * Sc.a * So, Sc.a * So); } )"; @@ -110,12 +112,12 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4f { const char* cShaderSrc_Linear = R"( struct VertexInput { @location(0) position: vec2f }; struct VertexOutput { @builtin(position) position : vec4f, @location(0) vGradCoord : vec4f }; +struct PaintSettings { modelMat : mat4x4f, blendSettings: vec4f }; struct GradSettings { settings: vec4f, focal: vec4f }; // uniforms @group(0) @binding(0) var uViewMat : mat4x4f; -@group(1) @binding(0) var uModelMat : mat4x4f; -@group(1) @binding(1) var uBlendSettings : vec4f; +@group(1) @binding(0) var uPaintSettings : PaintSettings; @group(2) @binding(0) var uSamplerGrad : sampler; @group(2) @binding(1) var uTextureGrad : texture_2d; @group(2) @binding(2) var uSettingGrad : GradSettings; @@ -124,7 +126,7 @@ struct GradSettings { settings: vec4f, focal: vec4f }; @vertex fn vs_main(in: VertexInput) -> VertexOutput { var out: VertexOutput; - out.position = uViewMat * uModelMat * vec4f(in.position.xy, 0.0, 1.0); + out.position = uViewMat * uPaintSettings.modelMat * vec4f(in.position.xy, 0.0, 1.0); out.vGradCoord = uTransformGrad * vec4f(in.position.xy, 0.0, 1.0); return out; } @@ -137,7 +139,7 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4f { let ba = ed - st; let t = dot(pos - st, ba) / dot(ba, ba); let Sc = textureSample(uTextureGrad, uSamplerGrad, vec2f(t, 0.5)); - let So = uBlendSettings.a; + let So = uPaintSettings.blendSettings.a; return vec4f(Sc.rgb * Sc.a * So, Sc.a * So); } )"; @@ -149,11 +151,11 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4f { const char* cShaderSrc_Radial = R"( struct VertexInput { @location(0) position: vec2f }; struct VertexOutput { @builtin(position) position : vec4f, @location(0) vGradCoord : vec4f }; +struct PaintSettings { modelMat : mat4x4f, blendSettings: vec4f }; struct GradSettings { settings: vec4f, focal: vec4f }; @group(0) @binding(0) var uViewMat : mat4x4f; -@group(1) @binding(0) var uModelMat : mat4x4f; -@group(1) @binding(1) var uBlendSettings : vec4f; +@group(1) @binding(0) var uPaintSettings : PaintSettings; @group(2) @binding(0) var uSamplerGrad : sampler; @group(2) @binding(1) var uTextureGrad : texture_2d; @group(2) @binding(2) var uSettingGrad : GradSettings; @@ -162,7 +164,7 @@ struct GradSettings { settings: vec4f, focal: vec4f }; @vertex fn vs_main(in: VertexInput) -> VertexOutput { var out: VertexOutput; - out.position = uViewMat * uModelMat * vec4f(in.position.xy, 0.0, 1.0); + out.position = uViewMat * uPaintSettings.modelMat * vec4f(in.position.xy, 0.0, 1.0); out.vGradCoord = uTransformGrad * vec4f(in.position.xy, 0.0, 1.0); return out; } @@ -179,7 +181,7 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4f { let c = 1.0*dot(d0, d0) - 1.0*r0*r0; let t = (-b + sqrt(b*b - 4*a*c))/(2*a); let Sc = textureSample(uTextureGrad, uSamplerGrad, vec2f(1.0 - t, 0.5)); - let So = uBlendSettings.a; + let So = uPaintSettings.blendSettings.a; return vec4f(Sc.rgb * Sc.a * So, Sc.a * So); } )"; @@ -191,17 +193,17 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4f { const char* cShaderSrc_Image = R"( struct VertexInput { @location(0) position: vec2f, @location(1) texCoord: vec2f }; struct VertexOutput { @builtin(position) position: vec4f, @location(0) vTexCoord: vec2f }; +struct PaintSettings { modelMat : mat4x4f, blendSettings: vec4f }; @group(0) @binding(0) var uViewMat : mat4x4f; -@group(1) @binding(0) var uModelMat : mat4x4f; -@group(1) @binding(1) var uBlendSettings : vec4f; +@group(1) @binding(0) var uPaintSettings : PaintSettings; @group(2) @binding(0) var uSampler : sampler; @group(2) @binding(1) var uTextureView : texture_2d; @vertex fn vs_main(in: VertexInput) -> VertexOutput { var out: VertexOutput; - out.position = uViewMat * uModelMat * vec4f(in.position.xy, 0.0, 1.0); + out.position = uViewMat * uPaintSettings.modelMat * vec4f(in.position.xy, 0.0, 1.0); out.vTexCoord = in.texCoord; return out; } @@ -209,7 +211,7 @@ fn vs_main(in: VertexInput) -> VertexOutput { @fragment fn fs_main(in: VertexOutput) -> @location(0) vec4f { var Sc: vec4f = textureSample(uTextureView, uSampler, in.vTexCoord.xy); - let So: f32 = uBlendSettings.a; + let So: f32 = uPaintSettings.blendSettings.a; return vec4f(Sc.rgb * Sc.a * So, Sc.a * So); }; )"; @@ -248,10 +250,10 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4f { const char* cShaderSrc_Solid_Blend = R"( struct VertexInput { @location(0) position: vec2f }; struct VertexOutput { @builtin(position) position: vec4f, @location(1) vScrCoord: vec2f }; +struct PaintSettings { modelMat : mat4x4f, blendSettings: vec4f }; @group(0) @binding(0) var uViewMat : mat4x4f; -@group(1) @binding(0) var uModelMat : mat4x4f; -@group(1) @binding(1) var uBlendSettings : vec4f; +@group(1) @binding(0) var uPaintSettings : PaintSettings; @group(2) @binding(0) var uSolidColor : vec4f; @group(3) @binding(0) var uSamplerDst : sampler; @group(3) @binding(1) var uTextureDst : texture_2d; @@ -259,7 +261,7 @@ struct VertexOutput { @builtin(position) position: vec4f, @location(1) vScrCoord @vertex fn vs_main(in: VertexInput) -> VertexOutput { var out: VertexOutput; - let pos = uViewMat * uModelMat * vec4f(in.position.xy, 0.0, 1.0); + let pos = uViewMat * uPaintSettings.modelMat * vec4f(in.position.xy, 0.0, 1.0); out.position = pos; out.vScrCoord = vec2f(0.5 + pos.x * 0.5, 0.5 - pos.y * 0.5); return out; @@ -274,7 +276,7 @@ fn getFragData(in: VertexOutput) -> FragData { var data: FragData; data.Sc = colorSrc.rgb; data.Sa = colorSrc.a; - data.So = uBlendSettings.a; + data.So = uPaintSettings.blendSettings.a; data.Dc = colorDst.rgb; data.Da = colorDst.a; data.Sc = data.Sa * data.So * data.Sc; @@ -288,11 +290,11 @@ fn postProcess(d: FragData, R: vec4f) -> vec4f { return R; }; const char* cShaderSrc_Linear_Blend = R"( struct VertexInput { @location(0) position: vec2f }; struct VertexOutput { @builtin(position) position: vec4f, @location(0) vGradCoord : vec4f, @location(1) vScrCoord: vec2f }; +struct PaintSettings { modelMat : mat4x4f, blendSettings: vec4f }; struct GradSettings { settings: vec4f, focal: vec4f }; @group(0) @binding(0) var uViewMat : mat4x4f; -@group(1) @binding(0) var uModelMat : mat4x4f; -@group(1) @binding(1) var uBlendSettings : vec4f; +@group(1) @binding(0) var uPaintSettings : PaintSettings; @group(2) @binding(0) var uSamplerGrad : sampler; @group(2) @binding(1) var uTextureGrad : texture_2d; @group(2) @binding(2) var uSettingGrad : vec4f; @@ -303,7 +305,7 @@ struct GradSettings { settings: vec4f, focal: vec4f }; @vertex fn vs_main(in: VertexInput) -> VertexOutput { var out: VertexOutput; - let pos = uViewMat * uModelMat * vec4f(in.position.xy, 0.0, 1.0); + let pos = uViewMat * uPaintSettings.modelMat * vec4f(in.position.xy, 0.0, 1.0); out.position = pos; out.vGradCoord = uTransformGrad * vec4f(in.position.xy, 0.0, 1.0); out.vScrCoord = vec2f(0.5 + pos.x * 0.5, 0.5 - pos.y * 0.5); @@ -324,7 +326,7 @@ fn getFragData(in: VertexOutput) -> FragData { var data: FragData; data.Sc = colorSrc.rgb; data.Sa = colorSrc.a; - data.So = uBlendSettings.a; + data.So = uPaintSettings.blendSettings.a; data.Dc = colorDst.rgb; data.Da = colorDst.a; data.Sc = mix(data.Dc, data.Sc, data.Sa * data.So); @@ -338,11 +340,11 @@ fn postProcess(d: FragData, R: vec4f) -> vec4f { return R; }; const char* cShaderSrc_Radial_Blend = R"( struct VertexInput { @location(0) position: vec2f }; struct VertexOutput { @builtin(position) position: vec4f, @location(0) vGradCoord : vec4f, @location(1) vScrCoord: vec2f }; +struct PaintSettings { modelMat : mat4x4f, blendSettings: vec4f }; struct GradSettings { settings: vec4f, focal: vec4f }; @group(0) @binding(0) var uViewMat : mat4x4f; -@group(1) @binding(0) var uModelMat : mat4x4f; -@group(1) @binding(1) var uBlendSettings : vec4f; +@group(1) @binding(0) var uPaintSettings : PaintSettings; @group(2) @binding(0) var uSamplerGrad : sampler; @group(2) @binding(1) var uTextureGrad : texture_2d; @group(2) @binding(2) var uSettingGrad : GradSettings; @@ -353,7 +355,7 @@ struct GradSettings { settings: vec4f, focal: vec4f }; @vertex fn vs_main(in: VertexInput) -> VertexOutput { var out: VertexOutput; - let pos = uViewMat * uModelMat * vec4f(in.position.xy, 0.0, 1.0); + let pos = uViewMat * uPaintSettings.modelMat * vec4f(in.position.xy, 0.0, 1.0); out.position = pos; out.vGradCoord = uTransformGrad * vec4f(in.position.xy, 0.0, 1.0); out.vScrCoord = vec2f(0.5 + pos.x * 0.5, 0.5 - pos.y * 0.5); @@ -376,7 +378,7 @@ fn getFragData(in: VertexOutput) -> FragData { var data: FragData; data.Sc = colorSrc.rgb; data.Sa = colorSrc.a; - data.So = uBlendSettings.a; + data.So = uPaintSettings.blendSettings.a; data.Dc = colorDst.rgb; data.Da = colorDst.a; data.Sc = mix(data.Dc, data.Sc, data.Sa * data.So); @@ -390,11 +392,11 @@ fn postProcess(d: FragData, R: vec4f) -> vec4f { return R; }; const char* cShaderSrc_Image_Blend = R"( struct VertexInput { @location(0) position: vec2f, @location(1) texCoord: vec2f }; struct VertexOutput { @builtin(position) position: vec4f, @location(0) vTexCoord : vec2f, @location(1) vScrCoord: vec2f }; +struct PaintSettings { modelMat : mat4x4f, blendSettings: vec4f }; @group(0) @binding(0) var uViewMat : mat4x4f; -@group(1) @binding(0) var uModelMat : mat4x4f; -@group(1) @binding(1) var uBlendSettings : vec4f; -@group(2) @binding(0) var uSamplerSrc : sampler; +@group(1) @binding(0) var uPaintSettings : PaintSettings; +@group(2) @binding(0) var uSamplerSrc : sampler; @group(2) @binding(1) var uTextureSrc : texture_2d; @group(3) @binding(0) var uSamplerDst : sampler; @group(3) @binding(1) var uTextureDst : texture_2d; @@ -402,7 +404,7 @@ struct VertexOutput { @builtin(position) position: vec4f, @location(0) vTexCoord @vertex fn vs_main(in: VertexInput) -> VertexOutput { var out: VertexOutput; - let pos = uViewMat * uModelMat * vec4f(in.position.xy, 0.0, 1.0); + let pos = uViewMat * uPaintSettings.modelMat * vec4f(in.position.xy, 0.0, 1.0); out.position = pos; out.vTexCoord = in.texCoord; out.vScrCoord = vec2f(0.5 + pos.x * 0.5, 0.5 - pos.y * 0.5); @@ -418,7 +420,7 @@ fn getFragData(in: VertexOutput) -> FragData { var data: FragData; data.Sc = colorSrc.rgb; data.Sa = colorSrc.a; - data.So = uBlendSettings.a; + data.So = uPaintSettings.blendSettings.a; data.Dc = colorDst.rgb; data.Da = colorDst.a; data.Sc = data.Sc * data.So; diff --git a/src/renderer/wg_engine/tvgWgShaderTypes.h b/src/renderer/wg_engine/tvgWgShaderTypes.h index 66853217..400426b0 100644 --- a/src/renderer/wg_engine/tvgWgShaderTypes.h +++ b/src/renderer/wg_engine/tvgWgShaderTypes.h @@ -55,6 +55,16 @@ struct WgShaderTypeVec4f void update(const RenderRegion& r); }; +// base paint settings - transform and blend settings (alligned to 256 bytes) +struct WgShaderTypePaintSettings +{ + WgShaderTypeMat4x4f modelMat; + WgShaderTypeVec4f blendSettings; + uint8_t _padding[256 - sizeof(modelMat) - sizeof(blendSettings)]; +}; +// must be alligned with in-shader data type +static_assert(sizeof(WgShaderTypePaintSettings) == 256); + // sampler, texture, vec4f #define WG_TEXTURE_GRADIENT_SIZE 512 struct WgShaderTypeGradient