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/DawnTest.h"
16
17 #include "utils/ComboRenderPipelineDescriptor.h"
18 #include "utils/DawnHelpers.h"
19
20 class TextureZeroInitTest : public DawnTest {
21 protected:
SetUp()22 void SetUp() override {
23 DawnTest::SetUp();
24 }
CreateTextureDescriptor(uint32_t mipLevelCount,uint32_t arrayLayerCount,dawn::TextureUsageBit usage,dawn::TextureFormat format)25 dawn::TextureDescriptor CreateTextureDescriptor(uint32_t mipLevelCount,
26 uint32_t arrayLayerCount,
27 dawn::TextureUsageBit usage,
28 dawn::TextureFormat format) {
29 dawn::TextureDescriptor descriptor;
30 descriptor.dimension = dawn::TextureDimension::e2D;
31 descriptor.size.width = kSize;
32 descriptor.size.height = kSize;
33 descriptor.size.depth = 1;
34 descriptor.arrayLayerCount = arrayLayerCount;
35 descriptor.sampleCount = 1;
36 descriptor.format = format;
37 descriptor.mipLevelCount = mipLevelCount;
38 descriptor.usage = usage;
39 return descriptor;
40 }
CreateTextureViewDescriptor(uint32_t baseMipLevel,uint32_t baseArrayLayer)41 dawn::TextureViewDescriptor CreateTextureViewDescriptor(uint32_t baseMipLevel,
42 uint32_t baseArrayLayer) {
43 dawn::TextureViewDescriptor descriptor;
44 descriptor.format = kColorFormat;
45 descriptor.baseArrayLayer = baseArrayLayer;
46 descriptor.arrayLayerCount = 1;
47 descriptor.baseMipLevel = baseMipLevel;
48 descriptor.mipLevelCount = 1;
49 descriptor.dimension = dawn::TextureViewDimension::e2D;
50 return descriptor;
51 }
CreatePipelineForTest()52 dawn::RenderPipeline CreatePipelineForTest() {
53 utils::ComboRenderPipelineDescriptor pipelineDescriptor(device);
54 const char* vs =
55 R"(#version 450
56 const vec2 pos[6] = vec2[6](vec2(-1.0f, -1.0f),
57 vec2(-1.0f, 1.0f),
58 vec2( 1.0f, -1.0f),
59 vec2( 1.0f, 1.0f),
60 vec2(-1.0f, 1.0f),
61 vec2( 1.0f, -1.0f)
62 );
63
64 void main() {
65 gl_Position = vec4(pos[gl_VertexIndex], 0.0, 1.0);
66 })";
67 pipelineDescriptor.cVertexStage.module =
68 utils::CreateShaderModule(device, utils::ShaderStage::Vertex, vs);
69
70 const char* fs =
71 R"(#version 450
72 layout(location = 0) out vec4 fragColor;
73 void main() {
74 fragColor = vec4(1.0, 0.0, 0.0, 1.0);
75 })";
76 pipelineDescriptor.cFragmentStage.module =
77 utils::CreateShaderModule(device, utils::ShaderStage::Fragment, fs);
78
79 pipelineDescriptor.cDepthStencilState.depthCompare = dawn::CompareFunction::Equal;
80 pipelineDescriptor.cDepthStencilState.stencilFront.compare = dawn::CompareFunction::Equal;
81 pipelineDescriptor.depthStencilState = &pipelineDescriptor.cDepthStencilState;
82
83 return device.CreateRenderPipeline(&pipelineDescriptor);
84 }
85 constexpr static uint32_t kSize = 128;
86 constexpr static dawn::TextureFormat kColorFormat = dawn::TextureFormat::RGBA8Unorm;
87 constexpr static dawn::TextureFormat kDepthStencilFormat =
88 dawn::TextureFormat::Depth24PlusStencil8;
89 };
90
91 // This tests that the code path of CopyTextureToBuffer clears correctly to Zero after first usage
TEST_P(TextureZeroInitTest,CopyTextureToBufferSource)92 TEST_P(TextureZeroInitTest, CopyTextureToBufferSource) {
93 dawn::TextureDescriptor descriptor = CreateTextureDescriptor(
94 1, 1, dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::CopySrc,
95 kColorFormat);
96 dawn::Texture texture = device.CreateTexture(&descriptor);
97
98 // Texture's first usage is in EXPECT_PIXEL_RGBA8_EQ's call to CopyTextureToBuffer
99 RGBA8 filledWithZeros(0, 0, 0, 0);
100 EXPECT_PIXEL_RGBA8_EQ(filledWithZeros, texture, 0, 0);
101 }
102
103 // Test that non-zero mip level clears subresource to Zero after first use
104 // This goes through the BeginRenderPass's code path
TEST_P(TextureZeroInitTest,RenderingMipMapClearsToZero)105 TEST_P(TextureZeroInitTest, RenderingMipMapClearsToZero) {
106 dawn::TextureDescriptor descriptor = CreateTextureDescriptor(
107 4, 1, dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::CopySrc,
108 kColorFormat);
109 dawn::Texture texture = device.CreateTexture(&descriptor);
110
111 dawn::TextureViewDescriptor viewDescriptor = CreateTextureViewDescriptor(2, 0);
112 dawn::TextureView view = texture.CreateView(&viewDescriptor);
113
114 utils::BasicRenderPass renderPass = utils::BasicRenderPass(kSize, kSize, texture, kColorFormat);
115
116 renderPass.renderPassInfo.cColorAttachmentsInfoPtr[0]->attachment = view;
117 dawn::CommandEncoder encoder = device.CreateCommandEncoder();
118 {
119 // Texture's first usage is in BeginRenderPass's call to RecordRenderPass
120 dawn::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo);
121 pass.EndPass();
122 }
123 dawn::CommandBuffer commands = encoder.Finish();
124 queue.Submit(1, &commands);
125
126 uint32_t mipSize = kSize >> 2;
127 std::vector<RGBA8> expected(mipSize * mipSize, {0, 0, 0, 0});
128
129 EXPECT_TEXTURE_RGBA8_EQ(expected.data(), renderPass.color, 0, 0, mipSize, mipSize, 2, 0);
130 }
131
132 // Test that non-zero array layers clears subresource to Zero after first use.
133 // This goes through the BeginRenderPass's code path
TEST_P(TextureZeroInitTest,RenderingArrayLayerClearsToZero)134 TEST_P(TextureZeroInitTest, RenderingArrayLayerClearsToZero) {
135 dawn::TextureDescriptor descriptor = CreateTextureDescriptor(
136 1, 4, dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::CopySrc,
137 kColorFormat);
138 dawn::Texture texture = device.CreateTexture(&descriptor);
139
140 dawn::TextureViewDescriptor viewDescriptor = CreateTextureViewDescriptor(0, 2);
141 dawn::TextureView view = texture.CreateView(&viewDescriptor);
142
143 utils::BasicRenderPass renderPass = utils::BasicRenderPass(kSize, kSize, texture, kColorFormat);
144
145 renderPass.renderPassInfo.cColorAttachmentsInfoPtr[0]->attachment = view;
146 dawn::CommandEncoder encoder = device.CreateCommandEncoder();
147 {
148 dawn::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo);
149 pass.EndPass();
150 }
151 dawn::CommandBuffer commands = encoder.Finish();
152 queue.Submit(1, &commands);
153
154 std::vector<RGBA8> expected(kSize * kSize, {0, 0, 0, 0});
155
156 EXPECT_TEXTURE_RGBA8_EQ(expected.data(), renderPass.color, 0, 0, kSize, kSize, 0, 2);
157 }
158
159 // This tests CopyBufferToTexture fully overwrites copy so lazy init is not needed.
160 // TODO(natlee@microsoft.com): Add backdoor to dawn native to query the number of zero-inited
161 // subresources
TEST_P(TextureZeroInitTest,CopyBufferToTexture)162 TEST_P(TextureZeroInitTest, CopyBufferToTexture) {
163 dawn::TextureDescriptor descriptor =
164 CreateTextureDescriptor(4, 1,
165 dawn::TextureUsageBit::CopyDst | dawn::TextureUsageBit::Sampled |
166 dawn::TextureUsageBit::CopySrc,
167 kColorFormat);
168 dawn::Texture texture = device.CreateTexture(&descriptor);
169
170 std::vector<uint8_t> data(4 * kSize * kSize, 100);
171 dawn::Buffer stagingBuffer = utils::CreateBufferFromData(
172 device, data.data(), static_cast<uint32_t>(data.size()), dawn::BufferUsageBit::CopySrc);
173
174 dawn::BufferCopyView bufferCopyView = utils::CreateBufferCopyView(stagingBuffer, 0, 0, 0);
175 dawn::TextureCopyView textureCopyView = utils::CreateTextureCopyView(texture, 0, 0, {0, 0, 0});
176 dawn::Extent3D copySize = {kSize, kSize, 1};
177
178 dawn::CommandEncoder encoder = device.CreateCommandEncoder();
179 encoder.CopyBufferToTexture(&bufferCopyView, &textureCopyView, ©Size);
180 dawn::CommandBuffer commands = encoder.Finish();
181 queue.Submit(1, &commands);
182
183 std::vector<RGBA8> expected(kSize * kSize, {100, 100, 100, 100});
184
185 EXPECT_TEXTURE_RGBA8_EQ(expected.data(), texture, 0, 0, kSize, kSize, 0, 0);
186 }
187
188 // Test for a copy only to a subset of the subresource, lazy init is necessary to clear the other
189 // half.
TEST_P(TextureZeroInitTest,CopyBufferToTextureHalf)190 TEST_P(TextureZeroInitTest, CopyBufferToTextureHalf) {
191 dawn::TextureDescriptor descriptor =
192 CreateTextureDescriptor(4, 1,
193 dawn::TextureUsageBit::CopyDst | dawn::TextureUsageBit::Sampled |
194 dawn::TextureUsageBit::CopySrc,
195 kColorFormat);
196 dawn::Texture texture = device.CreateTexture(&descriptor);
197
198 std::vector<uint8_t> data(4 * kSize * kSize, 100);
199 dawn::Buffer stagingBuffer = utils::CreateBufferFromData(
200 device, data.data(), static_cast<uint32_t>(data.size()), dawn::BufferUsageBit::CopySrc);
201
202 dawn::BufferCopyView bufferCopyView = utils::CreateBufferCopyView(stagingBuffer, 0, 0, 0);
203 dawn::TextureCopyView textureCopyView = utils::CreateTextureCopyView(texture, 0, 0, {0, 0, 0});
204 dawn::Extent3D copySize = {kSize / 2, kSize, 1};
205
206 dawn::CommandEncoder encoder = device.CreateCommandEncoder();
207 encoder.CopyBufferToTexture(&bufferCopyView, &textureCopyView, ©Size);
208 dawn::CommandBuffer commands = encoder.Finish();
209 queue.Submit(1, &commands);
210
211 std::vector<RGBA8> expected100((kSize / 2) * kSize, {100, 100, 100, 100});
212 std::vector<RGBA8> expectedZeros((kSize / 2) * kSize, {0, 0, 0, 0});
213 // first half filled with 100, by the buffer data
214 EXPECT_TEXTURE_RGBA8_EQ(expected100.data(), texture, 0, 0, kSize / 2, kSize, 0, 0);
215 // second half should be cleared
216 EXPECT_TEXTURE_RGBA8_EQ(expectedZeros.data(), texture, kSize / 2, 0, kSize / 2, kSize, 0, 0);
217 }
218
219 // This tests CopyTextureToTexture fully overwrites copy so lazy init is not needed.
TEST_P(TextureZeroInitTest,CopyTextureToTexture)220 TEST_P(TextureZeroInitTest, CopyTextureToTexture) {
221 dawn::TextureDescriptor srcDescriptor = CreateTextureDescriptor(
222 1, 1, dawn::TextureUsageBit::Sampled | dawn::TextureUsageBit::CopySrc, kColorFormat);
223 dawn::Texture srcTexture = device.CreateTexture(&srcDescriptor);
224
225 dawn::TextureCopyView srcTextureCopyView =
226 utils::CreateTextureCopyView(srcTexture, 0, 0, {0, 0, 0});
227
228 dawn::TextureDescriptor dstDescriptor =
229 CreateTextureDescriptor(1, 1,
230 dawn::TextureUsageBit::OutputAttachment |
231 dawn::TextureUsageBit::CopyDst | dawn::TextureUsageBit::CopySrc,
232 kColorFormat);
233 dawn::Texture dstTexture = device.CreateTexture(&dstDescriptor);
234
235 dawn::TextureCopyView dstTextureCopyView =
236 utils::CreateTextureCopyView(dstTexture, 0, 0, {0, 0, 0});
237
238 dawn::Extent3D copySize = {kSize, kSize, 1};
239
240 dawn::CommandEncoder encoder = device.CreateCommandEncoder();
241 encoder.CopyTextureToTexture(&srcTextureCopyView, &dstTextureCopyView, ©Size);
242 dawn::CommandBuffer commands = encoder.Finish();
243 queue.Submit(1, &commands);
244
245 std::vector<RGBA8> expected(kSize * kSize, {0, 0, 0, 0});
246
247 EXPECT_TEXTURE_RGBA8_EQ(expected.data(), srcTexture, 0, 0, kSize, kSize, 0, 0);
248 EXPECT_TEXTURE_RGBA8_EQ(expected.data(), dstTexture, 0, 0, kSize, kSize, 0, 0);
249 }
250
251 // This Tests the CopyTextureToTexture's copy only to a subset of the subresource, lazy init is
252 // necessary to clear the other half.
TEST_P(TextureZeroInitTest,CopyTextureToTextureHalf)253 TEST_P(TextureZeroInitTest, CopyTextureToTextureHalf) {
254 dawn::TextureDescriptor srcDescriptor =
255 CreateTextureDescriptor(1, 1,
256 dawn::TextureUsageBit::Sampled | dawn::TextureUsageBit::CopySrc |
257 dawn::TextureUsageBit::CopyDst,
258 kColorFormat);
259 dawn::Texture srcTexture = device.CreateTexture(&srcDescriptor);
260
261 // fill srcTexture with 100
262 {
263 std::vector<uint8_t> data(4 * kSize * kSize, 100);
264 dawn::Buffer stagingBuffer = utils::CreateBufferFromData(
265 device, data.data(), static_cast<uint32_t>(data.size()), dawn::BufferUsageBit::CopySrc);
266 dawn::BufferCopyView bufferCopyView = utils::CreateBufferCopyView(stagingBuffer, 0, 0, 0);
267 dawn::TextureCopyView textureCopyView =
268 utils::CreateTextureCopyView(srcTexture, 0, 0, {0, 0, 0});
269 dawn::Extent3D copySize = {kSize, kSize, 1};
270 dawn::CommandEncoder encoder = device.CreateCommandEncoder();
271 encoder.CopyBufferToTexture(&bufferCopyView, &textureCopyView, ©Size);
272 dawn::CommandBuffer commands = encoder.Finish();
273 queue.Submit(1, &commands);
274 }
275
276 dawn::TextureCopyView srcTextureCopyView =
277 utils::CreateTextureCopyView(srcTexture, 0, 0, {0, 0, 0});
278
279 dawn::TextureDescriptor dstDescriptor =
280 CreateTextureDescriptor(1, 1,
281 dawn::TextureUsageBit::OutputAttachment |
282 dawn::TextureUsageBit::CopyDst | dawn::TextureUsageBit::CopySrc,
283 kColorFormat);
284 dawn::Texture dstTexture = device.CreateTexture(&dstDescriptor);
285
286 dawn::TextureCopyView dstTextureCopyView =
287 utils::CreateTextureCopyView(dstTexture, 0, 0, {0, 0, 0});
288 dawn::Extent3D copySize = {kSize / 2, kSize, 1};
289
290 dawn::CommandEncoder encoder = device.CreateCommandEncoder();
291 encoder.CopyTextureToTexture(&srcTextureCopyView, &dstTextureCopyView, ©Size);
292 dawn::CommandBuffer commands = encoder.Finish();
293 queue.Submit(1, &commands);
294
295 std::vector<RGBA8> expectedWithZeros((kSize / 2) * kSize, {0, 0, 0, 0});
296 std::vector<RGBA8> expectedWith100(kSize * kSize, {100, 100, 100, 100});
297
298 EXPECT_TEXTURE_RGBA8_EQ(expectedWith100.data(), srcTexture, 0, 0, kSize, kSize, 0, 0);
299 EXPECT_TEXTURE_RGBA8_EQ(expectedWith100.data(), dstTexture, 0, 0, kSize / 2, kSize, 0, 0);
300 EXPECT_TEXTURE_RGBA8_EQ(expectedWithZeros.data(), dstTexture, kSize / 2, 0, kSize / 2, kSize, 0,
301 0);
302 }
303
304 // This tests the texture with depth attachment and load op load will init depth stencil texture to
305 // 0s.
TEST_P(TextureZeroInitTest,RenderingLoadingDepth)306 TEST_P(TextureZeroInitTest, RenderingLoadingDepth) {
307 dawn::TextureDescriptor srcDescriptor =
308 CreateTextureDescriptor(1, 1,
309 dawn::TextureUsageBit::CopySrc | dawn::TextureUsageBit::CopyDst |
310 dawn::TextureUsageBit::OutputAttachment,
311 kColorFormat);
312 dawn::Texture srcTexture = device.CreateTexture(&srcDescriptor);
313
314 dawn::TextureDescriptor depthStencilDescriptor = CreateTextureDescriptor(
315 1, 1, dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::CopySrc,
316 kDepthStencilFormat);
317 dawn::Texture depthStencilTexture = device.CreateTexture(&depthStencilDescriptor);
318
319 utils::ComboRenderPassDescriptor renderPassDescriptor({srcTexture.CreateDefaultView()},
320 depthStencilTexture.CreateDefaultView());
321 renderPassDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = dawn::LoadOp::Load;
322 renderPassDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = dawn::LoadOp::Clear;
323 renderPassDescriptor.cDepthStencilAttachmentInfo.clearStencil = 0;
324
325 dawn::CommandEncoder encoder = device.CreateCommandEncoder();
326 auto pass = encoder.BeginRenderPass(&renderPassDescriptor);
327 pass.SetPipeline(CreatePipelineForTest());
328 pass.Draw(6, 1, 0, 0);
329 pass.EndPass();
330 dawn::CommandBuffer commandBuffer = encoder.Finish();
331 queue.Submit(1, &commandBuffer);
332
333 // Expect the texture to be red because depth test passed.
334 std::vector<RGBA8> expected(kSize * kSize, {255, 0, 0, 255});
335 EXPECT_TEXTURE_RGBA8_EQ(expected.data(), srcTexture, 0, 0, kSize, kSize, 0, 0);
336 }
337
338 // This tests the texture with stencil attachment and load op load will init depth stencil texture
339 // to 0s.
TEST_P(TextureZeroInitTest,RenderingLoadingStencil)340 TEST_P(TextureZeroInitTest, RenderingLoadingStencil) {
341 dawn::TextureDescriptor srcDescriptor =
342 CreateTextureDescriptor(1, 1,
343 dawn::TextureUsageBit::CopySrc | dawn::TextureUsageBit::CopyDst |
344 dawn::TextureUsageBit::OutputAttachment,
345 kColorFormat);
346 dawn::Texture srcTexture = device.CreateTexture(&srcDescriptor);
347
348 dawn::TextureDescriptor depthStencilDescriptor = CreateTextureDescriptor(
349 1, 1, dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::CopySrc,
350 kDepthStencilFormat);
351 dawn::Texture depthStencilTexture = device.CreateTexture(&depthStencilDescriptor);
352
353 utils::ComboRenderPassDescriptor renderPassDescriptor({srcTexture.CreateDefaultView()},
354 depthStencilTexture.CreateDefaultView());
355 renderPassDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = dawn::LoadOp::Clear;
356 renderPassDescriptor.cDepthStencilAttachmentInfo.clearDepth = 0.0f;
357 renderPassDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = dawn::LoadOp::Load;
358
359 dawn::CommandEncoder encoder = device.CreateCommandEncoder();
360 auto pass = encoder.BeginRenderPass(&renderPassDescriptor);
361 pass.SetPipeline(CreatePipelineForTest());
362 pass.Draw(6, 1, 0, 0);
363 pass.EndPass();
364 dawn::CommandBuffer commandBuffer = encoder.Finish();
365 queue.Submit(1, &commandBuffer);
366
367 // Expect the texture to be red because stencil test passed.
368 std::vector<RGBA8> expected(kSize * kSize, {255, 0, 0, 255});
369 EXPECT_TEXTURE_RGBA8_EQ(expected.data(), srcTexture, 0, 0, kSize, kSize, 0, 0);
370 }
371
372 // This tests the texture with depth stencil attachment and load op load will init depth stencil
373 // texture to 0s.
TEST_P(TextureZeroInitTest,RenderingLoadingDepthStencil)374 TEST_P(TextureZeroInitTest, RenderingLoadingDepthStencil) {
375 dawn::TextureDescriptor srcDescriptor =
376 CreateTextureDescriptor(1, 1,
377 dawn::TextureUsageBit::CopySrc | dawn::TextureUsageBit::CopyDst |
378 dawn::TextureUsageBit::OutputAttachment,
379 kColorFormat);
380 dawn::Texture srcTexture = device.CreateTexture(&srcDescriptor);
381
382 dawn::TextureDescriptor depthStencilDescriptor = CreateTextureDescriptor(
383 1, 1, dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::CopySrc,
384 kDepthStencilFormat);
385 dawn::Texture depthStencilTexture = device.CreateTexture(&depthStencilDescriptor);
386
387 utils::ComboRenderPassDescriptor renderPassDescriptor({srcTexture.CreateDefaultView()},
388 depthStencilTexture.CreateDefaultView());
389 renderPassDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = dawn::LoadOp::Load;
390 renderPassDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = dawn::LoadOp::Load;
391
392 dawn::CommandEncoder encoder = device.CreateCommandEncoder();
393 auto pass = encoder.BeginRenderPass(&renderPassDescriptor);
394 pass.SetPipeline(CreatePipelineForTest());
395 pass.Draw(6, 1, 0, 0);
396 pass.EndPass();
397 dawn::CommandBuffer commandBuffer = encoder.Finish();
398 queue.Submit(1, &commandBuffer);
399
400 // Expect the texture to be red because both depth and stencil tests passed.
401 std::vector<RGBA8> expected(kSize * kSize, {255, 0, 0, 255});
402 EXPECT_TEXTURE_RGBA8_EQ(expected.data(), srcTexture, 0, 0, kSize, kSize, 0, 0);
403 }
404
405 // This tests the color attachments clear to 0s
TEST_P(TextureZeroInitTest,ColorAttachmentsClear)406 TEST_P(TextureZeroInitTest, ColorAttachmentsClear) {
407 dawn::TextureDescriptor descriptor = CreateTextureDescriptor(
408 1, 1, dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::CopySrc,
409 kColorFormat);
410 dawn::Texture texture = device.CreateTexture(&descriptor);
411 utils::BasicRenderPass renderPass = utils::BasicRenderPass(kSize, kSize, texture, kColorFormat);
412 renderPass.renderPassInfo.cColorAttachmentsInfoPtr[0]->loadOp = dawn::LoadOp::Load;
413
414 dawn::CommandEncoder encoder = device.CreateCommandEncoder();
415 {
416 dawn::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo);
417 pass.EndPass();
418 }
419 dawn::CommandBuffer commands = encoder.Finish();
420 queue.Submit(1, &commands);
421
422 std::vector<RGBA8> expected(kSize * kSize, {0, 0, 0, 0});
423 EXPECT_TEXTURE_RGBA8_EQ(expected.data(), renderPass.color, 0, 0, kSize, kSize, 0, 0);
424 }
425
426 DAWN_INSTANTIATE_TEST(
427 TextureZeroInitTest,
428 ForceWorkarounds(D3D12Backend, {"nonzero_clear_resources_on_creation_for_testing"}),
429 ForceWorkarounds(OpenGLBackend, {"nonzero_clear_resources_on_creation_for_testing"}),
430 ForceWorkarounds(VulkanBackend, {"nonzero_clear_resources_on_creation_for_testing"}));
431