Add validation rule for depth/stencil between pipeline and render bundle
This change also adds a unittest to validation colorFormatCount in
RenderBundleEncoderDescriptor, and fixes a style issue as well.
Bug: dawn:485
Change-Id: I642f0e250835d76288ac42fa18a8dabf2db30047
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/66621
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Yunchao He <yunchao.he@intel.com>
diff --git a/src/dawn_native/RenderBundleEncoder.cpp b/src/dawn_native/RenderBundleEncoder.cpp
index cd12323..4c68c4c 100644
--- a/src/dawn_native/RenderBundleEncoder.cpp
+++ b/src/dawn_native/RenderBundleEncoder.cpp
@@ -90,8 +90,8 @@
: RenderEncoderBase(device,
&mBundleEncodingContext,
device->GetOrCreateAttachmentState(descriptor),
- false,
- false),
+ descriptor->depthReadOnly,
+ descriptor->stencilReadOnly),
mBundleEncodingContext(device, this) {
}
diff --git a/src/dawn_native/RenderPipeline.cpp b/src/dawn_native/RenderPipeline.cpp
index 82fdde8..1c16bba 100644
--- a/src/dawn_native/RenderPipeline.cpp
+++ b/src/dawn_native/RenderPipeline.cpp
@@ -543,15 +543,15 @@
return stages;
}
- bool StencilTestEnabled(const DepthStencilState* mDepthStencil) {
- return mDepthStencil->stencilBack.compare != wgpu::CompareFunction::Always ||
- mDepthStencil->stencilBack.failOp != wgpu::StencilOperation::Keep ||
- mDepthStencil->stencilBack.depthFailOp != wgpu::StencilOperation::Keep ||
- mDepthStencil->stencilBack.passOp != wgpu::StencilOperation::Keep ||
- mDepthStencil->stencilFront.compare != wgpu::CompareFunction::Always ||
- mDepthStencil->stencilFront.failOp != wgpu::StencilOperation::Keep ||
- mDepthStencil->stencilFront.depthFailOp != wgpu::StencilOperation::Keep ||
- mDepthStencil->stencilFront.passOp != wgpu::StencilOperation::Keep;
+ bool StencilTestEnabled(const DepthStencilState* depthStencil) {
+ return depthStencil->stencilBack.compare != wgpu::CompareFunction::Always ||
+ depthStencil->stencilBack.failOp != wgpu::StencilOperation::Keep ||
+ depthStencil->stencilBack.depthFailOp != wgpu::StencilOperation::Keep ||
+ depthStencil->stencilBack.passOp != wgpu::StencilOperation::Keep ||
+ depthStencil->stencilFront.compare != wgpu::CompareFunction::Always ||
+ depthStencil->stencilFront.failOp != wgpu::StencilOperation::Keep ||
+ depthStencil->stencilFront.depthFailOp != wgpu::StencilOperation::Keep ||
+ depthStencil->stencilFront.passOp != wgpu::StencilOperation::Keep;
}
// RenderPipelineBase
diff --git a/src/dawn_native/RenderPipeline.h b/src/dawn_native/RenderPipeline.h
index 4020bcc..bd354ab 100644
--- a/src/dawn_native/RenderPipeline.h
+++ b/src/dawn_native/RenderPipeline.h
@@ -41,7 +41,7 @@
bool IsStripPrimitiveTopology(wgpu::PrimitiveTopology primitiveTopology);
- bool StencilTestEnabled(const DepthStencilState* mDepthStencil);
+ bool StencilTestEnabled(const DepthStencilState* depthStencil);
struct VertexAttributeInfo {
wgpu::VertexFormat format;
diff --git a/src/tests/unittests/validation/PipelineAndPassCompatibilityTests.cpp b/src/tests/unittests/validation/PipelineAndPassCompatibilityTests.cpp
index a71afa2..e30299f 100644
--- a/src/tests/unittests/validation/PipelineAndPassCompatibilityTests.cpp
+++ b/src/tests/unittests/validation/PipelineAndPassCompatibilityTests.cpp
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include "utils/ComboRenderBundleEncoderDescriptor.h"
#include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/WGPUHelpers.h"
@@ -105,8 +106,40 @@
}
}
+ // Test depthWrite/stencilWrite in DepthStencilState in pipeline vs
+ // depthReadOnly/stencilReadOnly in RenderBundleEncoderDescriptor in RenderBundle
+ TEST_F(RenderPipelineAndPassCompatibilityTests,
+ WriteAndReadOnlyConflictForDepthStencilWithRenderBundle) {
+ 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
+ // depthReadOnlyInBundle and stencilReadOnlyInBundle.
+ for (bool depthStencilReadOnlyInBundle : {true, false}) {
+ utils::ComboRenderBundleEncoderDescriptor desc = {};
+ desc.depthStencilFormat = kFormat;
+ desc.depthReadOnly = depthStencilReadOnlyInBundle;
+ desc.stencilReadOnly = depthStencilReadOnlyInBundle;
+
+ for (bool depthWriteInPipeline : {true, false}) {
+ for (bool stencilWriteInPipeline : {true, false}) {
+ wgpu::RenderBundleEncoder renderBundleEncoder =
+ device.CreateRenderBundleEncoder(&desc);
+ wgpu::RenderPipeline pipeline =
+ CreatePipeline(kFormat, depthWriteInPipeline, stencilWriteInPipeline);
+ renderBundleEncoder.SetPipeline(pipeline);
+ renderBundleEncoder.Draw(3);
+ if (depthStencilReadOnlyInBundle &&
+ (depthWriteInPipeline || stencilWriteInPipeline)) {
+ ASSERT_DEVICE_ERROR(renderBundleEncoder.Finish());
+ } else {
+ renderBundleEncoder.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.
diff --git a/src/tests/unittests/validation/RenderBundleValidationTests.cpp b/src/tests/unittests/validation/RenderBundleValidationTests.cpp
index 50c452e..bb3a01a 100644
--- a/src/tests/unittests/validation/RenderBundleValidationTests.cpp
+++ b/src/tests/unittests/validation/RenderBundleValidationTests.cpp
@@ -611,6 +611,30 @@
}
}
+// Test that it is invalid to create a render bundle with no texture formats
+TEST_F(RenderBundleValidationTest, ColorFormatsCountOutOfBounds) {
+ std::array<wgpu::TextureFormat, kMaxColorAttachments + 1> colorFormats;
+ for (uint32_t i = 0; i < colorFormats.size(); ++i) {
+ colorFormats[i] = wgpu::TextureFormat::RGBA8Unorm;
+ }
+
+ // colorFormatsCount <= kMaxColorAttachments is valid.
+ {
+ wgpu::RenderBundleEncoderDescriptor desc;
+ desc.colorFormatsCount = kMaxColorAttachments;
+ desc.colorFormats = colorFormats.data();
+ device.CreateRenderBundleEncoder(&desc);
+ }
+
+ // colorFormatsCount > kMaxColorAttachments is invalid.
+ {
+ wgpu::RenderBundleEncoderDescriptor desc;
+ desc.colorFormatsCount = kMaxColorAttachments + 1;
+ desc.colorFormats = colorFormats.data();
+ ASSERT_DEVICE_ERROR(device.CreateRenderBundleEncoder(&desc));
+ }
+}
+
// Test that render bundle color formats cannot be set to undefined.
TEST_F(RenderBundleValidationTest, ColorFormatUndefined) {
utils::ComboRenderBundleEncoderDescriptor desc = {};