blob: f3de6bfccb024b7ec21cc6746493c2bf91cbbbe6 [file] [log] [blame]
Yunchao Hedaffd222021-10-14 04:09:21 +00001// Copyright 2021 The Dawn Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Yunchao Hee43eaab2021-10-18 16:57:31 +000015#include "utils/ComboRenderBundleEncoderDescriptor.h"
Yunchao Hedaffd222021-10-14 04:09:21 +000016#include "utils/ComboRenderPipelineDescriptor.h"
17#include "utils/WGPUHelpers.h"
18
19#include "tests/unittests/validation/ValidationTest.h"
20
21constexpr static uint32_t kSize = 4;
Yunchao Hed2c9cd32021-10-19 21:10:23 +000022// Note that format Depth24PlusStencil8 has both depth and stencil aspects, so parameters
23// depthReadOnly and stencilReadOnly should be the same in render pass and render bundle.
24wgpu::TextureFormat kFormat = wgpu::TextureFormat::Depth24PlusStencil8;
Yunchao Hedaffd222021-10-14 04:09:21 +000025
26namespace {
27
28 class RenderPipelineAndPassCompatibilityTests : public ValidationTest {
29 public:
30 wgpu::RenderPipeline CreatePipeline(wgpu::TextureFormat format,
31 bool enableDepthWrite,
32 bool enableStencilWrite) {
33 // Create a NoOp pipeline
34 utils::ComboRenderPipelineDescriptor pipelineDescriptor;
35 pipelineDescriptor.vertex.module = utils::CreateShaderModule(device, R"(
36 [[stage(vertex)]] fn main() -> [[builtin(position)]] vec4<f32> {
37 return vec4<f32>();
38 })");
39 pipelineDescriptor.cFragment.module = utils::CreateShaderModule(device, R"(
40 [[stage(fragment)]] fn main() {
41 })");
42 pipelineDescriptor.cFragment.targets = nullptr;
43 pipelineDescriptor.cFragment.targetCount = 0;
44
45 // Enable depth/stencil write if needed
46 wgpu::DepthStencilState* depthStencil = pipelineDescriptor.EnableDepthStencil(format);
47 if (enableDepthWrite) {
48 depthStencil->depthWriteEnabled = true;
49 }
50 if (enableStencilWrite) {
51 depthStencil->stencilFront.failOp = wgpu::StencilOperation::Replace;
52 }
53 return device.CreateRenderPipeline(&pipelineDescriptor);
54 }
55
56 utils::ComboRenderPassDescriptor CreateRenderPassDescriptor(wgpu::TextureFormat format,
57 bool depthReadOnly,
58 bool stencilReadOnly) {
59 wgpu::TextureDescriptor textureDescriptor = {};
60 textureDescriptor.size = {kSize, kSize, 1};
61 textureDescriptor.format = format;
62 textureDescriptor.usage = wgpu::TextureUsage::RenderAttachment;
63 wgpu::Texture depthStencilTexture = device.CreateTexture(&textureDescriptor);
64
65 utils::ComboRenderPassDescriptor passDescriptor({}, depthStencilTexture.CreateView());
66 if (depthReadOnly) {
67 passDescriptor.cDepthStencilAttachmentInfo.depthReadOnly = true;
68 passDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Load;
69 passDescriptor.cDepthStencilAttachmentInfo.depthStoreOp = wgpu::StoreOp::Store;
70 }
71
72 if (stencilReadOnly) {
73 passDescriptor.cDepthStencilAttachmentInfo.stencilReadOnly = true;
74 passDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Load;
75 passDescriptor.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Store;
76 }
77
78 return passDescriptor;
79 }
80 };
81
Yunchao Hed2c9cd32021-10-19 21:10:23 +000082 // Test depthWrite/stencilWrite in DepthStencilState in render pipeline vs
83 // depthReadOnly/stencilReadOnly in DepthStencilAttachment in render pass.
Yunchao Hedaffd222021-10-14 04:09:21 +000084 TEST_F(RenderPipelineAndPassCompatibilityTests, WriteAndReadOnlyConflictForDepthStencil) {
Yunchao Hedaffd222021-10-14 04:09:21 +000085 for (bool depthStencilReadOnlyInPass : {true, false}) {
86 for (bool depthWriteInPipeline : {true, false}) {
87 for (bool stencilWriteInPipeline : {true, false}) {
88 wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
89 utils::ComboRenderPassDescriptor passDescriptor = CreateRenderPassDescriptor(
90 kFormat, depthStencilReadOnlyInPass, depthStencilReadOnlyInPass);
91 wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&passDescriptor);
92 wgpu::RenderPipeline pipeline =
93 CreatePipeline(kFormat, depthWriteInPipeline, stencilWriteInPipeline);
94 pass.SetPipeline(pipeline);
95 pass.Draw(3);
96 pass.EndPass();
97 if (depthStencilReadOnlyInPass &&
98 (depthWriteInPipeline || stencilWriteInPipeline)) {
99 ASSERT_DEVICE_ERROR(encoder.Finish());
100 } else {
101 encoder.Finish();
102 }
103 }
104 }
105 }
106 }
107
Yunchao Hed2c9cd32021-10-19 21:10:23 +0000108 // Test depthWrite/stencilWrite in DepthStencilState in render pipeline vs
109 // depthReadOnly/stencilReadOnly in RenderBundleEncoderDescriptor in render bundle.
Yunchao Hee43eaab2021-10-18 16:57:31 +0000110 TEST_F(RenderPipelineAndPassCompatibilityTests,
Yunchao Hed2c9cd32021-10-19 21:10:23 +0000111 WriteAndReadOnlyConflictForDepthStencilBetweenPipelineAndBundle) {
Yunchao Hee43eaab2021-10-18 16:57:31 +0000112 for (bool depthStencilReadOnlyInBundle : {true, false}) {
113 utils::ComboRenderBundleEncoderDescriptor desc = {};
114 desc.depthStencilFormat = kFormat;
115 desc.depthReadOnly = depthStencilReadOnlyInBundle;
116 desc.stencilReadOnly = depthStencilReadOnlyInBundle;
117
118 for (bool depthWriteInPipeline : {true, false}) {
119 for (bool stencilWriteInPipeline : {true, false}) {
120 wgpu::RenderBundleEncoder renderBundleEncoder =
121 device.CreateRenderBundleEncoder(&desc);
122 wgpu::RenderPipeline pipeline =
123 CreatePipeline(kFormat, depthWriteInPipeline, stencilWriteInPipeline);
124 renderBundleEncoder.SetPipeline(pipeline);
125 renderBundleEncoder.Draw(3);
126 if (depthStencilReadOnlyInBundle &&
127 (depthWriteInPipeline || stencilWriteInPipeline)) {
128 ASSERT_DEVICE_ERROR(renderBundleEncoder.Finish());
129 } else {
130 renderBundleEncoder.Finish();
131 }
132 }
133 }
134 }
135 }
136
Yunchao Hed2c9cd32021-10-19 21:10:23 +0000137 // Test depthReadOnly/stencilReadOnly in RenderBundleEncoderDescriptor in render bundle vs
138 // depthReadOnly/stencilReadOnly in DepthStencilAttachment in render pass.
139 TEST_F(RenderPipelineAndPassCompatibilityTests,
140 WriteAndReadOnlyConflictForDepthStencilBetweenBundleAndPass) {
141 for (bool depthStencilReadOnlyInPass : {true, false}) {
142 for (bool depthStencilReadOnlyInBundle : {true, false}) {
143 for (bool emptyBundle : {true, false}) {
144 // Create render bundle, with or without a pipeline
145 utils::ComboRenderBundleEncoderDescriptor desc = {};
146 desc.depthStencilFormat = kFormat;
147 desc.depthReadOnly = depthStencilReadOnlyInBundle;
148 desc.stencilReadOnly = depthStencilReadOnlyInBundle;
149 wgpu::RenderBundleEncoder renderBundleEncoder =
150 device.CreateRenderBundleEncoder(&desc);
151 if (!emptyBundle) {
152 wgpu::RenderPipeline pipeline = CreatePipeline(
153 kFormat, !depthStencilReadOnlyInBundle, !depthStencilReadOnlyInBundle);
154 renderBundleEncoder.SetPipeline(pipeline);
155 renderBundleEncoder.Draw(3);
156 }
157 wgpu::RenderBundle bundle = renderBundleEncoder.Finish();
158
159 // Create render pass and call ExecuteBundles()
160 wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
161 utils::ComboRenderPassDescriptor passDescriptor = CreateRenderPassDescriptor(
162 kFormat, depthStencilReadOnlyInPass, depthStencilReadOnlyInPass);
163 wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&passDescriptor);
164 pass.ExecuteBundles(1, &bundle);
165 pass.EndPass();
Yunchao He0994bbe2021-11-10 02:06:05 +0000166 if (!depthStencilReadOnlyInPass || depthStencilReadOnlyInBundle) {
Yunchao Hed2c9cd32021-10-19 21:10:23 +0000167 encoder.Finish();
Yunchao He0994bbe2021-11-10 02:06:05 +0000168 } else {
169 ASSERT_DEVICE_ERROR(encoder.Finish());
Yunchao Hed2c9cd32021-10-19 21:10:23 +0000170 }
171 }
172 }
173 }
174 }
175
Yunchao Hedaffd222021-10-14 04:09:21 +0000176 // TODO(dawn:485): add more tests. For example:
Yunchao Hedaffd222021-10-14 04:09:21 +0000177 // - depth/stencil attachment should be designated if depth/stencil test is enabled.
178 // - pipeline and pass compatibility tests for color attachment(s).
179 // - pipeline and pass compatibility tests for compute.
180
181} // anonymous namespace