This commit is contained in:
Sergii Liebodkin 2025-06-06 11:07:06 +00:00 committed by GitHub
commit 0a999ad13d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 171 additions and 110 deletions

View file

@ -103,9 +103,15 @@ WGPUBindGroup WgBindGroupLayouts::createBindGroupStrorage3RO(WGPUTextureView tex
WGPUBindGroup WgBindGroupLayouts::createBindGroupBuffer1Un(WGPUBuffer buff) 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[] = { 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 }; const WGPUBindGroupDescriptor bindGroupDesc { .layout = layoutBuffer1Un, .entryCount = 1, .entries = bindGroupEntrys };
return wgpuDeviceCreateBindGroup(device, &bindGroupDesc); return wgpuDeviceCreateBindGroup(device, &bindGroupDesc);

View file

@ -49,6 +49,7 @@ public:
WGPUBindGroup createBindGroupStrorage2RO(WGPUTextureView texView0, WGPUTextureView texView1); WGPUBindGroup createBindGroupStrorage2RO(WGPUTextureView texView0, WGPUTextureView texView1);
WGPUBindGroup createBindGroupStrorage3RO(WGPUTextureView texView0, WGPUTextureView texView1, WGPUTextureView texView2); WGPUBindGroup createBindGroupStrorage3RO(WGPUTextureView texView0, WGPUTextureView texView1, WGPUTextureView texView2);
WGPUBindGroup createBindGroupBuffer1Un(WGPUBuffer buff); WGPUBindGroup createBindGroupBuffer1Un(WGPUBuffer buff);
WGPUBindGroup createBindGroupBuffer1Un(WGPUBuffer buff, uint64_t offset, uint64_t size);
WGPUBindGroup createBindGroupBuffer2Un(WGPUBuffer buff0, WGPUBuffer buff1); WGPUBindGroup createBindGroupBuffer2Un(WGPUBuffer buff0, WGPUBuffer buff1);
WGPUBindGroup createBindGroupBuffer3Un(WGPUBuffer buff0, WGPUBuffer buff1, WGPUBuffer buff2); WGPUBindGroup createBindGroupBuffer3Un(WGPUBuffer buff0, WGPUBuffer buff1, WGPUBuffer buff2);
void releaseBindGroup(WGPUBindGroup& bindGroup); void releaseBindGroup(WGPUBindGroup& bindGroup);

View file

@ -28,7 +28,7 @@ void WgCompositor::initialize(WgContext& context, uint32_t width, uint32_t heigh
{ {
// pipelines (external handle, do not release) // pipelines (external handle, do not release)
pipelines.initialize(context); pipelines.initialize(context);
stageBuffer.initialize(context); stageBufferGeometry.initialize(context);
// initialize opacity pool // initialize opacity pool
initPools(context); initPools(context);
// allocate global view matrix handles // allocate global view matrix handles
@ -64,7 +64,8 @@ void WgCompositor::release(WgContext& context)
context.layouts.releaseBindGroup(bindGroupViewMat); context.layouts.releaseBindGroup(bindGroupViewMat);
context.releaseBuffer(bufferViewMat); context.releaseBuffer(bufferViewMat);
// release stage buffer // release stage buffer
stageBuffer.release(context); stageBufferPaint.release(context);
stageBufferGeometry.release(context);
// release pipelines // release pipelines
pipelines.release(context); pipelines.release(context);
} }
@ -190,27 +191,31 @@ void WgCompositor::endRenderPass()
void WgCompositor::reset(WgContext& context) void WgCompositor::reset(WgContext& context)
{ {
stageBuffer.clear(); stageBufferGeometry.clear();
stageBufferPaint.clear();
} }
void WgCompositor::flush(WgContext& context) void WgCompositor::flush(WgContext& context)
{ {
stageBuffer.append(&meshDataBlit); stageBufferGeometry.append(&meshDataBlit);
stageBuffer.flush(context); stageBufferGeometry.flush(context);
stageBufferPaint.flush(context);
} }
void WgCompositor::requestShape(WgRenderDataShape* renderData) void WgCompositor::requestShape(WgRenderDataShape* renderData)
{ {
stageBuffer.append(renderData); stageBufferGeometry.append(renderData);
renderData->bindGroupPaintInd = stageBufferPaint.append(renderData->paintSettings);
// TODO: expand for fill settings // TODO: expand for fill settings
} }
void WgCompositor::requestImage(WgRenderDataPicture* renderData) void WgCompositor::requestImage(WgRenderDataPicture* renderData)
{ {
stageBuffer.append(renderData); stageBufferGeometry.append(renderData);
renderData->bindGroupPaintInd = stageBufferPaint.append(renderData->paintSettings);
// TODO: expand for fill settings // TODO: expand for fill settings
} }
@ -332,8 +337,8 @@ void WgCompositor::drawMesh(WgContext& context, WgMeshData* meshData)
uint64_t icount = meshData->ibuffer.count; uint64_t icount = meshData->ibuffer.count;
uint64_t vsize = meshData->vbuffer.count * sizeof(Point); uint64_t vsize = meshData->vbuffer.count * sizeof(Point);
uint64_t isize = icount * sizeof(uint32_t); 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, stageBuffer.ibuffer_gpu, WGPUIndexFormat_Uint32, meshData->ioffset, isize); wgpuRenderPassEncoderSetIndexBuffer(renderPassEncoder, stageBufferGeometry.ibuffer_gpu, WGPUIndexFormat_Uint32, meshData->ioffset, isize);
wgpuRenderPassEncoderDrawIndexed(renderPassEncoder, icount, 1, 0, 0, 0); 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 icount = (meshData->vbuffer.count - 2) * 3;
uint64_t vsize = meshData->vbuffer.count * sizeof(Point); uint64_t vsize = meshData->vbuffer.count * sizeof(Point);
uint64_t isize = icount * sizeof(uint32_t); 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); wgpuRenderPassEncoderSetIndexBuffer(renderPassEncoder, context.bufferIndexFan, WGPUIndexFormat_Uint32, 0, isize);
wgpuRenderPassEncoderDrawIndexed(renderPassEncoder, icount, 1, 0, 0, 0); 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 icount = meshData->ibuffer.count;
uint64_t vsize = meshData->vbuffer.count * sizeof(Point); uint64_t vsize = meshData->vbuffer.count * sizeof(Point);
uint64_t isize = icount * sizeof(uint32_t); 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);
wgpuRenderPassEncoderSetVertexBuffer(renderPassEncoder, 1, stageBuffer.vbuffer_gpu, meshData->toffset, vsize); wgpuRenderPassEncoderSetVertexBuffer(renderPassEncoder, 1, stageBufferGeometry.vbuffer_gpu, meshData->toffset, vsize);
wgpuRenderPassEncoderSetIndexBuffer(renderPassEncoder, stageBuffer.ibuffer_gpu, WGPUIndexFormat_Uint32, meshData->ioffset, isize); wgpuRenderPassEncoderSetIndexBuffer(renderPassEncoder, stageBufferGeometry.ibuffer_gpu, WGPUIndexFormat_Uint32, meshData->ioffset, isize);
wgpuRenderPassEncoderDrawIndexed(renderPassEncoder, icount, 1, 0, 0, 0); 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; WGPURenderPipeline stencilPipeline = (renderData->fillRule == FillRule::NonZero) ? pipelines.nonzero : pipelines.evenodd;
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0); wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, stageBufferPaint[renderData->bindGroupPaintInd], 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, stencilPipeline); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, stencilPipeline);
// draw to stencil (first pass) // draw to stencil (first pass)
ARRAY_FOREACH(p, renderData->meshGroupShapes.meshes) ARRAY_FOREACH(p, renderData->meshGroupShapes.meshes)
@ -384,7 +389,7 @@ void WgCompositor::drawShape(WgContext& context, WgRenderDataShape* renderData)
// setup fill rules // setup fill rules
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0); wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); 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; WgRenderSettings& settings = renderData->renderSettingsShape;
if (settings.fillType == WgRenderSettingsType::Solid) { if (settings.fillType == WgRenderSettingsType::Solid) {
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, settings.bindGroupSolid, 0, nullptr); 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; WGPURenderPipeline stencilPipeline = (renderData->fillRule == FillRule::NonZero) ? pipelines.nonzero : pipelines.evenodd;
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0); wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, stageBufferPaint[renderData->bindGroupPaintInd], 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, stencilPipeline); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, stencilPipeline);
// draw to stencil (first pass) // draw to stencil (first pass)
ARRAY_FOREACH(p, renderData->meshGroupShapes.meshes) ARRAY_FOREACH(p, renderData->meshGroupShapes.meshes)
@ -426,7 +431,7 @@ void WgCompositor::blendShape(WgContext& context, WgRenderDataShape* renderData,
// setup fill rules // setup fill rules
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0); wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); 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); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 3, targetTemp0.bindGroupTexure, 0, nullptr);
uint32_t blendMethodInd = (uint32_t)blendMethod; uint32_t blendMethodInd = (uint32_t)blendMethod;
WgRenderSettings& settings = renderData->renderSettingsShape; 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; WGPURenderPipeline stencilPipeline = (renderData->fillRule == FillRule::NonZero) ? pipelines.nonzero : pipelines.evenodd;
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0); wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, stageBufferPaint[renderData->bindGroupPaintInd], 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, stencilPipeline); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, stencilPipeline);
// draw to stencil (first pass) // draw to stencil (first pass)
ARRAY_FOREACH(p, renderData->meshGroupShapes.meshes) ARRAY_FOREACH(p, renderData->meshGroupShapes.meshes)
@ -470,7 +475,7 @@ void WgCompositor::clipShape(WgContext& context, WgRenderDataShape* renderData)
// setup fill rules // setup fill rules
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0); wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); 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; WgRenderSettings& settings = renderData->renderSettingsShape;
if (settings.fillType == WgRenderSettingsType::Solid) { if (settings.fillType == WgRenderSettingsType::Solid) {
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, settings.bindGroupSolid, 0, nullptr); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, settings.bindGroupSolid, 0, nullptr);
@ -500,14 +505,14 @@ void WgCompositor::drawStrokes(WgContext& context, WgRenderDataShape* renderData
// setup stencil rules // setup stencil rules
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 255); wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 255);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); 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); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.direct);
// draw to stencil (first pass) // draw to stencil (first pass)
drawMesh(context, renderData->meshGroupStrokes.meshes[i]); drawMesh(context, renderData->meshGroupStrokes.meshes[i]);
// setup fill rules // setup fill rules
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0); wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); 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; WgRenderSettings& settings = renderData->renderSettingsStroke;
if (settings.fillType == WgRenderSettingsType::Solid) { if (settings.fillType == WgRenderSettingsType::Solid) {
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, settings.bindGroupSolid, 0, nullptr); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, settings.bindGroupSolid, 0, nullptr);
@ -543,14 +548,14 @@ void WgCompositor::blendStrokes(WgContext& context, WgRenderDataShape* renderDat
// setup stencil rules // setup stencil rules
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 255); wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 255);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); 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); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.direct);
// draw to stencil (first pass) // draw to stencil (first pass)
drawMesh(context, renderData->meshGroupStrokes.meshes[i]); drawMesh(context, renderData->meshGroupStrokes.meshes[i]);
// setup fill rules // setup fill rules
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0); wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); 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); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 3, targetTemp0.bindGroupTexure, 0, nullptr);
uint32_t blendMethodInd = (uint32_t)blendMethod; uint32_t blendMethodInd = (uint32_t)blendMethod;
WgRenderSettings& settings = renderData->renderSettingsStroke; WgRenderSettings& settings = renderData->renderSettingsStroke;
@ -584,7 +589,7 @@ void WgCompositor::clipStrokes(WgContext& context, WgRenderDataShape* renderData
// setup stencil rules // setup stencil rules
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 255); wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 255);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); 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); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.direct);
// draw to stencil (first pass) // draw to stencil (first pass)
drawMesh(context, renderData->meshGroupStrokes.meshes[i]); drawMesh(context, renderData->meshGroupStrokes.meshes[i]);
@ -596,7 +601,7 @@ void WgCompositor::clipStrokes(WgContext& context, WgRenderDataShape* renderData
// setup fill rules // setup fill rules
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0); wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); 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; WgRenderSettings& settings = renderData->renderSettingsStroke;
if (settings.fillType == WgRenderSettingsType::Solid) { if (settings.fillType == WgRenderSettingsType::Solid) {
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, settings.bindGroupSolid, 0, nullptr); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, settings.bindGroupSolid, 0, nullptr);
@ -623,13 +628,13 @@ void WgCompositor::drawImage(WgContext& context, WgRenderDataPicture* renderData
// draw stencil // draw stencil
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 255); wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 255);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); 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); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.direct);
drawMeshImage(context, &renderData->meshData); drawMeshImage(context, &renderData->meshData);
// draw image // draw image
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0); wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); 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, 2, renderData->bindGroupPicture, 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.image); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.image);
drawMeshImage(context, &renderData->meshData); drawMeshImage(context, &renderData->meshData);
@ -650,14 +655,14 @@ void WgCompositor::blendImage(WgContext& context, WgRenderDataPicture* renderDat
// setup stencil rules // setup stencil rules
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 255); wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 255);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); 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); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.direct);
drawMeshImage(context, &renderData->meshData); drawMeshImage(context, &renderData->meshData);
// blend image // blend image
uint32_t blendMethodInd = (uint32_t)blendMethod; uint32_t blendMethodInd = (uint32_t)blendMethod;
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0); wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); 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, 2, renderData->bindGroupPicture, 0, nullptr);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 3, targetTemp0.bindGroupTexure, 0, nullptr); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 3, targetTemp0.bindGroupTexure, 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.image_blend[blendMethodInd]); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.image_blend[blendMethodInd]);
@ -674,7 +679,7 @@ void WgCompositor::clipImage(WgContext& context, WgRenderDataPicture* renderData
// setup stencil rules // setup stencil rules
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 255); wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 255);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); 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); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.direct);
drawMeshImage(context, &renderData->meshData); drawMeshImage(context, &renderData->meshData);
// merge depth and stencil buffer // merge depth and stencil buffer
@ -685,7 +690,7 @@ void WgCompositor::clipImage(WgContext& context, WgRenderDataPicture* renderData
// draw image // draw image
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0); wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); 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, 2, renderData->bindGroupPicture, 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.image); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.image);
drawMeshImage(context, &renderData->meshData); drawMeshImage(context, &renderData->meshData);
@ -734,7 +739,7 @@ void WgCompositor::blendScene(WgContext& context, WgRenderTarget* scene, WgCompo
void WgCompositor::markupClipPath(WgContext& context, WgRenderDataShape* renderData) void WgCompositor::markupClipPath(WgContext& context, WgRenderDataShape* renderData)
{ {
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, stageBufferPaint[renderData->bindGroupPaintInd], 0, nullptr);
// markup stencil // markup stencil
if (renderData->meshGroupStrokes.meshes.count > 0) { if (renderData->meshGroupStrokes.meshes.count > 0) {
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 255); wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 255);
@ -765,7 +770,7 @@ void WgCompositor::renderClipPath(WgContext& context, WgRenderDataPaint* paint)
// copy stencil to depth // copy stencil to depth
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0); wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); 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); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, bindGroupOpacities[128], 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.copy_stencil_to_depth); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.copy_stencil_to_depth);
drawMeshFan(context, &renderData0->meshDataBBox); drawMeshFan(context, &renderData0->meshDataBBox);
@ -777,31 +782,31 @@ void WgCompositor::renderClipPath(WgContext& context, WgRenderDataPaint* paint)
markupClipPath(context, renderData); markupClipPath(context, renderData);
// copy stencil to depth (clear stencil) // copy stencil to depth (clear stencil)
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0); 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); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, bindGroupOpacities[190], 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.copy_stencil_to_depth_interm); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.copy_stencil_to_depth_interm);
drawMeshFan(context, &renderData->meshDataBBox); drawMeshFan(context, &renderData->meshDataBBox);
// copy depth to stencil // copy depth to stencil
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 1); 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); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, bindGroupOpacities[190], 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.copy_depth_to_stencil); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.copy_depth_to_stencil);
drawMeshFan(context, &renderData->meshDataBBox); drawMeshFan(context, &renderData->meshDataBBox);
// clear depth current (keep stencil) // clear depth current (keep stencil)
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0); 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); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, bindGroupOpacities[255], 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.clear_depth); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.clear_depth);
drawMeshFan(context, &renderData->meshDataBBox); drawMeshFan(context, &renderData->meshDataBBox);
// clear depth original (keep stencil) // clear depth original (keep stencil)
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0); 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); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, bindGroupOpacities[255], 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.clear_depth); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.clear_depth);
drawMeshFan(context, &renderData0->meshDataBBox); drawMeshFan(context, &renderData0->meshDataBBox);
// copy stencil to depth (clear stencil) // copy stencil to depth (clear stencil)
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0); 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); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, bindGroupOpacities[128], 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.copy_stencil_to_depth); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.copy_stencil_to_depth);
drawMeshFan(context, &renderData->meshDataBBox); drawMeshFan(context, &renderData->meshDataBBox);
@ -822,7 +827,7 @@ void WgCompositor::clearClipPath(WgContext& context, WgRenderDataPaint* paint)
// set transformations // set transformations
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0); wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr); 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); wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, bindGroupOpacities[255], 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.clear_depth); wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.clear_depth);
drawMeshFan(context, &renderData->meshDataBBox); drawMeshFan(context, &renderData->meshDataBBox);

View file

@ -39,7 +39,8 @@ private:
// pipelines // pipelines
WgPipelines pipelines{}; WgPipelines pipelines{};
// stage buffers // stage buffers
WgRenderDataStageBuffer stageBuffer{}; WgStageBufferGeometry stageBufferGeometry{};
WgStageBufferUniform<WgShaderTypePaintSettings> stageBufferPaint;
// global stencil/depth buffer handles // global stencil/depth buffer handles
WGPUTexture texDepthStencil{}; WGPUTexture texDepthStencil{};
WGPUTextureView texViewDepthStencil{}; WGPUTextureView texViewDepthStencil{};

View file

@ -167,17 +167,17 @@ void WgPipelines::initialize(WgContext& context)
const WgBindGroupLayouts& layouts = context.layouts; const WgBindGroupLayouts& layouts = context.layouts;
// bind group layouts helpers // bind group layouts helpers
const WGPUBindGroupLayout bindGroupLayoutsStencil[] { layouts.layoutBuffer1Un, layouts.layoutBuffer2Un }; const WGPUBindGroupLayout bindGroupLayoutsStencil[] { layouts.layoutBuffer1Un, layouts.layoutBuffer1Un };
const WGPUBindGroupLayout bindGroupLayoutsDepth[] { layouts.layoutBuffer1Un, layouts.layoutBuffer2Un, layouts.layoutBuffer1Un }; const WGPUBindGroupLayout bindGroupLayoutsDepth[] { layouts.layoutBuffer1Un, layouts.layoutBuffer1Un, layouts.layoutBuffer1Un };
// bind group layouts normal blend // bind group layouts normal blend
const WGPUBindGroupLayout bindGroupLayoutsSolid[] { layouts.layoutBuffer1Un, layouts.layoutBuffer2Un, layouts.layoutBuffer1Un }; const WGPUBindGroupLayout bindGroupLayoutsSolid[] { layouts.layoutBuffer1Un, layouts.layoutBuffer1Un, layouts.layoutBuffer1Un };
const WGPUBindGroupLayout bindGroupLayoutsGradient[] { layouts.layoutBuffer1Un, layouts.layoutBuffer2Un, layouts.layoutTexSampledBuff2Un }; const WGPUBindGroupLayout bindGroupLayoutsGradient[] { layouts.layoutBuffer1Un, layouts.layoutBuffer1Un, layouts.layoutTexSampledBuff2Un };
const WGPUBindGroupLayout bindGroupLayoutsImage[] { layouts.layoutBuffer1Un, layouts.layoutBuffer2Un, layouts.layoutTexSampled }; const WGPUBindGroupLayout bindGroupLayoutsImage[] { layouts.layoutBuffer1Un, layouts.layoutBuffer1Un, layouts.layoutTexSampled };
const WGPUBindGroupLayout bindGroupLayoutsScene[] { layouts.layoutTexSampled, layouts.layoutBuffer1Un }; const WGPUBindGroupLayout bindGroupLayoutsScene[] { layouts.layoutTexSampled, layouts.layoutBuffer1Un };
// bind group layouts custom blend // bind group layouts custom blend
const WGPUBindGroupLayout bindGroupLayoutsSolidBlend[] { layouts.layoutBuffer1Un, layouts.layoutBuffer2Un, layouts.layoutBuffer1Un, layouts.layoutTexSampled }; const WGPUBindGroupLayout bindGroupLayoutsSolidBlend[] { layouts.layoutBuffer1Un, layouts.layoutBuffer1Un, layouts.layoutBuffer1Un, layouts.layoutTexSampled };
const WGPUBindGroupLayout bindGroupLayoutsGradientBlend[] { layouts.layoutBuffer1Un, layouts.layoutBuffer2Un, layouts.layoutTexSampledBuff2Un, layouts.layoutTexSampled }; const WGPUBindGroupLayout bindGroupLayoutsGradientBlend[] { layouts.layoutBuffer1Un, layouts.layoutBuffer1Un, layouts.layoutTexSampledBuff2Un, layouts.layoutTexSampled };
const WGPUBindGroupLayout bindGroupLayoutsImageBlend[] { layouts.layoutBuffer1Un, layouts.layoutBuffer2Un, layouts.layoutTexSampled, layouts.layoutTexSampled }; const WGPUBindGroupLayout bindGroupLayoutsImageBlend[] { layouts.layoutBuffer1Un, layouts.layoutBuffer1Un, layouts.layoutTexSampled, layouts.layoutTexSampled };
const WGPUBindGroupLayout bindGroupLayoutsSceneBlend[] { layouts.layoutTexSampled, layouts.layoutTexSampled, layouts.layoutBuffer1Un }; const WGPUBindGroupLayout bindGroupLayoutsSceneBlend[] { layouts.layoutTexSampled, layouts.layoutTexSampled, layouts.layoutBuffer1Un };
// bind group layouts scene compose // bind group layouts scene compose
const WGPUBindGroupLayout bindGroupLayoutsSceneCompose[] { layouts.layoutTexSampled, layouts.layoutTexSampled }; const WGPUBindGroupLayout bindGroupLayoutsSceneCompose[] { layouts.layoutTexSampled, layouts.layoutTexSampled };

View file

@ -284,23 +284,14 @@ void WgRenderSettings::release(WgContext& context)
void WgRenderDataPaint::release(WgContext& context) void WgRenderDataPaint::release(WgContext& context)
{ {
context.layouts.releaseBindGroup(bindGroupPaint);
context.releaseBuffer(bufferModelMat);
context.releaseBuffer(bufferBlendSettings);
clips.clear(); clips.clear();
}; };
void WgRenderDataPaint::update(WgContext& context, const tvg::Matrix& transform, tvg::ColorSpace cs, uint8_t opacity) void WgRenderDataPaint::update(WgContext& context, const tvg::Matrix& transform, tvg::ColorSpace cs, uint8_t opacity)
{ {
WgShaderTypeMat4x4f modelMat(transform); paintSettings.modelMat.update(transform);
WgShaderTypeVec4f blendSettings(cs, opacity); paintSettings.blendSettings.update(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);
}
} }
@ -676,10 +667,10 @@ void WgRenderDataEffectParamsPool::release(WgContext& context)
} }
//*********************************************************************** //***********************************************************************
// WgRenderDataStageBuffer // WgStageBufferGeometry
//*********************************************************************** //***********************************************************************
void WgRenderDataStageBuffer::append(WgMeshData* meshData) void WgStageBufferGeometry::append(WgMeshData* meshData)
{ {
assert(meshData); assert(meshData);
uint32_t vsize = meshData->vbuffer.count * sizeof(meshData->vbuffer[0]); 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); ARRAY_FOREACH(p, meshDataGroup->meshes) append(*p);
} }
void WgRenderDataStageBuffer::append(WgRenderDataShape* renderDataShape) void WgStageBufferGeometry::append(WgRenderDataShape* renderDataShape)
{ {
append(&renderDataShape->meshGroupShapes); append(&renderDataShape->meshGroupShapes);
append(&renderDataShape->meshGroupShapesBBox); 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); append(&renderDataPicture->meshData);
ARRAY_FOREACH(p, renderDataPicture->clips) 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(vbuffer_gpu);
context.releaseBuffer(ibuffer_gpu); context.releaseBuffer(ibuffer_gpu);
} }
void WgRenderDataStageBuffer::clear() void WgStageBufferGeometry::clear()
{ {
vbuffer.clear(); vbuffer.clear();
ibuffer.clear(); ibuffer.clear();
} }
void WgRenderDataStageBuffer::flush(WgContext& context) void WgStageBufferGeometry::flush(WgContext& context)
{ {
context.allocateBufferVertex(vbuffer_gpu, (float *)vbuffer.data, vbuffer.count); context.allocateBufferVertex(vbuffer_gpu, (float *)vbuffer.data, vbuffer.count);
context.allocateBufferIndex(ibuffer_gpu, (uint32_t *)ibuffer.data, ibuffer.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, 0, vbuffer_gpu, voffset, vbuffer.count - voffset);
wgpuRenderPassEncoderSetVertexBuffer(renderPass, 1, vbuffer_gpu, toffset, vbuffer.count - toffset); wgpuRenderPassEncoderSetVertexBuffer(renderPass, 1, vbuffer_gpu, toffset, vbuffer.count - toffset);

View file

@ -94,9 +94,8 @@ struct WgRenderSettings
struct WgRenderDataPaint struct WgRenderDataPaint
{ {
WGPUBuffer bufferModelMat{}; WgShaderTypePaintSettings paintSettings;
WGPUBuffer bufferBlendSettings{}; uint32_t bindGroupPaintInd{};
WGPUBindGroup bindGroupPaint{};
RenderRegion viewport{}; RenderRegion viewport{};
BBox aabb{{},{}}; BBox aabb{{},{}};
float opacity{}; float opacity{};
@ -221,7 +220,7 @@ public:
void release(WgContext& context); void release(WgContext& context);
}; };
class WgRenderDataStageBuffer { class WgStageBufferGeometry {
private: private:
Array<uint8_t> vbuffer; Array<uint8_t> vbuffer;
Array<uint8_t> ibuffer; Array<uint8_t> ibuffer;
@ -240,4 +239,50 @@ public:
void bind(WGPURenderPassEncoder renderPass, size_t voffset, size_t toffset); void bind(WGPURenderPassEncoder renderPass, size_t voffset, size_t toffset);
}; };
// typed uniform stage buffer with related bind groups handling
template<typename T>
class WgStageBufferUniform {
private:
Array<T> ubuffer;
WGPUBuffer ubuffer_gpu{};
Array<WGPUBindGroup> 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_ #endif // _TVG_WG_RENDER_DATA_H_

View file

@ -32,14 +32,15 @@
const char* cShaderSrc_Stencil = R"( const char* cShaderSrc_Stencil = R"(
struct VertexInput { @location(0) position: vec2f }; struct VertexInput { @location(0) position: vec2f };
struct VertexOutput { @builtin(position) position: vec4f }; struct VertexOutput { @builtin(position) position: vec4f };
struct PaintSettings { modelMat : mat4x4f, blendSettings: vec4f };
@group(0) @binding(0) var<uniform> uViewMat : mat4x4f; @group(0) @binding(0) var<uniform> uViewMat : mat4x4f;
@group(1) @binding(0) var<uniform> uModelMat : mat4x4f; @group(1) @binding(0) var<uniform> uPaintSettings : PaintSettings;
@vertex @vertex
fn vs_main(in: VertexInput) -> VertexOutput { fn vs_main(in: VertexInput) -> VertexOutput {
var out: 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; return out;
} }
@ -56,15 +57,16 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4f {
const char* cShaderSrc_Depth = R"( const char* cShaderSrc_Depth = R"(
struct VertexInput { @location(0) position: vec2f }; struct VertexInput { @location(0) position: vec2f };
struct VertexOutput { @builtin(position) position: vec4f }; struct VertexOutput { @builtin(position) position: vec4f };
struct PaintSettings { modelMat : mat4x4f, blendSettings: vec4f };
@group(0) @binding(0) var<uniform> uViewMat : mat4x4f; @group(0) @binding(0) var<uniform> uViewMat : mat4x4f;
@group(1) @binding(0) var<uniform> uModelMat : mat4x4f; @group(1) @binding(0) var<uniform> uPaintSettings : PaintSettings;
@group(2) @binding(0) var<uniform> uDepth : f32; @group(2) @binding(0) var<uniform> uDepth : f32;
@vertex @vertex
fn vs_main(in: VertexInput) -> VertexOutput { fn vs_main(in: VertexInput) -> VertexOutput {
var out: 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; out.position.z = uDepth;
return out; return out;
} }
@ -82,23 +84,23 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4f {
const char* cShaderSrc_Solid = R"( const char* cShaderSrc_Solid = R"(
struct VertexInput { @location(0) position: vec2f }; struct VertexInput { @location(0) position: vec2f };
struct VertexOutput { @builtin(position) position: vec4f }; struct VertexOutput { @builtin(position) position: vec4f };
struct PaintSettings { modelMat : mat4x4f, blendSettings: vec4f };
@group(0) @binding(0) var<uniform> uViewMat : mat4x4f; @group(0) @binding(0) var<uniform> uViewMat : mat4x4f;
@group(1) @binding(0) var<uniform> uModelMat : mat4x4f; @group(1) @binding(0) var<uniform> uPaintSettings : PaintSettings;
@group(1) @binding(1) var<uniform> uBlendSettings : vec4f;
@group(2) @binding(0) var<uniform> uSolidColor : vec4f; @group(2) @binding(0) var<uniform> uSolidColor : vec4f;
@vertex @vertex
fn vs_main(in: VertexInput) -> VertexOutput { fn vs_main(in: VertexInput) -> VertexOutput {
var out: 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; return out;
} }
@fragment @fragment
fn fs_main(in: VertexOutput) -> @location(0) vec4f { fn fs_main(in: VertexOutput) -> @location(0) vec4f {
let Sc = uSolidColor; let Sc = uSolidColor;
let So = uBlendSettings.a; let So = uPaintSettings.blendSettings.a;
return vec4f(Sc.rgb * Sc.a * So, Sc.a * So); 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"( const char* cShaderSrc_Linear = R"(
struct VertexInput { @location(0) position: vec2f }; struct VertexInput { @location(0) position: vec2f };
struct VertexOutput { @builtin(position) position : vec4f, @location(0) vGradCoord : vec4f }; struct VertexOutput { @builtin(position) position : vec4f, @location(0) vGradCoord : vec4f };
struct PaintSettings { modelMat : mat4x4f, blendSettings: vec4f };
struct GradSettings { settings: vec4f, focal: vec4f }; struct GradSettings { settings: vec4f, focal: vec4f };
// uniforms // uniforms
@group(0) @binding(0) var<uniform> uViewMat : mat4x4f; @group(0) @binding(0) var<uniform> uViewMat : mat4x4f;
@group(1) @binding(0) var<uniform> uModelMat : mat4x4f; @group(1) @binding(0) var<uniform> uPaintSettings : PaintSettings;
@group(1) @binding(1) var<uniform> uBlendSettings : vec4f;
@group(2) @binding(0) var uSamplerGrad : sampler; @group(2) @binding(0) var uSamplerGrad : sampler;
@group(2) @binding(1) var uTextureGrad : texture_2d<f32>; @group(2) @binding(1) var uTextureGrad : texture_2d<f32>;
@group(2) @binding(2) var<uniform> uSettingGrad : GradSettings; @group(2) @binding(2) var<uniform> uSettingGrad : GradSettings;
@ -124,7 +126,7 @@ struct GradSettings { settings: vec4f, focal: vec4f };
@vertex @vertex
fn vs_main(in: VertexInput) -> VertexOutput { fn vs_main(in: VertexInput) -> VertexOutput {
var out: 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); out.vGradCoord = uTransformGrad * vec4f(in.position.xy, 0.0, 1.0);
return out; return out;
} }
@ -137,7 +139,7 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4f {
let ba = ed - st; let ba = ed - st;
let t = dot(pos - st, ba) / dot(ba, ba); let t = dot(pos - st, ba) / dot(ba, ba);
let Sc = textureSample(uTextureGrad, uSamplerGrad, vec2f(t, 0.5)); 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); 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"( const char* cShaderSrc_Radial = R"(
struct VertexInput { @location(0) position: vec2f }; struct VertexInput { @location(0) position: vec2f };
struct VertexOutput { @builtin(position) position : vec4f, @location(0) vGradCoord : vec4f }; struct VertexOutput { @builtin(position) position : vec4f, @location(0) vGradCoord : vec4f };
struct PaintSettings { modelMat : mat4x4f, blendSettings: vec4f };
struct GradSettings { settings: vec4f, focal: vec4f }; struct GradSettings { settings: vec4f, focal: vec4f };
@group(0) @binding(0) var<uniform> uViewMat : mat4x4f; @group(0) @binding(0) var<uniform> uViewMat : mat4x4f;
@group(1) @binding(0) var<uniform> uModelMat : mat4x4f; @group(1) @binding(0) var<uniform> uPaintSettings : PaintSettings;
@group(1) @binding(1) var<uniform> uBlendSettings : vec4f;
@group(2) @binding(0) var uSamplerGrad : sampler; @group(2) @binding(0) var uSamplerGrad : sampler;
@group(2) @binding(1) var uTextureGrad : texture_2d<f32>; @group(2) @binding(1) var uTextureGrad : texture_2d<f32>;
@group(2) @binding(2) var<uniform> uSettingGrad : GradSettings; @group(2) @binding(2) var<uniform> uSettingGrad : GradSettings;
@ -162,7 +164,7 @@ struct GradSettings { settings: vec4f, focal: vec4f };
@vertex @vertex
fn vs_main(in: VertexInput) -> VertexOutput { fn vs_main(in: VertexInput) -> VertexOutput {
var out: 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); out.vGradCoord = uTransformGrad * vec4f(in.position.xy, 0.0, 1.0);
return out; 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 c = 1.0*dot(d0, d0) - 1.0*r0*r0;
let t = (-b + sqrt(b*b - 4*a*c))/(2*a); let t = (-b + sqrt(b*b - 4*a*c))/(2*a);
let Sc = textureSample(uTextureGrad, uSamplerGrad, vec2f(1.0 - t, 0.5)); 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); 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"( const char* cShaderSrc_Image = R"(
struct VertexInput { @location(0) position: vec2f, @location(1) texCoord: vec2f }; struct VertexInput { @location(0) position: vec2f, @location(1) texCoord: vec2f };
struct VertexOutput { @builtin(position) position: vec4f, @location(0) vTexCoord: vec2f }; struct VertexOutput { @builtin(position) position: vec4f, @location(0) vTexCoord: vec2f };
struct PaintSettings { modelMat : mat4x4f, blendSettings: vec4f };
@group(0) @binding(0) var<uniform> uViewMat : mat4x4f; @group(0) @binding(0) var<uniform> uViewMat : mat4x4f;
@group(1) @binding(0) var<uniform> uModelMat : mat4x4f; @group(1) @binding(0) var<uniform> uPaintSettings : PaintSettings;
@group(1) @binding(1) var<uniform> uBlendSettings : vec4f;
@group(2) @binding(0) var uSampler : sampler; @group(2) @binding(0) var uSampler : sampler;
@group(2) @binding(1) var uTextureView : texture_2d<f32>; @group(2) @binding(1) var uTextureView : texture_2d<f32>;
@vertex @vertex
fn vs_main(in: VertexInput) -> VertexOutput { fn vs_main(in: VertexInput) -> VertexOutput {
var out: 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; out.vTexCoord = in.texCoord;
return out; return out;
} }
@ -209,7 +211,7 @@ fn vs_main(in: VertexInput) -> VertexOutput {
@fragment @fragment
fn fs_main(in: VertexOutput) -> @location(0) vec4f { fn fs_main(in: VertexOutput) -> @location(0) vec4f {
var Sc: vec4f = textureSample(uTextureView, uSampler, in.vTexCoord.xy); 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); 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"( const char* cShaderSrc_Solid_Blend = R"(
struct VertexInput { @location(0) position: vec2f }; struct VertexInput { @location(0) position: vec2f };
struct VertexOutput { @builtin(position) position: vec4f, @location(1) vScrCoord: vec2f }; struct VertexOutput { @builtin(position) position: vec4f, @location(1) vScrCoord: vec2f };
struct PaintSettings { modelMat : mat4x4f, blendSettings: vec4f };
@group(0) @binding(0) var<uniform> uViewMat : mat4x4f; @group(0) @binding(0) var<uniform> uViewMat : mat4x4f;
@group(1) @binding(0) var<uniform> uModelMat : mat4x4f; @group(1) @binding(0) var<uniform> uPaintSettings : PaintSettings;
@group(1) @binding(1) var<uniform> uBlendSettings : vec4f;
@group(2) @binding(0) var<uniform> uSolidColor : vec4f; @group(2) @binding(0) var<uniform> uSolidColor : vec4f;
@group(3) @binding(0) var uSamplerDst : sampler; @group(3) @binding(0) var uSamplerDst : sampler;
@group(3) @binding(1) var uTextureDst : texture_2d<f32>; @group(3) @binding(1) var uTextureDst : texture_2d<f32>;
@ -259,7 +261,7 @@ struct VertexOutput { @builtin(position) position: vec4f, @location(1) vScrCoord
@vertex @vertex
fn vs_main(in: VertexInput) -> VertexOutput { fn vs_main(in: VertexInput) -> VertexOutput {
var out: 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.position = pos;
out.vScrCoord = vec2f(0.5 + pos.x * 0.5, 0.5 - pos.y * 0.5); out.vScrCoord = vec2f(0.5 + pos.x * 0.5, 0.5 - pos.y * 0.5);
return out; return out;
@ -274,7 +276,7 @@ fn getFragData(in: VertexOutput) -> FragData {
var data: FragData; var data: FragData;
data.Sc = colorSrc.rgb; data.Sc = colorSrc.rgb;
data.Sa = colorSrc.a; data.Sa = colorSrc.a;
data.So = uBlendSettings.a; data.So = uPaintSettings.blendSettings.a;
data.Dc = colorDst.rgb; data.Dc = colorDst.rgb;
data.Da = colorDst.a; data.Da = colorDst.a;
data.Sc = data.Sa * data.So * data.Sc; 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"( const char* cShaderSrc_Linear_Blend = R"(
struct VertexInput { @location(0) position: vec2f }; struct VertexInput { @location(0) position: vec2f };
struct VertexOutput { @builtin(position) position: vec4f, @location(0) vGradCoord : vec4f, @location(1) vScrCoord: 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 }; struct GradSettings { settings: vec4f, focal: vec4f };
@group(0) @binding(0) var<uniform> uViewMat : mat4x4f; @group(0) @binding(0) var<uniform> uViewMat : mat4x4f;
@group(1) @binding(0) var<uniform> uModelMat : mat4x4f; @group(1) @binding(0) var<uniform> uPaintSettings : PaintSettings;
@group(1) @binding(1) var<uniform> uBlendSettings : vec4f;
@group(2) @binding(0) var uSamplerGrad : sampler; @group(2) @binding(0) var uSamplerGrad : sampler;
@group(2) @binding(1) var uTextureGrad : texture_2d<f32>; @group(2) @binding(1) var uTextureGrad : texture_2d<f32>;
@group(2) @binding(2) var<uniform> uSettingGrad : vec4f; @group(2) @binding(2) var<uniform> uSettingGrad : vec4f;
@ -303,7 +305,7 @@ struct GradSettings { settings: vec4f, focal: vec4f };
@vertex @vertex
fn vs_main(in: VertexInput) -> VertexOutput { fn vs_main(in: VertexInput) -> VertexOutput {
var out: 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.position = pos;
out.vGradCoord = uTransformGrad * vec4f(in.position.xy, 0.0, 1.0); 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); 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; var data: FragData;
data.Sc = colorSrc.rgb; data.Sc = colorSrc.rgb;
data.Sa = colorSrc.a; data.Sa = colorSrc.a;
data.So = uBlendSettings.a; data.So = uPaintSettings.blendSettings.a;
data.Dc = colorDst.rgb; data.Dc = colorDst.rgb;
data.Da = colorDst.a; data.Da = colorDst.a;
data.Sc = mix(data.Dc, data.Sc, data.Sa * data.So); 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"( const char* cShaderSrc_Radial_Blend = R"(
struct VertexInput { @location(0) position: vec2f }; struct VertexInput { @location(0) position: vec2f };
struct VertexOutput { @builtin(position) position: vec4f, @location(0) vGradCoord : vec4f, @location(1) vScrCoord: 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 }; struct GradSettings { settings: vec4f, focal: vec4f };
@group(0) @binding(0) var<uniform> uViewMat : mat4x4f; @group(0) @binding(0) var<uniform> uViewMat : mat4x4f;
@group(1) @binding(0) var<uniform> uModelMat : mat4x4f; @group(1) @binding(0) var<uniform> uPaintSettings : PaintSettings;
@group(1) @binding(1) var<uniform> uBlendSettings : vec4f;
@group(2) @binding(0) var uSamplerGrad : sampler; @group(2) @binding(0) var uSamplerGrad : sampler;
@group(2) @binding(1) var uTextureGrad : texture_2d<f32>; @group(2) @binding(1) var uTextureGrad : texture_2d<f32>;
@group(2) @binding(2) var<uniform> uSettingGrad : GradSettings; @group(2) @binding(2) var<uniform> uSettingGrad : GradSettings;
@ -353,7 +355,7 @@ struct GradSettings { settings: vec4f, focal: vec4f };
@vertex @vertex
fn vs_main(in: VertexInput) -> VertexOutput { fn vs_main(in: VertexInput) -> VertexOutput {
var out: 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.position = pos;
out.vGradCoord = uTransformGrad * vec4f(in.position.xy, 0.0, 1.0); 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); 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; var data: FragData;
data.Sc = colorSrc.rgb; data.Sc = colorSrc.rgb;
data.Sa = colorSrc.a; data.Sa = colorSrc.a;
data.So = uBlendSettings.a; data.So = uPaintSettings.blendSettings.a;
data.Dc = colorDst.rgb; data.Dc = colorDst.rgb;
data.Da = colorDst.a; data.Da = colorDst.a;
data.Sc = mix(data.Dc, data.Sc, data.Sa * data.So); 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"( const char* cShaderSrc_Image_Blend = R"(
struct VertexInput { @location(0) position: vec2f, @location(1) texCoord: vec2f }; 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 VertexOutput { @builtin(position) position: vec4f, @location(0) vTexCoord : vec2f, @location(1) vScrCoord: vec2f };
struct PaintSettings { modelMat : mat4x4f, blendSettings: vec4f };
@group(0) @binding(0) var<uniform> uViewMat : mat4x4f; @group(0) @binding(0) var<uniform> uViewMat : mat4x4f;
@group(1) @binding(0) var<uniform> uModelMat : mat4x4f; @group(1) @binding(0) var<uniform> uPaintSettings : PaintSettings;
@group(1) @binding(1) var<uniform> uBlendSettings : vec4f; @group(2) @binding(0) var uSamplerSrc : sampler;
@group(2) @binding(0) var uSamplerSrc : sampler;
@group(2) @binding(1) var uTextureSrc : texture_2d<f32>; @group(2) @binding(1) var uTextureSrc : texture_2d<f32>;
@group(3) @binding(0) var uSamplerDst : sampler; @group(3) @binding(0) var uSamplerDst : sampler;
@group(3) @binding(1) var uTextureDst : texture_2d<f32>; @group(3) @binding(1) var uTextureDst : texture_2d<f32>;
@ -402,7 +404,7 @@ struct VertexOutput { @builtin(position) position: vec4f, @location(0) vTexCoord
@vertex @vertex
fn vs_main(in: VertexInput) -> VertexOutput { fn vs_main(in: VertexInput) -> VertexOutput {
var out: 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.position = pos;
out.vTexCoord = in.texCoord; out.vTexCoord = in.texCoord;
out.vScrCoord = vec2f(0.5 + pos.x * 0.5, 0.5 - pos.y * 0.5); 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; var data: FragData;
data.Sc = colorSrc.rgb; data.Sc = colorSrc.rgb;
data.Sa = colorSrc.a; data.Sa = colorSrc.a;
data.So = uBlendSettings.a; data.So = uPaintSettings.blendSettings.a;
data.Dc = colorDst.rgb; data.Dc = colorDst.rgb;
data.Da = colorDst.a; data.Da = colorDst.a;
data.Sc = data.Sc * data.So; data.Sc = data.Sc * data.So;

View file

@ -55,6 +55,16 @@ struct WgShaderTypeVec4f
void update(const RenderRegion& r); 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 // sampler, texture, vec4f
#define WG_TEXTURE_GRADIENT_SIZE 512 #define WG_TEXTURE_GRADIENT_SIZE 512
struct WgShaderTypeGradient struct WgShaderTypeGradient