1 // Copyright 2019 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
15 #include "tests/unittests/validation/ValidationTest.h"
16
17 #include "utils/WGPUHelpers.h"
18
19 class DebugMarkerValidationTest : public ValidationTest {};
20
21 // Correct usage of debug markers should succeed in render pass.
TEST_F(DebugMarkerValidationTest,RenderSuccess)22 TEST_F(DebugMarkerValidationTest, RenderSuccess) {
23 DummyRenderPass renderPass(device);
24
25 wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
26 {
27 wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
28 pass.PushDebugGroup("Event Start");
29 pass.PushDebugGroup("Event Start");
30 pass.InsertDebugMarker("Marker");
31 pass.PopDebugGroup();
32 pass.PopDebugGroup();
33 pass.EndPass();
34 }
35
36 encoder.Finish();
37 }
38
39 // A PushDebugGroup call without a following PopDebugGroup produces an error in render pass.
TEST_F(DebugMarkerValidationTest,RenderUnbalancedPush)40 TEST_F(DebugMarkerValidationTest, RenderUnbalancedPush) {
41 DummyRenderPass renderPass(device);
42
43 wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
44 {
45 wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
46 pass.PushDebugGroup("Event Start");
47 pass.PushDebugGroup("Event Start");
48 pass.InsertDebugMarker("Marker");
49 pass.PopDebugGroup();
50 pass.EndPass();
51 }
52
53 ASSERT_DEVICE_ERROR(encoder.Finish());
54 }
55
56 // A PopDebugGroup call without a preceding PushDebugGroup produces an error in render pass.
TEST_F(DebugMarkerValidationTest,RenderUnbalancedPop)57 TEST_F(DebugMarkerValidationTest, RenderUnbalancedPop) {
58 DummyRenderPass renderPass(device);
59
60 wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
61 {
62 wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
63 pass.PushDebugGroup("Event Start");
64 pass.InsertDebugMarker("Marker");
65 pass.PopDebugGroup();
66 pass.PopDebugGroup();
67 pass.EndPass();
68 }
69
70 ASSERT_DEVICE_ERROR(encoder.Finish());
71 }
72
73 // Correct usage of debug markers should succeed in compute pass.
TEST_F(DebugMarkerValidationTest,ComputeSuccess)74 TEST_F(DebugMarkerValidationTest, ComputeSuccess) {
75 wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
76 {
77 wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
78 pass.PushDebugGroup("Event Start");
79 pass.PushDebugGroup("Event Start");
80 pass.InsertDebugMarker("Marker");
81 pass.PopDebugGroup();
82 pass.PopDebugGroup();
83 pass.EndPass();
84 }
85
86 encoder.Finish();
87 }
88
89 // A PushDebugGroup call without a following PopDebugGroup produces an error in compute pass.
TEST_F(DebugMarkerValidationTest,ComputeUnbalancedPush)90 TEST_F(DebugMarkerValidationTest, ComputeUnbalancedPush) {
91 wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
92 {
93 wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
94 pass.PushDebugGroup("Event Start");
95 pass.PushDebugGroup("Event Start");
96 pass.InsertDebugMarker("Marker");
97 pass.PopDebugGroup();
98 pass.EndPass();
99 }
100
101 ASSERT_DEVICE_ERROR(encoder.Finish());
102 }
103
104 // A PopDebugGroup call without a preceding PushDebugGroup produces an error in compute pass.
TEST_F(DebugMarkerValidationTest,ComputeUnbalancedPop)105 TEST_F(DebugMarkerValidationTest, ComputeUnbalancedPop) {
106 wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
107 {
108 wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
109 pass.PushDebugGroup("Event Start");
110 pass.InsertDebugMarker("Marker");
111 pass.PopDebugGroup();
112 pass.PopDebugGroup();
113 pass.EndPass();
114 }
115
116 ASSERT_DEVICE_ERROR(encoder.Finish());
117 }
118
119 // Correct usage of debug markers should succeed in command encoder.
TEST_F(DebugMarkerValidationTest,CommandEncoderSuccess)120 TEST_F(DebugMarkerValidationTest, CommandEncoderSuccess) {
121 wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
122 encoder.PushDebugGroup("Event Start");
123 encoder.PushDebugGroup("Event Start");
124 encoder.InsertDebugMarker("Marker");
125 encoder.PopDebugGroup();
126 encoder.PopDebugGroup();
127 encoder.Finish();
128 }
129
130 // A PushDebugGroup call without a following PopDebugGroup produces an error in command encoder.
TEST_F(DebugMarkerValidationTest,CommandEncoderUnbalancedPush)131 TEST_F(DebugMarkerValidationTest, CommandEncoderUnbalancedPush) {
132 wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
133 encoder.PushDebugGroup("Event Start");
134 encoder.PushDebugGroup("Event Start");
135 encoder.InsertDebugMarker("Marker");
136 encoder.PopDebugGroup();
137 ASSERT_DEVICE_ERROR(encoder.Finish());
138 }
139
140 // A PopDebugGroup call without a preceding PushDebugGroup produces an error in command encoder.
TEST_F(DebugMarkerValidationTest,CommandEncoderUnbalancedPop)141 TEST_F(DebugMarkerValidationTest, CommandEncoderUnbalancedPop) {
142 wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
143 encoder.PushDebugGroup("Event Start");
144 encoder.InsertDebugMarker("Marker");
145 encoder.PopDebugGroup();
146 encoder.PopDebugGroup();
147 ASSERT_DEVICE_ERROR(encoder.Finish());
148 }
149
150 // It is possible to nested pushes in a compute pass in a command encoder.
TEST_F(DebugMarkerValidationTest,NestedComputeInCommandEncoder)151 TEST_F(DebugMarkerValidationTest, NestedComputeInCommandEncoder) {
152 wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
153 encoder.PushDebugGroup("Event Start");
154 {
155 wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
156 pass.PushDebugGroup("Event Start");
157 pass.InsertDebugMarker("Marker");
158 pass.PopDebugGroup();
159 pass.EndPass();
160 }
161 encoder.PopDebugGroup();
162 encoder.Finish();
163 }
164
165 // Command encoder and compute pass pushes must be balanced independently.
TEST_F(DebugMarkerValidationTest,NestedComputeInCommandEncoderIndependent)166 TEST_F(DebugMarkerValidationTest, NestedComputeInCommandEncoderIndependent) {
167 wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
168 encoder.PushDebugGroup("Event Start");
169 {
170 wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
171 pass.InsertDebugMarker("Marker");
172 pass.PopDebugGroup();
173 pass.EndPass();
174 }
175 ASSERT_DEVICE_ERROR(encoder.Finish());
176 }
177
178 // It is possible to nested pushes in a render pass in a command encoder.
TEST_F(DebugMarkerValidationTest,NestedRenderInCommandEncoder)179 TEST_F(DebugMarkerValidationTest, NestedRenderInCommandEncoder) {
180 DummyRenderPass renderPass(device);
181
182 wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
183 encoder.PushDebugGroup("Event Start");
184 {
185 wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
186 pass.PushDebugGroup("Event Start");
187 pass.InsertDebugMarker("Marker");
188 pass.PopDebugGroup();
189 pass.EndPass();
190 }
191 encoder.PopDebugGroup();
192 encoder.Finish();
193 }
194
195 // Command encoder and render pass pushes must be balanced independently.
TEST_F(DebugMarkerValidationTest,NestedRenderInCommandEncoderIndependent)196 TEST_F(DebugMarkerValidationTest, NestedRenderInCommandEncoderIndependent) {
197 DummyRenderPass renderPass(device);
198
199 wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
200 encoder.PushDebugGroup("Event Start");
201 {
202 wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
203 pass.InsertDebugMarker("Marker");
204 pass.PopDebugGroup();
205 pass.EndPass();
206 }
207 ASSERT_DEVICE_ERROR(encoder.Finish());
208 }
209