wg_engine: separate pipelines ans bind group layouts (refactoring)

The main reason of refactoring is to separate bind group sets and pipelines, and change owning of pipelines to compositor
This commit is contained in:
Sergii Liebodkin 2024-11-26 11:07:20 +00:00
parent af7dbf2277
commit 77201546dd
12 changed files with 144 additions and 197 deletions

View file

@ -21,6 +21,7 @@
*/
#include "tvgWgBindGroups.h"
#include <cassert>
WGPUBindGroup WgBindGroupLayouts::createBindGroupTexSampled(WGPUSampler sampler, WGPUTextureView texView)
{
@ -147,11 +148,11 @@ void WgBindGroupLayouts::releaseBindGroupLayout(WGPUBindGroupLayout& bindGroupLa
}
void WgBindGroupLayouts::initialize(WgContext& context)
void WgBindGroupLayouts::initialize(WGPUDevice device)
{
// store device handle
device = context.device;
assert(device);
this->device = device;
// common bind group settings
const WGPUShaderStageFlags visibility_vert = WGPUShaderStage_Vertex | WGPUShaderStage_Fragment | WGPUShaderStage_Compute;
@ -162,111 +163,66 @@ void WgBindGroupLayouts::initialize(WgContext& context)
const WGPUStorageTextureBindingLayout storageTextureRO { .access = WGPUStorageTextureAccess_ReadOnly, .format = WGPUTextureFormat_RGBA8Unorm, .viewDimension = WGPUTextureViewDimension_2D };
const WGPUBufferBindingLayout bufferUniform { .type = WGPUBufferBindingType_Uniform };
{ // bind group layout tex sampled
const WGPUBindGroupLayoutEntry bindGroupLayoutEntries[] {
{ .binding = 0, .visibility = visibility_frag, .sampler = sampler },
{ .binding = 1, .visibility = visibility_frag, .texture = texture }
};
const WGPUBindGroupLayoutDescriptor bindGroupLayoutDesc { .entryCount = 2, .entries = bindGroupLayoutEntries };
layoutTexSampled = wgpuDeviceCreateBindGroupLayout(device, &bindGroupLayoutDesc);
assert(layoutTexSampled);
}
// bind group layout tex sampled with buffer uniforms
const WGPUBindGroupLayoutEntry entriesTexSampledBufferUniforms[] {
{ .binding = 0, .visibility = visibility_frag, .sampler = sampler },
{ .binding = 1, .visibility = visibility_frag, .texture = texture },
{ .binding = 2, .visibility = visibility_vert, .buffer = bufferUniform },
{ .binding = 3, .visibility = visibility_vert, .buffer = bufferUniform }
};
const WGPUBindGroupLayoutDescriptor layoutDescTexSambled { .entryCount = 2, .entries = entriesTexSampledBufferUniforms };
const WGPUBindGroupLayoutDescriptor layoutDescTexSampledBuff1Un { .entryCount = 3, .entries = entriesTexSampledBufferUniforms };
const WGPUBindGroupLayoutDescriptor layoutDescTexSampledBuff2Un { .entryCount = 4, .entries = entriesTexSampledBufferUniforms };
layoutTexSampled = wgpuDeviceCreateBindGroupLayout(device, &layoutDescTexSambled);
layoutTexSampledBuff1Un = wgpuDeviceCreateBindGroupLayout(device, &layoutDescTexSampledBuff1Un);
layoutTexSampledBuff2Un = wgpuDeviceCreateBindGroupLayout(device, &layoutDescTexSampledBuff2Un);
assert(layoutTexSampled);
assert(layoutTexSampledBuff1Un);
assert(layoutTexSampledBuff2Un);
{ // bind group layout tex sampled with buffer uniform
const WGPUBindGroupLayoutEntry bindGroupLayoutEntries[] {
{ .binding = 0, .visibility = visibility_frag, .sampler = sampler },
{ .binding = 1, .visibility = visibility_frag, .texture = texture },
{ .binding = 2, .visibility = visibility_vert, .buffer = bufferUniform }
};
const WGPUBindGroupLayoutDescriptor bindGroupLayoutDesc { .entryCount = 3, .entries = bindGroupLayoutEntries };
layoutTexSampledBuff1Un = wgpuDeviceCreateBindGroupLayout(device, &bindGroupLayoutDesc);
assert(layoutTexSampledBuff1Un);
}
// bind group layout tex storages WO
const WGPUBindGroupLayoutEntry entriesTexStoragesWO[] {
{ .binding = 0, .visibility = visibility_frag, .storageTexture = storageTextureWO }
};
const WGPUBindGroupLayoutDescriptor layoutDescTexStrorage1WO { .entryCount = 1, .entries = entriesTexStoragesWO };
layoutTexStrorage1WO = wgpuDeviceCreateBindGroupLayout(device, &layoutDescTexStrorage1WO);
assert(layoutTexStrorage1WO);
{ // bind group layout tex sampled with buffer uniforms
const WGPUBindGroupLayoutEntry bindGroupLayoutEntries[] {
{ .binding = 0, .visibility = visibility_frag, .sampler = sampler },
{ .binding = 1, .visibility = visibility_frag, .texture = texture },
{ .binding = 2, .visibility = visibility_vert, .buffer = bufferUniform },
{ .binding = 3, .visibility = visibility_vert, .buffer = bufferUniform }
};
const WGPUBindGroupLayoutDescriptor bindGroupLayoutDesc { .entryCount = 4, .entries = bindGroupLayoutEntries };
layoutTexSampledBuff2Un = wgpuDeviceCreateBindGroupLayout(device, &bindGroupLayoutDesc);
assert(layoutTexSampledBuff1Un);
}
// bind group layout tex storages RO
const WGPUBindGroupLayoutEntry entriesTexStoragesRO[] {
{ .binding = 0, .visibility = visibility_frag, .storageTexture = storageTextureRO },
{ .binding = 1, .visibility = visibility_frag, .storageTexture = storageTextureRO },
{ .binding = 2, .visibility = visibility_frag, .storageTexture = storageTextureRO }
};
const WGPUBindGroupLayoutDescriptor layoutDescTexStorages1RO { .entryCount = 1, .entries = entriesTexStoragesRO };
const WGPUBindGroupLayoutDescriptor layoutDescTexStorages2RO { .entryCount = 2, .entries = entriesTexStoragesRO };
const WGPUBindGroupLayoutDescriptor layoutDescTexStorages3RO { .entryCount = 3, .entries = entriesTexStoragesRO };
layoutTexStrorage1RO = wgpuDeviceCreateBindGroupLayout(device, &layoutDescTexStorages1RO);
layoutTexStrorage2RO = wgpuDeviceCreateBindGroupLayout(device, &layoutDescTexStorages2RO);
layoutTexStrorage3RO = wgpuDeviceCreateBindGroupLayout(device, &layoutDescTexStorages3RO);
assert(layoutTexStrorage1RO);
assert(layoutTexStrorage2RO);
assert(layoutTexStrorage3RO);
{ // bind group layout tex storage 1 WO
const WGPUBindGroupLayoutEntry bindGroupLayoutEntries[] {
{ .binding = 0, .visibility = visibility_frag, .storageTexture = storageTextureWO }
};
const WGPUBindGroupLayoutDescriptor bindGroupLayoutDesc { .entryCount = 1, .entries = bindGroupLayoutEntries };
layoutTexStrorage1WO = wgpuDeviceCreateBindGroupLayout(device, &bindGroupLayoutDesc);
assert(layoutTexStrorage1WO);
}
{ // bind group layout tex storage 1 RO
const WGPUBindGroupLayoutEntry bindGroupLayoutEntries[] {
{ .binding = 0, .visibility = visibility_frag, .storageTexture = storageTextureRO }
};
const WGPUBindGroupLayoutDescriptor bindGroupLayoutDesc { .entryCount = 1, .entries = bindGroupLayoutEntries };
layoutTexStrorage1RO = wgpuDeviceCreateBindGroupLayout(device, &bindGroupLayoutDesc);
assert(layoutTexStrorage1RO);
}
{ // bind group layout tex storage 2 RO
const WGPUBindGroupLayoutEntry bindGroupLayoutEntries[] {
{ .binding = 0, .visibility = visibility_frag, .storageTexture = storageTextureRO },
{ .binding = 1, .visibility = visibility_frag, .storageTexture = storageTextureRO }
};
const WGPUBindGroupLayoutDescriptor bindGroupLayoutDesc { .entryCount = 2, .entries = bindGroupLayoutEntries };
layoutTexStrorage2RO = wgpuDeviceCreateBindGroupLayout(device, &bindGroupLayoutDesc);
assert(layoutTexStrorage2RO);
}
{ // bind group layout tex storage 3 RO
const WGPUBindGroupLayoutEntry bindGroupLayoutEntries[] {
{ .binding = 0, .visibility = visibility_frag, .storageTexture = storageTextureRO },
{ .binding = 1, .visibility = visibility_frag, .storageTexture = storageTextureRO },
{ .binding = 2, .visibility = visibility_frag, .storageTexture = storageTextureRO }
};
const WGPUBindGroupLayoutDescriptor bindGroupLayoutDesc { .entryCount = 3, .entries = bindGroupLayoutEntries };
layoutTexStrorage3RO = wgpuDeviceCreateBindGroupLayout(device, &bindGroupLayoutDesc);
assert(layoutTexStrorage3RO);
}
{ // bind group layout buffer 1 uniform
const WGPUBindGroupLayoutEntry bindGroupLayoutEntries[] {
{ .binding = 0, .visibility = visibility_vert, .buffer = bufferUniform }
};
const WGPUBindGroupLayoutDescriptor bindGroupLayoutDesc { .entryCount = 1, .entries = bindGroupLayoutEntries };
layoutBuffer1Un = wgpuDeviceCreateBindGroupLayout(device, &bindGroupLayoutDesc);
assert(layoutBuffer1Un);
}
{ // bind group layout buffer 2 uniform
const WGPUBindGroupLayoutEntry bindGroupLayoutEntries[] {
{ .binding = 0, .visibility = visibility_vert, .buffer = bufferUniform },
{ .binding = 1, .visibility = visibility_vert, .buffer = bufferUniform }
};
const WGPUBindGroupLayoutDescriptor bindGroupLayoutDesc { .entryCount = 2, .entries = bindGroupLayoutEntries };
layoutBuffer2Un = wgpuDeviceCreateBindGroupLayout(device, &bindGroupLayoutDesc);
assert(layoutBuffer2Un);
}
{ // bind group layout buffer 3 uniform
const WGPUBindGroupLayoutEntry bindGroupLayoutEntries[] {
{ .binding = 0, .visibility = visibility_vert, .buffer = bufferUniform },
{ .binding = 1, .visibility = visibility_vert, .buffer = bufferUniform },
{ .binding = 2, .visibility = visibility_vert, .buffer = bufferUniform }
};
const WGPUBindGroupLayoutDescriptor bindGroupLayoutDesc { .entryCount = 3, .entries = bindGroupLayoutEntries };
layoutBuffer3Un = wgpuDeviceCreateBindGroupLayout(device, &bindGroupLayoutDesc);
assert(layoutBuffer3Un);
}
// bind group layout buffer uniforms
const WGPUBindGroupLayoutEntry entriesBufferUniform[] {
{ .binding = 0, .visibility = visibility_vert, .buffer = bufferUniform },
{ .binding = 1, .visibility = visibility_vert, .buffer = bufferUniform },
{ .binding = 2, .visibility = visibility_vert, .buffer = bufferUniform }
};
const WGPUBindGroupLayoutDescriptor layoutDescBufferUniforms1Un { .entryCount = 1, .entries = entriesBufferUniform };
const WGPUBindGroupLayoutDescriptor layoutDescBufferUniforms2Un { .entryCount = 2, .entries = entriesBufferUniform };
const WGPUBindGroupLayoutDescriptor layoutDescBufferUniforms3Un { .entryCount = 3, .entries = entriesBufferUniform };
layoutBuffer1Un = wgpuDeviceCreateBindGroupLayout(device, &layoutDescBufferUniforms1Un);
layoutBuffer2Un = wgpuDeviceCreateBindGroupLayout(device, &layoutDescBufferUniforms2Un);
layoutBuffer3Un = wgpuDeviceCreateBindGroupLayout(device, &layoutDescBufferUniforms3Un);
assert(layoutBuffer1Un);
assert(layoutBuffer2Un);
assert(layoutBuffer3Un);
}
void WgBindGroupLayouts::release(WgContext& context)
void WgBindGroupLayouts::release()
{
releaseBindGroupLayout(layoutBuffer3Un);
releaseBindGroupLayout(layoutBuffer2Un);

View file

@ -23,7 +23,7 @@
#ifndef _TVG_WG_BIND_GROUPS_H_
#define _TVG_WG_BIND_GROUPS_H_
#include "tvgWgCommon.h"
#include <webgpu/webgpu.h>
class WgBindGroupLayouts {
private:
@ -53,8 +53,8 @@ public:
void releaseBindGroup(WGPUBindGroup& bindGroup);
void releaseBindGroupLayout(WGPUBindGroupLayout& bindGroupLayout);
public:
void initialize(WgContext& context);
void release(WgContext& context);
void initialize(WGPUDevice device);
void release();
};
#endif // _TVG_WG_BIND_GROUPS_H_

View file

@ -23,6 +23,7 @@
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
#include <cassert>
#include "tvgWgCommon.h"
#include "tvgArray.h"
@ -50,11 +51,15 @@ void WgContext::initialize(WGPUInstance instance, WGPUDevice device)
assert(samplerLinearRepeat);
assert(samplerLinearMirror);
assert(samplerLinearClamp);
// initialize bind group layouts
layouts.initialize(device);
}
void WgContext::release()
{
layouts.release();
releaseSampler(samplerLinearClamp);
releaseSampler(samplerLinearMirror);
releaseSampler(samplerLinearRepeat);

View file

@ -23,14 +23,11 @@
#ifndef _TVG_WG_COMMON_H_
#define _TVG_WG_COMMON_H_
#include <cassert>
#include <webgpu/webgpu.h>
#include "tvgWgBindGroups.h"
#define WG_VERTEX_BUFFER_MIN_SIZE 2048
#define WG_INDEX_BUFFER_MIN_SIZE 2048
class WgPipelines;
struct WgContext {
// external webgpu handles
WGPUInstance instance{};
@ -39,14 +36,14 @@ struct WgContext {
// common webgpu handles
WGPUQueue queue{};
WGPUTextureFormat preferredFormat{};
// external handles (do not release)
WgPipelines* pipelines{};
// shared webgpu assets
WGPUBuffer bufferIndexFan{};
WGPUSampler samplerNearestRepeat{};
WGPUSampler samplerLinearRepeat{};
WGPUSampler samplerLinearMirror{};
WGPUSampler samplerLinearClamp{};
// bind groups layouts
WgBindGroupLayouts layouts;
void initialize(WGPUInstance instance, WGPUDevice device);
void release();

View file

@ -26,7 +26,7 @@
void WgCompositor::initialize(WgContext& context, uint32_t width, uint32_t height)
{
// pipelines (external handle, do not release)
pipelines = context.pipelines;
pipelines.initialize(context);
// store render target dimensions
this->width = width;
this->height = height;
@ -38,12 +38,12 @@ void WgCompositor::initialize(WgContext& context, uint32_t width, uint32_t heigh
// allocate global view matrix handles
WgShaderTypeMat4x4f viewMat(width, height);
context.allocateBufferUniform(bufferViewMat, &viewMat, sizeof(viewMat));
bindGroupViewMat = pipelines->layouts.createBindGroupBuffer1Un(bufferViewMat);
bindGroupViewMat = context.layouts.createBindGroupBuffer1Un(bufferViewMat);
// initialize opacity pool
for (uint32_t i = 0; i < 256; i++) {
float opacity = i / 255.0f;
context.allocateBufferUniform(bufferOpacities[i], &opacity, sizeof(float));
bindGroupOpacities[i] = pipelines->layouts.createBindGroupBuffer1Un(bufferOpacities[i]);
bindGroupOpacities[i] = context.layouts.createBindGroupBuffer1Un(bufferOpacities[i]);
}
// initialize intermediate render storages
storageDstCopy.initialize(context, width, height);
@ -60,11 +60,11 @@ void WgCompositor::release(WgContext& context)
storageDstCopy.release(context);
// release opacity pool
for (uint32_t i = 0; i < 256; i++) {
context.pipelines->layouts.releaseBindGroup(bindGroupOpacities[i]);
context.layouts.releaseBindGroup(bindGroupOpacities[i]);
context.releaseBuffer(bufferOpacities[i]);
}
// release global view matrix handles
context.pipelines->layouts.releaseBindGroup(bindGroupViewMat);
context.layouts.releaseBindGroup(bindGroupViewMat);
context.releaseBuffer(bufferViewMat);
// release global stencil buffer handles
context.releaseTextureView(texViewDepthStencilMS);
@ -73,7 +73,8 @@ void WgCompositor::release(WgContext& context)
context.releaseTexture(texDepthStencil);
height = 0;
width = 0;
pipelines = nullptr;
// release pipelines
pipelines.release(context);
}
@ -203,7 +204,7 @@ void WgCompositor::composeScene(WgContext& context, WgRenderStorage* src, WgRend
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, src->bindGroupTexure, 0, nullptr);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, mask->bindGroupTexure, 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->scene_compose[(uint32_t)cmp->method]);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.scene_compose[(uint32_t)cmp->method]);
meshData.drawImage(context, renderPassEncoder);
}
@ -221,7 +222,7 @@ void WgCompositor::blit(WgContext& context, WGPUCommandEncoder encoder, WgRender
const WGPURenderPassDescriptor renderPassDesc{ .colorAttachmentCount = 1, .colorAttachments = &colorAttachment, .depthStencilAttachment = &depthStencilAttachment };
WGPURenderPassEncoder renderPass = wgpuCommandEncoderBeginRenderPass(encoder, &renderPassDesc);
wgpuRenderPassEncoderSetBindGroup(renderPass, 0, src->bindGroupTexure, 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPass, pipelines->blit);
wgpuRenderPassEncoderSetPipeline(renderPass, pipelines.blit);
meshData.drawImage(context, renderPass);
wgpuRenderPassEncoderEnd(renderPass);
wgpuRenderPassEncoderRelease(renderPass);
@ -238,7 +239,7 @@ void WgCompositor::drawShape(WgContext& context, WgRenderDataShape* renderData)
if ((renderData->viewport.w <= 0) || (renderData->viewport.h <= 0)) return;
wgpuRenderPassEncoderSetScissorRect(renderPassEncoder, renderData->viewport.x, renderData->viewport.y, renderData->viewport.w, renderData->viewport.h);
// setup stencil rules
WGPURenderPipeline stencilPipeline = (renderData->fillRule == FillRule::Winding) ? pipelines->winding : pipelines->evenodd;
WGPURenderPipeline stencilPipeline = (renderData->fillRule == FillRule::Winding) ? pipelines.winding : pipelines.evenodd;
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr);
@ -253,13 +254,13 @@ void WgCompositor::drawShape(WgContext& context, WgRenderDataShape* renderData)
WgRenderSettings& settings = renderData->renderSettingsShape;
if (settings.fillType == WgRenderSettingsType::Solid) {
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, settings.bindGroupSolid, 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->solid);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.solid);
} else if (settings.fillType == WgRenderSettingsType::Linear) {
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, settings.bindGroupGradient, 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->linear);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.linear);
} else if (settings.fillType == WgRenderSettingsType::Radial) {
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, settings.bindGroupGradient, 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->radial);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.radial);
}
// draw to color (second pass)
renderData->meshDataBBox.drawFan(context, renderPassEncoder);
@ -285,7 +286,7 @@ void WgCompositor::blendShape(WgContext& context, WgRenderDataShape* renderData,
// render shape with blend settings
wgpuRenderPassEncoderSetScissorRect(renderPassEncoder, renderData->viewport.x, renderData->viewport.y, renderData->viewport.w, renderData->viewport.h);
// setup stencil rules
WGPURenderPipeline stencilPipeline = (renderData->fillRule == FillRule::Winding) ? pipelines->winding : pipelines->evenodd;
WGPURenderPipeline stencilPipeline = (renderData->fillRule == FillRule::Winding) ? pipelines.winding : pipelines.evenodd;
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr);
@ -302,13 +303,13 @@ void WgCompositor::blendShape(WgContext& context, WgRenderDataShape* renderData,
WgRenderSettings& settings = renderData->renderSettingsShape;
if (settings.fillType == WgRenderSettingsType::Solid) {
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, settings.bindGroupSolid, 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->solid_blend[blendMethodInd]);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.solid_blend[blendMethodInd]);
} else if (settings.fillType == WgRenderSettingsType::Linear) {
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, settings.bindGroupGradient, 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->linear_blend[blendMethodInd]);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.linear_blend[blendMethodInd]);
} else if (settings.fillType == WgRenderSettingsType::Radial) {
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, settings.bindGroupGradient, 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->radial_blend[blendMethodInd]);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.radial_blend[blendMethodInd]);
}
// draw to color (second pass)
renderData->meshDataBBox.drawFan(context, renderPassEncoder);
@ -325,7 +326,7 @@ void WgCompositor::clipShape(WgContext& context, WgRenderDataShape* renderData)
if ((renderData->viewport.w <= 0) || (renderData->viewport.h <= 0)) return;
wgpuRenderPassEncoderSetScissorRect(renderPassEncoder, renderData->viewport.x, renderData->viewport.y, renderData->viewport.w, renderData->viewport.h);
// setup stencil rules
WGPURenderPipeline stencilPipeline = (renderData->fillRule == FillRule::Winding) ? pipelines->winding : pipelines->evenodd;
WGPURenderPipeline stencilPipeline = (renderData->fillRule == FillRule::Winding) ? pipelines.winding : pipelines.evenodd;
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr);
@ -336,7 +337,7 @@ void WgCompositor::clipShape(WgContext& context, WgRenderDataShape* renderData)
// merge depth and stencil buffer
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, bindGroupOpacities[128], 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->merge_depth_stencil);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.merge_depth_stencil);
renderData->meshDataBBox.drawFan(context, renderPassEncoder);
// setup fill rules
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
@ -345,13 +346,13 @@ void WgCompositor::clipShape(WgContext& context, WgRenderDataShape* renderData)
WgRenderSettings& settings = renderData->renderSettingsShape;
if (settings.fillType == WgRenderSettingsType::Solid) {
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, settings.bindGroupSolid, 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->solid);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.solid);
} else if (settings.fillType == WgRenderSettingsType::Linear) {
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, settings.bindGroupGradient, 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->linear);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.linear);
} else if (settings.fillType == WgRenderSettingsType::Radial) {
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, settings.bindGroupGradient, 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->radial);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.radial);
}
// draw to color (second pass)
renderData->meshDataBBox.drawFan(context, renderPassEncoder);
@ -373,7 +374,7 @@ void WgCompositor::drawStrokes(WgContext& context, WgRenderDataShape* renderData
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 255);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->direct);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.direct);
// draw to stencil (first pass)
renderData->meshGroupStrokes.meshes[i]->draw(context, renderPassEncoder);
// setup fill rules
@ -383,13 +384,13 @@ void WgCompositor::drawStrokes(WgContext& context, WgRenderDataShape* renderData
WgRenderSettings& settings = renderData->renderSettingsStroke;
if (settings.fillType == WgRenderSettingsType::Solid) {
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, settings.bindGroupSolid, 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->solid);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.solid);
} else if (settings.fillType == WgRenderSettingsType::Linear) {
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, settings.bindGroupGradient, 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->linear);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.linear);
} else if (settings.fillType == WgRenderSettingsType::Radial) {
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, settings.bindGroupGradient, 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->radial);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.radial);
}
// draw to color (second pass)
renderData->meshGroupStrokesBBox.meshes[i]->drawFan(context, renderPassEncoder);
@ -420,7 +421,7 @@ void WgCompositor::blendStrokes(WgContext& context, WgRenderDataShape* renderDat
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 255);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->direct);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.direct);
// draw to stencil (first pass)
renderData->meshGroupStrokes.meshes[i]->draw(context, renderPassEncoder);
// setup fill rules
@ -432,13 +433,13 @@ void WgCompositor::blendStrokes(WgContext& context, WgRenderDataShape* renderDat
WgRenderSettings& settings = renderData->renderSettingsStroke;
if (settings.fillType == WgRenderSettingsType::Solid) {
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, settings.bindGroupSolid, 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->solid_blend[blendMethodInd]);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.solid_blend[blendMethodInd]);
} else if (settings.fillType == WgRenderSettingsType::Linear) {
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, settings.bindGroupGradient, 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->linear_blend[blendMethodInd]);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.linear_blend[blendMethodInd]);
} else if (settings.fillType == WgRenderSettingsType::Radial) {
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, settings.bindGroupGradient, 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->radial_blend[blendMethodInd]);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.radial_blend[blendMethodInd]);
}
// draw to color (second pass)
renderData->meshGroupStrokesBBox.meshes[i]->drawFan(context, renderPassEncoder);
@ -461,13 +462,13 @@ void WgCompositor::clipStrokes(WgContext& context, WgRenderDataShape* renderData
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 255);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->direct);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.direct);
// draw to stencil (first pass)
renderData->meshGroupStrokes.meshes[i]->draw(context, renderPassEncoder);
// merge depth and stencil buffer
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, bindGroupOpacities[128], 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->merge_depth_stencil);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.merge_depth_stencil);
renderData->meshDataBBox.drawFan(context, renderPassEncoder);
// setup fill rules
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
@ -476,13 +477,13 @@ void WgCompositor::clipStrokes(WgContext& context, WgRenderDataShape* renderData
WgRenderSettings& settings = renderData->renderSettingsStroke;
if (settings.fillType == WgRenderSettingsType::Solid) {
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, settings.bindGroupSolid, 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->solid);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.solid);
} else if (settings.fillType == WgRenderSettingsType::Linear) {
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, settings.bindGroupGradient, 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->linear);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.linear);
} else if (settings.fillType == WgRenderSettingsType::Radial) {
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, settings.bindGroupGradient, 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->radial);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.radial);
}
// draw to color (second pass)
renderData->meshGroupStrokesBBox.meshes[i]->drawFan(context, renderPassEncoder);
@ -500,14 +501,14 @@ void WgCompositor::drawImage(WgContext& context, WgRenderDataPicture* renderData
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 255);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->direct);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.direct);
renderData->meshData.drawImage(context, renderPassEncoder);
// draw image
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, renderData->bindGroupPicture, 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->image);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.image);
renderData->meshData.drawImage(context, renderPassEncoder);
}
@ -530,7 +531,7 @@ void WgCompositor::blendImage(WgContext& context, WgRenderDataPicture* renderDat
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 255);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->direct);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.direct);
renderData->meshData.drawImage(context, renderPassEncoder);
// blend image
uint32_t blendMethodInd = (uint32_t)blendMethod;
@ -539,7 +540,7 @@ void WgCompositor::blendImage(WgContext& context, WgRenderDataPicture* renderDat
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, renderData->bindGroupPicture, 0, nullptr);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 3, storageDstCopy.bindGroupTexure, 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->image_blend[blendMethodInd]);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.image_blend[blendMethodInd]);
renderData->meshData.drawImage(context, renderPassEncoder);
};
@ -554,19 +555,19 @@ void WgCompositor::clipImage(WgContext& context, WgRenderDataPicture* renderData
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 255);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->direct);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.direct);
renderData->meshData.drawImage(context, renderPassEncoder);
// merge depth and stencil buffer
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, bindGroupOpacities[128], 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->merge_depth_stencil);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.merge_depth_stencil);
renderData->meshData.drawImage(context, renderPassEncoder);
// draw image
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, renderData->bindGroupPicture, 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->image);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.image);
renderData->meshData.drawImage(context, renderPassEncoder);
}
@ -582,7 +583,7 @@ void WgCompositor::drawScene(WgContext& context, WgRenderStorage* scene, WgCompo
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, scene->bindGroupTexure, 0, nullptr);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, bindGroupOpacities[compose->opacity], 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->scene);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.scene);
meshData.drawImage(context, renderPassEncoder);
}
@ -608,7 +609,7 @@ void WgCompositor::blendScene(WgContext& context, WgRenderStorage* scene, WgComp
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, scene->bindGroupTexure, 0, nullptr);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, storageDstCopy.bindGroupTexure, 0, nullptr);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, bindGroupOpacities[compose->opacity], 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->scene_blend[blendMethodInd]);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.scene_blend[blendMethodInd]);
meshData.drawImage(context, renderPassEncoder);
}
@ -625,7 +626,7 @@ void WgCompositor::renderClipPath(WgContext& context, WgRenderDataPaint* paint)
// set transformations
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr);
// markup stencil
WGPURenderPipeline stencilPipeline = (renderData0->fillRule == FillRule::Winding) ? pipelines->winding : pipelines->evenodd;
WGPURenderPipeline stencilPipeline = (renderData0->fillRule == FillRule::Winding) ? pipelines.winding : pipelines.evenodd;
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData0->bindGroupPaint, 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, stencilPipeline);
@ -635,14 +636,14 @@ void WgCompositor::renderClipPath(WgContext& context, WgRenderDataPaint* paint)
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData0->bindGroupPaint, 0, nullptr);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, bindGroupOpacities[128], 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->copy_stencil_to_depth);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.copy_stencil_to_depth);
renderData0->meshDataBBox.drawFan(context, renderPassEncoder);
// merge clip pathes with AND logic
for (uint32_t clipIndex = 1; clipIndex < paint->clips.count; clipIndex++) {
// get render data
WgRenderDataShape* renderData = (WgRenderDataShape*)paint->clips[clipIndex];
// markup stencil
WGPURenderPipeline stencilPipeline = (renderData->fillRule == FillRule::Winding) ? pipelines->winding : pipelines->evenodd;
WGPURenderPipeline stencilPipeline = (renderData->fillRule == FillRule::Winding) ? pipelines.winding : pipelines.evenodd;
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, stencilPipeline);
@ -652,31 +653,31 @@ void WgCompositor::renderClipPath(WgContext& context, WgRenderDataPaint* paint)
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, bindGroupOpacities[190], 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->copy_stencil_to_depth_interm);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.copy_stencil_to_depth_interm);
renderData->meshDataBBox.drawFan(context, renderPassEncoder);
// copy depth to stencil
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 1);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, bindGroupOpacities[190], 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->copy_depth_to_stencil);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.copy_depth_to_stencil);
renderData->meshDataBBox.drawFan(context, renderPassEncoder);
// clear depth current (keep stencil)
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, bindGroupOpacities[255], 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->clear_depth);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.clear_depth);
renderData->meshDataBBox.drawFan(context, renderPassEncoder);
// clear depth original (keep stencil)
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData0->bindGroupPaint, 0, nullptr);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, bindGroupOpacities[255], 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->clear_depth);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.clear_depth);
renderData0->meshDataBBox.drawFan(context, renderPassEncoder);
// copy stencil to depth (clear stencil)
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, bindGroupOpacities[128], 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->copy_stencil_to_depth);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.copy_stencil_to_depth);
renderData->meshDataBBox.drawFan(context, renderPassEncoder);
}
}
@ -697,7 +698,7 @@ void WgCompositor::clearClipPath(WgContext& context, WgRenderDataPaint* paint)
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr);
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, bindGroupOpacities[255], 0, nullptr);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines->clear_depth);
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.clear_depth);
renderData->meshDataBBox.drawFan(context, renderPassEncoder);
}
}

View file

@ -35,8 +35,8 @@ struct WgCompose: RenderCompositor
class WgCompositor
{
private:
// pipelines (external handle, do not release)
WgPipelines* pipelines{};
// pipelines
WgPipelines pipelines{};
// global stencil/depth buffer handles
WGPUTexture texDepthStencil{};
WGPUTextureView texViewDepthStencil{};

View file

@ -23,6 +23,7 @@
#include "tvgWgPipelines.h"
#include "tvgWgShaderSrc.h"
#include <cstring>
#include <cassert>
WGPUShaderModule WgPipelines::createShaderModule(WGPUDevice device, const char* label, const char* code)
{
@ -130,13 +131,6 @@ void WgPipelines::releaseShaderModule(WGPUShaderModule& shaderModule)
void WgPipelines::initialize(WgContext& context)
{
// share pipelines to context
assert(!context.pipelines);
context.pipelines = this;
// initialize bind group layouts
layouts.initialize(context);
// common pipeline settings
const WGPUVertexAttribute vertexAttributePos { .format = WGPUVertexFormat_Float32x2, .offset = 0, .shaderLocation = 0 };
const WGPUVertexAttribute vertexAttributeTex { .format = WGPUVertexFormat_Float32x2, .offset = 0, .shaderLocation = 1 };
@ -160,6 +154,7 @@ void WgPipelines::initialize(WgContext& context)
.alpha = { .operation = WGPUBlendOperation_Add, .srcFactor = WGPUBlendFactor_One, .dstFactor = WGPUBlendFactor_OneMinusSrcAlpha }
};
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 };
@ -521,5 +516,4 @@ void WgPipelines::releaseGraphicHandles(WgContext& context)
void WgPipelines::release(WgContext& context)
{
releaseGraphicHandles(context);
layouts.release(context);
}

View file

@ -23,7 +23,7 @@
#ifndef _TVG_WG_PIPELINES_H_
#define _TVG_WG_PIPELINES_H_
#include "tvgWgBindGroups.h"
#include "tvgWgCommon.h"
class WgPipelines {
private:
@ -91,9 +91,6 @@ public:
WGPURenderPipeline scene_compose[11]{};
// pipeline blit
WGPURenderPipeline blit{};
public:
// layouts
WgBindGroupLayouts layouts;
private:
void releaseGraphicHandles(WgContext& context);
private:

View file

@ -261,8 +261,8 @@ void WgRenderSettings::update(WgContext& context, const Fill* fill, const Render
if (fill->spread() == FillSpread::Reflect) sampler = context.samplerLinearMirror;
if (fill->spread() == FillSpread::Repeat) sampler = context.samplerLinearRepeat;
// update bind group
context.pipelines->layouts.releaseBindGroup(bindGroupGradient);
bindGroupGradient = context.pipelines->layouts.createBindGroupTexSampledBuff2Un(
context.layouts.releaseBindGroup(bindGroupGradient);
bindGroupGradient = context.layouts.createBindGroupTexSampledBuff2Un(
sampler, texViewGradient, bufferGroupGradient, bufferGroupTransfromGrad);
}
skip = false;
@ -270,8 +270,8 @@ void WgRenderSettings::update(WgContext& context, const Fill* fill, const Render
rasterType = WgRenderRasterType::Solid;
WgShaderTypeSolidColor solidColor(c);
if (context.allocateBufferUniform(bufferGroupSolid, &solidColor, sizeof(solidColor))) {
context.pipelines->layouts.releaseBindGroup(bindGroupSolid);
bindGroupSolid = context.pipelines->layouts.createBindGroupBuffer1Un(bufferGroupSolid);
context.layouts.releaseBindGroup(bindGroupSolid);
bindGroupSolid = context.layouts.createBindGroupBuffer1Un(bufferGroupSolid);
}
fillType = WgRenderSettingsType::Solid;
skip = (c.a == 0);
@ -281,8 +281,8 @@ void WgRenderSettings::update(WgContext& context, const Fill* fill, const Render
void WgRenderSettings::release(WgContext& context)
{
context.pipelines->layouts.releaseBindGroup(bindGroupSolid);
context.pipelines->layouts.releaseBindGroup(bindGroupGradient);
context.layouts.releaseBindGroup(bindGroupSolid);
context.layouts.releaseBindGroup(bindGroupGradient);
context.releaseBuffer(bufferGroupSolid);
context.releaseBuffer(bufferGroupGradient);
context.releaseBuffer(bufferGroupTransfromGrad);
@ -296,7 +296,7 @@ void WgRenderSettings::release(WgContext& context)
void WgRenderDataPaint::release(WgContext& context)
{
context.pipelines->layouts.releaseBindGroup(bindGroupPaint);
context.layouts.releaseBindGroup(bindGroupPaint);
context.releaseBuffer(bufferModelMat);
context.releaseBuffer(bufferBlendSettings);
clips.clear();
@ -310,8 +310,8 @@ void WgRenderDataPaint::update(WgContext& context, const tvg::Matrix& transform,
bool bufferModelMatChanged = context.allocateBufferUniform(bufferModelMat, &modelMat, sizeof(modelMat));
bool bufferBlendSettingsChanged = context.allocateBufferUniform(bufferBlendSettings, &blendSettings, sizeof(blendSettings));
if (bufferModelMatChanged || bufferBlendSettingsChanged) {
context.pipelines->layouts.releaseBindGroup(bindGroupPaint);
bindGroupPaint = context.pipelines->layouts.createBindGroupBuffer2Un(bufferModelMat, bufferBlendSettings);
context.layouts.releaseBindGroup(bindGroupPaint);
bindGroupPaint = context.layouts.createBindGroupBuffer2Un(bufferModelMat, bufferBlendSettings);
}
}
@ -545,8 +545,8 @@ void WgRenderDataPicture::updateSurface(WgContext& context, const RenderSurface*
// update texture data
imageData.update(context, surface);
// update texture bind group
context.pipelines->layouts.releaseBindGroup(bindGroupPicture);
bindGroupPicture = context.pipelines->layouts.createBindGroupTexSampled(
context.layouts.releaseBindGroup(bindGroupPicture);
bindGroupPicture = context.layouts.createBindGroupTexSampled(
context.samplerLinearRepeat, imageData.textureView
);
}
@ -554,7 +554,7 @@ void WgRenderDataPicture::updateSurface(WgContext& context, const RenderSurface*
void WgRenderDataPicture::release(WgContext& context)
{
context.pipelines->layouts.releaseBindGroup(bindGroupPicture);
context.layouts.releaseBindGroup(bindGroupPicture);
imageData.release(context);
meshData.release(context);
WgRenderDataPaint::release(context);

View file

@ -30,17 +30,17 @@ void WgRenderStorage::initialize(WgContext& context, uint32_t width, uint32_t he
textureMS = context.createTexAttachement(width, height, WGPUTextureFormat_RGBA8Unorm, 4);
texView = context.createTextureView(texture);
texViewMS = context.createTextureView(textureMS);
bindGroupRead = context.pipelines->layouts.createBindGroupStrorage1RO(texView);
bindGroupWrite = context.pipelines->layouts.createBindGroupStrorage1WO(texView);
bindGroupTexure = context.pipelines->layouts.createBindGroupTexSampled(context.samplerNearestRepeat, texView);
bindGroupRead = context.layouts.createBindGroupStrorage1RO(texView);
bindGroupWrite = context.layouts.createBindGroupStrorage1WO(texView);
bindGroupTexure = context.layouts.createBindGroupTexSampled(context.samplerNearestRepeat, texView);
}
void WgRenderStorage::release(WgContext& context)
{
context.pipelines->layouts.releaseBindGroup(bindGroupTexure);
context.pipelines->layouts.releaseBindGroup(bindGroupWrite);
context.pipelines->layouts.releaseBindGroup(bindGroupRead);
context.layouts.releaseBindGroup(bindGroupTexure);
context.layouts.releaseBindGroup(bindGroupWrite);
context.layouts.releaseBindGroup(bindGroupRead);
context.releaseTextureView(texViewMS);
context.releaseTexture(textureMS);
context.releaseTextureView(texView);

View file

@ -61,7 +61,6 @@ void WgRenderer::release()
// release context handles
mCompositor.release(mContext);
mPipelines.release(mContext);
mContext.release();
// release gpu handles
@ -312,7 +311,6 @@ bool WgRenderer::target(WGPUDevice device, WGPUInstance instance, void* target,
// initialize rendering context
mContext.initialize(instance, this->device);
mPipelines.initialize(mContext);
// initialize render tree instances
mRenderStoragePool.initialize(mContext, width, height);

View file

@ -85,7 +85,6 @@ private:
// rendering context
WgContext mContext;
WgPipelines mPipelines;
WgCompositor mCompositor;
// rendering states