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)
{
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);

View file

@ -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);

View file

@ -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);

View file

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

View file

@ -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 };

View file

@ -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);

View file

@ -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<uint8_t> vbuffer;
Array<uint8_t> 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<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_

View file

@ -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<uniform> uViewMat : mat4x4f;
@group(1) @binding(0) var<uniform> uModelMat : mat4x4f;
@group(1) @binding(0) var<uniform> 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<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;
@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<uniform> uViewMat : mat4x4f;
@group(1) @binding(0) var<uniform> uModelMat : mat4x4f;
@group(1) @binding(1) var<uniform> uBlendSettings : vec4f;
@group(1) @binding(0) var<uniform> uPaintSettings : PaintSettings;
@group(2) @binding(0) var<uniform> 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<uniform> uViewMat : mat4x4f;
@group(1) @binding(0) var<uniform> uModelMat : mat4x4f;
@group(1) @binding(1) var<uniform> uBlendSettings : vec4f;
@group(1) @binding(0) var<uniform> uPaintSettings : PaintSettings;
@group(2) @binding(0) var uSamplerGrad : sampler;
@group(2) @binding(1) var uTextureGrad : texture_2d<f32>;
@group(2) @binding(2) var<uniform> 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<uniform> uViewMat : mat4x4f;
@group(1) @binding(0) var<uniform> uModelMat : mat4x4f;
@group(1) @binding(1) var<uniform> uBlendSettings : vec4f;
@group(1) @binding(0) var<uniform> uPaintSettings : PaintSettings;
@group(2) @binding(0) var uSamplerGrad : sampler;
@group(2) @binding(1) var uTextureGrad : texture_2d<f32>;
@group(2) @binding(2) var<uniform> 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<uniform> uViewMat : mat4x4f;
@group(1) @binding(0) var<uniform> uModelMat : mat4x4f;
@group(1) @binding(1) var<uniform> uBlendSettings : vec4f;
@group(1) @binding(0) var<uniform> uPaintSettings : PaintSettings;
@group(2) @binding(0) var uSampler : sampler;
@group(2) @binding(1) var uTextureView : texture_2d<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.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<uniform> uViewMat : mat4x4f;
@group(1) @binding(0) var<uniform> uModelMat : mat4x4f;
@group(1) @binding(1) var<uniform> uBlendSettings : vec4f;
@group(1) @binding(0) var<uniform> uPaintSettings : PaintSettings;
@group(2) @binding(0) var<uniform> uSolidColor : vec4f;
@group(3) @binding(0) var uSamplerDst : sampler;
@group(3) @binding(1) var uTextureDst : texture_2d<f32>;
@ -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<uniform> uViewMat : mat4x4f;
@group(1) @binding(0) var<uniform> uModelMat : mat4x4f;
@group(1) @binding(1) var<uniform> uBlendSettings : vec4f;
@group(1) @binding(0) var<uniform> uPaintSettings : PaintSettings;
@group(2) @binding(0) var uSamplerGrad : sampler;
@group(2) @binding(1) var uTextureGrad : texture_2d<f32>;
@group(2) @binding(2) var<uniform> 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<uniform> uViewMat : mat4x4f;
@group(1) @binding(0) var<uniform> uModelMat : mat4x4f;
@group(1) @binding(1) var<uniform> uBlendSettings : vec4f;
@group(1) @binding(0) var<uniform> uPaintSettings : PaintSettings;
@group(2) @binding(0) var uSamplerGrad : sampler;
@group(2) @binding(1) var uTextureGrad : texture_2d<f32>;
@group(2) @binding(2) var<uniform> 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,10 +392,10 @@ 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<uniform> uViewMat : mat4x4f;
@group(1) @binding(0) var<uniform> uModelMat : mat4x4f;
@group(1) @binding(1) var<uniform> uBlendSettings : vec4f;
@group(1) @binding(0) var<uniform> uPaintSettings : PaintSettings;
@group(2) @binding(0) var uSamplerSrc : sampler;
@group(2) @binding(1) var uTextureSrc : texture_2d<f32>;
@group(3) @binding(0) var uSamplerDst : sampler;
@ -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;

View file

@ -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