wg_engine: fix color buffer corruption with wgpu-opengl wrapper (linux)

In a case of usage stencil buffer only we need to turn off an color target writes. In other case color buffer fill be filled by unxepcted color if fragment shader did not return any value.
It happens in a case on OpenGL realization of webgpu, that used in linux

Befire:

After:
This commit is contained in:
Sergii Liebodkin 2024-05-31 13:51:46 +03:00 committed by Hermet Park
parent f77894e407
commit a2ea964be1
7 changed files with 44 additions and 39 deletions

View file

@ -107,9 +107,16 @@ void WgContext::release()
if (device) {
wgpuDeviceDestroy(device);
wgpuDeviceRelease(device);
device = nullptr;
}
if (adapter) {
wgpuAdapterRelease(adapter);
adapter = nullptr;
}
if (instance) {
wgpuInstanceRelease(instance);
instance = nullptr;
}
if (adapter) wgpuAdapterRelease(adapter);
if (instance) wgpuInstanceRelease(instance);
}
@ -426,7 +433,7 @@ WGPUBindGroupLayoutEntry WgBindGroup::makeBindGroupLayoutEntryStorageTexture(uin
bindGroupLayoutEntry.visibility = WGPUShaderStage_Fragment | WGPUShaderStage_Compute;
bindGroupLayoutEntry.storageTexture.nextInChain = nullptr;
bindGroupLayoutEntry.storageTexture.access = access;
bindGroupLayoutEntry.storageTexture.format = WGPUTextureFormat_RGBA8Unorm;
bindGroupLayoutEntry.storageTexture.format = WGPUTextureFormat_BGRA8Unorm;
bindGroupLayoutEntry.storageTexture.viewDimension = WGPUTextureViewDimension_2D;
return bindGroupLayoutEntry;
}
@ -547,7 +554,7 @@ void WgPipeline::destroyShaderModule(WGPUShaderModule& shaderModule)
// render pipeline
//*****************************************************************************
void WgRenderPipeline::allocate(WGPUDevice device, WgPipelineBlendType blendType,
void WgRenderPipeline::allocate(WGPUDevice device, WgPipelineBlendType blendType, WGPUColorWriteMask writeMask,
WGPUVertexBufferLayout vertexBufferLayouts[], uint32_t attribsCount,
WGPUBindGroupLayout bindGroupLayouts[], uint32_t bindGroupsCount,
WGPUCompareFunction compareFront, WGPUStencilOperation operationFront,
@ -560,7 +567,7 @@ void WgRenderPipeline::allocate(WGPUDevice device, WgPipelineBlendType blendType
mPipelineLayout = createPipelineLayout(device, bindGroupLayouts, bindGroupsCount);
assert(mPipelineLayout);
mRenderPipeline = createRenderPipeline(device, blendType,
mRenderPipeline = createRenderPipeline(device, blendType, writeMask,
vertexBufferLayouts, attribsCount,
compareFront, operationFront,
compareBack, operationBack,
@ -623,14 +630,13 @@ WGPUBlendState WgRenderPipeline::makeBlendState(WgPipelineBlendType blendType)
}
WGPUColorTargetState WgRenderPipeline::makeColorTargetState(const WGPUBlendState* blendState)
WGPUColorTargetState WgRenderPipeline::makeColorTargetState(const WGPUBlendState* blendState, const WGPUColorWriteMask writeMask)
{
WGPUColorTargetState colorTargetState{};
colorTargetState.nextInChain = nullptr;
//colorTargetState.format = WGPUTextureFormat_BGRA8Unorm; // (WGPUTextureFormat_BGRA8UnormSrgb)
colorTargetState.format = WGPUTextureFormat_RGBA8Unorm; // (WGPUTextureFormat_BGRA8UnormSrgb)
colorTargetState.format = WGPUTextureFormat_BGRA8Unorm;
colorTargetState.blend = blendState;
colorTargetState.writeMask = WGPUColorWriteMask_All;
colorTargetState.writeMask = writeMask;
return colorTargetState;
}
@ -721,7 +727,7 @@ WGPUFragmentState WgRenderPipeline::makeFragmentState(WGPUShaderModule shaderMod
}
WGPURenderPipeline WgRenderPipeline::createRenderPipeline(WGPUDevice device, WgPipelineBlendType blendType,
WGPURenderPipeline WgRenderPipeline::createRenderPipeline(WGPUDevice device, WgPipelineBlendType blendType, WGPUColorWriteMask writeMask,
WGPUVertexBufferLayout vertexBufferLayouts[], uint32_t attribsCount,
WGPUCompareFunction compareFront, WGPUStencilOperation operationFront,
WGPUCompareFunction compareBack, WGPUStencilOperation operationBack,
@ -730,7 +736,7 @@ WGPURenderPipeline WgRenderPipeline::createRenderPipeline(WGPUDevice device, WgP
{
WGPUBlendState blendState = makeBlendState(blendType);
WGPUColorTargetState colorTargetStates[] = {
makeColorTargetState(&blendState)
makeColorTargetState(&blendState, writeMask)
};
WGPUVertexState vertexState = makeVertexState(shaderModule, vertexBufferLayouts, attribsCount);

View file

@ -125,7 +125,7 @@ struct WgRenderPipeline: public WgPipeline
{
protected:
WGPURenderPipeline mRenderPipeline{};
void allocate(WGPUDevice device, WgPipelineBlendType blendType,
void allocate(WGPUDevice device, WgPipelineBlendType blendType, WGPUColorWriteMask writeMask,
WGPUVertexBufferLayout vertexBufferLayouts[], uint32_t attribsCount,
WGPUBindGroupLayout bindGroupLayouts[], uint32_t bindGroupsCount,
WGPUCompareFunction compareFront, WGPUStencilOperation operationFront,
@ -136,7 +136,7 @@ public:
void set(WGPURenderPassEncoder renderPassEncoder);
static WGPUBlendState makeBlendState(WgPipelineBlendType blendType);
static WGPUColorTargetState makeColorTargetState(const WGPUBlendState* blendState);
static WGPUColorTargetState makeColorTargetState(const WGPUBlendState* blendState, const WGPUColorWriteMask writeMask);
static WGPUVertexBufferLayout makeVertexBufferLayout(const WGPUVertexAttribute* vertexAttributes, uint32_t count, uint64_t stride);
static WGPUVertexState makeVertexState(WGPUShaderModule shaderModule, const WGPUVertexBufferLayout* buffers, uint32_t count);
static WGPUPrimitiveState makePrimitiveState();
@ -144,7 +144,7 @@ public:
static WGPUMultisampleState makeMultisampleState();
static WGPUFragmentState makeFragmentState(WGPUShaderModule shaderModule, WGPUColorTargetState* targets, uint32_t size);
static WGPURenderPipeline createRenderPipeline(WGPUDevice device, WgPipelineBlendType blendType,
static WGPURenderPipeline createRenderPipeline(WGPUDevice device, WgPipelineBlendType blendType, WGPUColorWriteMask writeMask,
WGPUVertexBufferLayout vertexBufferLayouts[], uint32_t attribsCount,
WGPUCompareFunction compareFront, WGPUStencilOperation operationFront,
WGPUCompareFunction compareBack, WGPUStencilOperation operationBack,

View file

@ -55,7 +55,7 @@ void WgPipelineFillShapeWinding::initialize(WGPUDevice device)
auto pipelineLabel = "The render pipeline fill shape winding";
// allocate all pipeline handles
allocate(device, WgPipelineBlendType::Src,
allocate(device, WgPipelineBlendType::Add, WGPUColorWriteMask_None,
vertexBufferLayouts, ARRAY_ELEMENTS_COUNT(vertexBufferLayouts),
bindGroupLayouts, ARRAY_ELEMENTS_COUNT(bindGroupLayouts),
stencilFuncionFront, stencilOperationFront, stencilFuncionBack, stencilOperationBack,
@ -89,7 +89,7 @@ void WgPipelineFillShapeEvenOdd::initialize(WGPUDevice device)
auto pipelineLabel = "The render pipeline fill shape Even Odd";
// allocate all pipeline handles
allocate(device, WgPipelineBlendType::Src,
allocate(device, WgPipelineBlendType::Add, WGPUColorWriteMask_None,
vertexBufferLayouts, ARRAY_ELEMENTS_COUNT(vertexBufferLayouts),
bindGroupLayouts, ARRAY_ELEMENTS_COUNT(bindGroupLayouts),
stencilFuncionFront, stencilOperationFront, stencilFuncionBack, stencilOperationBack,
@ -121,7 +121,7 @@ void WgPipelineFillStroke::initialize(WGPUDevice device)
auto pipelineLabel = "The render pipeline fill stroke";
// allocate all pipeline handles
allocate(device, WgPipelineBlendType::Src,
allocate(device, WgPipelineBlendType::Add, WGPUColorWriteMask_None,
vertexBufferLayouts, ARRAY_ELEMENTS_COUNT(vertexBufferLayouts),
bindGroupLayouts, ARRAY_ELEMENTS_COUNT(bindGroupLayouts),
stencilFuncion, stencilOperation, stencilFuncion, stencilOperation,
@ -154,7 +154,7 @@ void WgPipelineSolid::initialize(WGPUDevice device, WgPipelineBlendType blendTyp
auto pipelineLabel = "The render pipeline solid color";
// allocate all pipeline handles
allocate(device, blendType,
allocate(device, blendType, WGPUColorWriteMask_All,
vertexBufferLayouts, ARRAY_ELEMENTS_COUNT(vertexBufferLayouts),
bindGroupLayouts, ARRAY_ELEMENTS_COUNT(bindGroupLayouts),
stencilFuncion, stencilOperation, stencilFuncion, stencilOperation,
@ -187,7 +187,7 @@ void WgPipelineLinear::initialize(WGPUDevice device, WgPipelineBlendType blendTy
auto pipelineLabel = "The render pipeline linear gradient";
// allocate all pipeline handles
allocate(device, blendType,
allocate(device, blendType, WGPUColorWriteMask_All,
vertexBufferLayouts, ARRAY_ELEMENTS_COUNT(vertexBufferLayouts),
bindGroupLayouts, ARRAY_ELEMENTS_COUNT(bindGroupLayouts),
stencilFuncion, stencilOperation, stencilFuncion, stencilOperation,
@ -220,7 +220,7 @@ void WgPipelineRadial::initialize(WGPUDevice device, WgPipelineBlendType blendTy
auto pipelineLabel = "The render pipeline radial gradient";
// allocate all pipeline handles
allocate(device, blendType,
allocate(device, blendType, WGPUColorWriteMask_All,
vertexBufferLayouts, ARRAY_ELEMENTS_COUNT(vertexBufferLayouts),
bindGroupLayouts, ARRAY_ELEMENTS_COUNT(bindGroupLayouts),
stencilFuncion, stencilOperation, stencilFuncion, stencilOperation,
@ -255,7 +255,7 @@ void WgPipelineImage::initialize(WGPUDevice device, WgPipelineBlendType blendTyp
auto pipelineLabel = "The render pipeline image";
// allocate all pipeline handles
allocate(device, blendType,
allocate(device, blendType, WGPUColorWriteMask_All,
vertexBufferLayouts, ARRAY_ELEMENTS_COUNT(vertexBufferLayouts),
bindGroupLayouts, ARRAY_ELEMENTS_COUNT(bindGroupLayouts),
stencilFuncion, stencilOperation, stencilFuncion, stencilOperation,

View file

@ -353,8 +353,8 @@ void WgRenderDataShape::releaseMeshes(WgContext &context)
meshGroupStrokes.release(context);
meshGroupShapesBBox.release(context);
meshGroupShapes.release(context);
pMin = {0.0f, 0.0f };
pMax = {0.0f, 0.0f };
pMin = {FLT_MAX, FLT_MAX};
pMax = {0.0f, 0.0f};
}

View file

@ -41,7 +41,7 @@
WGPUTextureUsage_TextureBinding |
WGPUTextureUsage_StorageBinding |
WGPUTextureUsage_RenderAttachment,
WGPUTextureFormat_RGBA8Unorm,
WGPUTextureFormat_BGRA8Unorm,
width, height, "The target texture color");
texStencil = context.createTexture2d(
WGPUTextureUsage_RenderAttachment,
@ -266,7 +266,7 @@ void WgRenderStorage::beginRenderPass(WGPUCommandEncoder commandEncoder, bool cl
depthStencilAttachment.depthClearValue = 1.0f;
depthStencilAttachment.depthReadOnly = false;
depthStencilAttachment.stencilLoadOp = WGPULoadOp_Clear;
depthStencilAttachment.stencilStoreOp = WGPUStoreOp_Store;
depthStencilAttachment.stencilStoreOp = WGPUStoreOp_Discard;
depthStencilAttachment.stencilClearValue = 0;
depthStencilAttachment.stencilReadOnly = false;
// render pass color attachment

View file

@ -320,8 +320,7 @@ bool WgRenderer::target(void* window, uint32_t w, uint32_t h)
mTargetSurface.stride = w;
mTargetSurface.w = w > 0 ? w : 1;
mTargetSurface.h = h > 0 ? h : 1;
// TODO: replace solution to cross-platform realization
// surface descriptor from windows hwnd
WGPUSurfaceDescriptorFromWindowsHWND surfaceDescHwnd{};
surfaceDescHwnd.chain.next = nullptr;
@ -337,8 +336,8 @@ bool WgRenderer::target(void* window, uint32_t w, uint32_t h)
WGPUSurfaceConfiguration surfaceConfiguration{};
surfaceConfiguration.nextInChain = nullptr;
surfaceConfiguration.device = mContext.device;
surfaceConfiguration.format = WGPUTextureFormat_RGBA8Unorm;
surfaceConfiguration.usage = WGPUTextureUsage_RenderAttachment | WGPUTextureUsage_CopyDst;
surfaceConfiguration.format = WGPUTextureFormat_BGRA8Unorm;
surfaceConfiguration.usage = WGPUTextureUsage_CopyDst;
surfaceConfiguration.viewFormatCount = 0;
surfaceConfiguration.viewFormats = nullptr;
surfaceConfiguration.alphaMode = WGPUCompositeAlphaMode_Auto;

View file

@ -365,7 +365,7 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4f {
// pipeline shader modules clear
const char* cShaderSource_PipelineComputeClear = R"(
@group(0) @binding(0) var imageDst : texture_storage_2d<rgba8unorm, read_write>;
@group(0) @binding(0) var imageDst : texture_storage_2d<bgra8unorm, read_write>;
@compute @workgroup_size(8, 8)
fn cs_main( @builtin(global_invocation_id) id: vec3u) {
@ -376,8 +376,8 @@ fn cs_main( @builtin(global_invocation_id) id: vec3u) {
// pipeline shader modules blend
const char* cShaderSource_PipelineComputeBlend = R"(
@group(0) @binding(0) var imageSrc : texture_storage_2d<rgba8unorm, read_write>;
@group(1) @binding(0) var imageDst : texture_storage_2d<rgba8unorm, read_write>;
@group(0) @binding(0) var imageSrc : texture_storage_2d<bgra8unorm, read_write>;
@group(1) @binding(0) var imageDst : texture_storage_2d<bgra8unorm, read_write>;
@group(2) @binding(0) var<uniform> blendMethod : u32;
@compute @workgroup_size(8, 8)
@ -420,8 +420,8 @@ fn cs_main( @builtin(global_invocation_id) id: vec3u) {
// pipeline shader modules compose
const char* cShaderSource_PipelineComputeCompose = R"(
@group(0) @binding(0) var imageSrc : texture_storage_2d<rgba8unorm, read_write>;
@group(1) @binding(0) var imageMsk : texture_storage_2d<rgba8unorm, read_write>;
@group(0) @binding(0) var imageSrc : texture_storage_2d<bgra8unorm, read_write>;
@group(1) @binding(0) var imageMsk : texture_storage_2d<bgra8unorm, read_write>;
@group(2) @binding(0) var<uniform> composeMethod : u32;
@group(3) @binding(0) var<uniform> opacity : f32;
@ -455,9 +455,9 @@ fn cs_main( @builtin(global_invocation_id) id: vec3u) {
// pipeline shader modules compose blend
const char* cShaderSource_PipelineComputeComposeBlend = R"(
@group(0) @binding(0) var imageSrc : texture_storage_2d<rgba8unorm, read>;
@group(0) @binding(1) var imageMsk : texture_storage_2d<rgba8unorm, read>;
@group(0) @binding(2) var imageDst : texture_storage_2d<rgba8unorm, read_write>;
@group(0) @binding(0) var imageSrc : texture_storage_2d<bgra8unorm, read>;
@group(0) @binding(1) var imageMsk : texture_storage_2d<bgra8unorm, read>;
@group(0) @binding(2) var imageDst : texture_storage_2d<bgra8unorm, read_write>;
@group(1) @binding(0) var<uniform> composeMethod : u32;
@group(2) @binding(0) var<uniform> blendMethod : u32;
@group(3) @binding(0) var<uniform> opacity : f32;
@ -517,8 +517,8 @@ fn cs_main( @builtin(global_invocation_id) id: vec3u) {
// pipeline shader modules anti-aliasing
const char* cShaderSource_PipelineComputeAntiAlias = R"(
@group(0) @binding(0) var imageSrc : texture_storage_2d<rgba8unorm, read_write>;
@group(1) @binding(0) var imageDst : texture_storage_2d<rgba8unorm, read_write>;
@group(0) @binding(0) var imageSrc : texture_storage_2d<bgra8unorm, read_write>;
@group(1) @binding(0) var imageDst : texture_storage_2d<bgra8unorm, read_write>;
@compute @workgroup_size(8, 8)
fn cs_main( @builtin(global_invocation_id) id: vec3u) {