mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-15 08:06:19 +00:00
Add validation rule for depth/stencil between pipeline and pass
depthWrite/stencilWrite in DepthStencilState in RenderPipeline should be compatible with depthReadOnly/stencilReadOnly in DepthStencilAttachment in RenderPass. Otherwise, you may need to generate validation errors. Bug: dawn:485 Change-Id: I7b541056dafc4dee4eb31f4cefbac48c0ffc4b18 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/66240 Commit-Queue: Yunchao He <yunchao.he@intel.com> Reviewed-by: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
// Copyright 2021 The Dawn Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "utils/ComboRenderPipelineDescriptor.h"
|
||||
#include "utils/WGPUHelpers.h"
|
||||
|
||||
#include "tests/unittests/validation/ValidationTest.h"
|
||||
|
||||
constexpr static uint32_t kSize = 4;
|
||||
|
||||
namespace {
|
||||
|
||||
class RenderPipelineAndPassCompatibilityTests : public ValidationTest {
|
||||
public:
|
||||
wgpu::RenderPipeline CreatePipeline(wgpu::TextureFormat format,
|
||||
bool enableDepthWrite,
|
||||
bool enableStencilWrite) {
|
||||
// Create a NoOp pipeline
|
||||
utils::ComboRenderPipelineDescriptor pipelineDescriptor;
|
||||
pipelineDescriptor.vertex.module = utils::CreateShaderModule(device, R"(
|
||||
[[stage(vertex)]] fn main() -> [[builtin(position)]] vec4<f32> {
|
||||
return vec4<f32>();
|
||||
})");
|
||||
pipelineDescriptor.cFragment.module = utils::CreateShaderModule(device, R"(
|
||||
[[stage(fragment)]] fn main() {
|
||||
})");
|
||||
pipelineDescriptor.cFragment.targets = nullptr;
|
||||
pipelineDescriptor.cFragment.targetCount = 0;
|
||||
|
||||
// Enable depth/stencil write if needed
|
||||
wgpu::DepthStencilState* depthStencil = pipelineDescriptor.EnableDepthStencil(format);
|
||||
if (enableDepthWrite) {
|
||||
depthStencil->depthWriteEnabled = true;
|
||||
}
|
||||
if (enableStencilWrite) {
|
||||
depthStencil->stencilFront.failOp = wgpu::StencilOperation::Replace;
|
||||
}
|
||||
return device.CreateRenderPipeline(&pipelineDescriptor);
|
||||
}
|
||||
|
||||
utils::ComboRenderPassDescriptor CreateRenderPassDescriptor(wgpu::TextureFormat format,
|
||||
bool depthReadOnly,
|
||||
bool stencilReadOnly) {
|
||||
wgpu::TextureDescriptor textureDescriptor = {};
|
||||
textureDescriptor.size = {kSize, kSize, 1};
|
||||
textureDescriptor.format = format;
|
||||
textureDescriptor.usage = wgpu::TextureUsage::RenderAttachment;
|
||||
wgpu::Texture depthStencilTexture = device.CreateTexture(&textureDescriptor);
|
||||
|
||||
utils::ComboRenderPassDescriptor passDescriptor({}, depthStencilTexture.CreateView());
|
||||
if (depthReadOnly) {
|
||||
passDescriptor.cDepthStencilAttachmentInfo.depthReadOnly = true;
|
||||
passDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Load;
|
||||
passDescriptor.cDepthStencilAttachmentInfo.depthStoreOp = wgpu::StoreOp::Store;
|
||||
}
|
||||
|
||||
if (stencilReadOnly) {
|
||||
passDescriptor.cDepthStencilAttachmentInfo.stencilReadOnly = true;
|
||||
passDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Load;
|
||||
passDescriptor.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Store;
|
||||
}
|
||||
|
||||
return passDescriptor;
|
||||
}
|
||||
};
|
||||
|
||||
// Test depthWrite/stencilWrite in DepthStencilState in pipeline vs
|
||||
// depthReadOnly/stencilReadOnly in DepthStencilAttachment in pass
|
||||
TEST_F(RenderPipelineAndPassCompatibilityTests, WriteAndReadOnlyConflictForDepthStencil) {
|
||||
wgpu::TextureFormat kFormat = wgpu::TextureFormat::Depth24PlusStencil8;
|
||||
// If the format has both depth and stencil aspects, depthReadOnly and stencilReadOnly
|
||||
// should be the same. So it is not necessary to set two separate booleans like
|
||||
// depthReadOnlyInPass and stencilReadOnlyInPass.
|
||||
for (bool depthStencilReadOnlyInPass : {true, false}) {
|
||||
for (bool depthWriteInPipeline : {true, false}) {
|
||||
for (bool stencilWriteInPipeline : {true, false}) {
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
utils::ComboRenderPassDescriptor passDescriptor = CreateRenderPassDescriptor(
|
||||
kFormat, depthStencilReadOnlyInPass, depthStencilReadOnlyInPass);
|
||||
wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&passDescriptor);
|
||||
wgpu::RenderPipeline pipeline =
|
||||
CreatePipeline(kFormat, depthWriteInPipeline, stencilWriteInPipeline);
|
||||
pass.SetPipeline(pipeline);
|
||||
pass.Draw(3);
|
||||
pass.EndPass();
|
||||
if (depthStencilReadOnlyInPass &&
|
||||
(depthWriteInPipeline || stencilWriteInPipeline)) {
|
||||
ASSERT_DEVICE_ERROR(encoder.Finish());
|
||||
} else {
|
||||
encoder.Finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(dawn:485): add more tests. For example:
|
||||
// - readOnly vs write for depth/stencil with renderbundle.
|
||||
// - depth/stencil attachment should be designated if depth/stencil test is enabled.
|
||||
// - pipeline and pass compatibility tests for color attachment(s).
|
||||
// - pipeline and pass compatibility tests for compute.
|
||||
|
||||
} // anonymous namespace
|
||||
Reference in New Issue
Block a user