mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-07 21:23:32 +00:00
wg_engine: uniform stage buffers (transform and solid color)
https://github.com/thorvg/thorvg/issues/3505
This commit is contained in:
parent
0fa5d41c8d
commit
5b46637a3d
9 changed files with 171 additions and 110 deletions
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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{};
|
||||
|
|
|
@ -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 };
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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,11 +392,11 @@ fn postProcess(d: FragData, R: vec4f) -> vec4f { return R; };
|
|||
const char* cShaderSrc_Image_Blend = R"(
|
||||
struct VertexInput { @location(0) position: vec2f, @location(1) texCoord: vec2f };
|
||||
struct VertexOutput { @builtin(position) position: vec4f, @location(0) vTexCoord : vec2f, @location(1) vScrCoord: vec2f };
|
||||
struct PaintSettings { modelMat : mat4x4f, blendSettings: vec4f };
|
||||
|
||||
@group(0) @binding(0) var<uniform> uViewMat : mat4x4f;
|
||||
@group(1) @binding(0) var<uniform> uModelMat : mat4x4f;
|
||||
@group(1) @binding(1) var<uniform> uBlendSettings : vec4f;
|
||||
@group(2) @binding(0) var uSamplerSrc : sampler;
|
||||
@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;
|
||||
@group(3) @binding(1) var uTextureDst : texture_2d<f32>;
|
||||
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue