blob: 72e02fc7cb03575458f280dc725d938a2abc56bf [file] [log] [blame]
Jeremy Gebben170781d2020-11-19 16:21:21 -07001/*
Jeremy Gebben5c1bb2d2021-02-15 08:58:04 -07002 * Copyright (c) 2015-2021 The Khronos Group Inc.
3 * Copyright (c) 2015-2021 Valve Corporation
4 * Copyright (c) 2015-2021 LunarG, Inc.
5 * Copyright (c) 2015-2021 Google, Inc.
Jeremy Gebben170781d2020-11-19 16:21:21 -07006 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Author: Chia-I Wu <olvaffe@gmail.com>
14 * Author: Chris Forbes <chrisf@ijw.co.nz>
15 * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
16 * Author: Mark Lobodzinski <mark@lunarg.com>
17 * Author: Mike Stroyan <mike@LunarG.com>
18 * Author: Tobin Ehlis <tobine@google.com>
19 * Author: Tony Barbour <tony@LunarG.com>
20 * Author: Cody Northrop <cnorthrop@google.com>
21 * Author: Dave Houlton <daveh@lunarg.com>
22 * Author: Jeremy Kniager <jeremyk@lunarg.com>
23 * Author: Shannon McPherson <shannon@lunarg.com>
24 * Author: John Zulauf <jzulauf@lunarg.com>
25 */
26#include <type_traits>
27
28#include "cast_utils.h"
29#include "layer_validation_tests.h"
30
31TEST_F(VkSyncValTest, SyncBufferCopyHazards) {
32 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
33 if (DeviceExtensionSupported(gpu(), nullptr, VK_AMD_BUFFER_MARKER_EXTENSION_NAME)) {
34 m_device_extension_names.push_back(VK_AMD_BUFFER_MARKER_EXTENSION_NAME);
35 }
36 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
37 bool has_amd_buffer_maker = DeviceExtensionEnabled(VK_AMD_BUFFER_MARKER_EXTENSION_NAME);
38
39 VkBufferObj buffer_a;
40 VkBufferObj buffer_b;
41 VkBufferObj buffer_c;
42 VkMemoryPropertyFlags mem_prop = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
43 buffer_a.init_as_src_and_dst(*m_device, 256, mem_prop);
44 buffer_b.init_as_src_and_dst(*m_device, 256, mem_prop);
45 buffer_c.init_as_src_and_dst(*m_device, 256, mem_prop);
46
47 VkBufferCopy region = {0, 0, 256};
48 VkBufferCopy front2front = {0, 0, 128};
49 VkBufferCopy front2back = {0, 128, 128};
50 VkBufferCopy back2back = {128, 128, 128};
51
52 auto cb = m_commandBuffer->handle();
53 m_commandBuffer->begin();
54
55 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &region);
56
57 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
58 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &region);
59 m_errorMonitor->VerifyFound();
60
61 // Use the barrier to clean up the WAW, and try again. (and show that validation is accounting for the barrier effect too.)
Mark Lobodzinski07d0a612020-12-30 15:42:31 -070062 auto buffer_barrier = LvlInitStruct<VkBufferMemoryBarrier>();
Jeremy Gebben170781d2020-11-19 16:21:21 -070063 buffer_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
64 buffer_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
65 buffer_barrier.buffer = buffer_a.handle();
66 buffer_barrier.offset = 0;
67 buffer_barrier.size = 256;
68 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, &buffer_barrier, 0,
69 nullptr);
70
71 m_errorMonitor->ExpectSuccess();
72 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &front2front);
73 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &back2back);
74 m_errorMonitor->VerifyNotFound();
75
76 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
77 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &front2back);
78 m_errorMonitor->VerifyFound();
79
80 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
81 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_b.handle(), 1, &region);
82 m_errorMonitor->VerifyFound();
83
84 // NOTE: Since the previous command skips in validation, the state update is never done, and the validation layer thus doesn't
85 // record the write operation to b. So we'll need to repeat it successfully to set up for the *next* test.
86
87 // Use the barrier to clean up the WAW, and try again. (and show that validation is accounting for the barrier effect too.)
Mark Lobodzinski07d0a612020-12-30 15:42:31 -070088 auto mem_barrier = LvlInitStruct<VkMemoryBarrier>();
Jeremy Gebben170781d2020-11-19 16:21:21 -070089 mem_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
90 mem_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
91 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1, &mem_barrier, 0, nullptr, 0,
92 nullptr);
93 m_errorMonitor->ExpectSuccess();
94
95 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_c.handle(), buffer_b.handle(), 1, &region);
96 m_errorMonitor->VerifyNotFound();
97
98 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
99 mem_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; // Protect C but not B
100 mem_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
101 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1, &mem_barrier, 0, nullptr, 0,
102 nullptr);
103 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_b.handle(), buffer_c.handle(), 1, &region);
104 m_errorMonitor->VerifyFound();
105
106 m_commandBuffer->end();
107
108 // CmdFillBuffer
109 m_errorMonitor->ExpectSuccess();
110 m_commandBuffer->reset();
111 m_commandBuffer->begin();
112 vk::CmdFillBuffer(m_commandBuffer->handle(), buffer_a.handle(), 0, 256, 1);
113 m_commandBuffer->end();
114 m_errorMonitor->VerifyNotFound();
115
116 m_commandBuffer->reset();
117 m_commandBuffer->begin();
118 vk::CmdCopyBuffer(cb, buffer_b.handle(), buffer_a.handle(), 1, &region);
119 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
120 vk::CmdFillBuffer(m_commandBuffer->handle(), buffer_a.handle(), 0, 256, 1);
121 m_errorMonitor->VerifyFound();
122 m_commandBuffer->end();
123
124 // CmdUpdateBuffer
125 int i = 10;
126 m_errorMonitor->ExpectSuccess();
127 m_commandBuffer->reset();
128 m_commandBuffer->begin();
129 vk::CmdUpdateBuffer(m_commandBuffer->handle(), buffer_a.handle(), 0, sizeof(i), &i);
130 m_commandBuffer->end();
131 m_errorMonitor->VerifyNotFound();
132
133 m_commandBuffer->reset();
134 m_commandBuffer->begin();
135 vk::CmdCopyBuffer(cb, buffer_b.handle(), buffer_a.handle(), 1, &region);
136 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
137 vk::CmdUpdateBuffer(m_commandBuffer->handle(), buffer_a.handle(), 0, sizeof(i), &i);
138 m_errorMonitor->VerifyFound();
139 m_commandBuffer->end();
140
John Zulaufcbf67cf2021-04-26 21:06:32 -0600141 // Create secondary buffers to use
John Zulaufee17cce2021-04-15 18:21:38 -0600142 m_errorMonitor->ExpectSuccess();
John Zulaufcbf67cf2021-04-26 21:06:32 -0600143 VkCommandBufferObj secondary_cb1(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
144 VkCommandBuffer scb1 = secondary_cb1.handle();
145 secondary_cb1.begin();
146 vk::CmdCopyBuffer(scb1, buffer_c.handle(), buffer_a.handle(), 1, &front2front);
147 secondary_cb1.end();
148 m_errorMonitor->VerifyNotFound();
149
150 m_errorMonitor->ExpectSuccess();
151 VkCommandBufferObj secondary_cb2(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
152 VkCommandBuffer scb2 = secondary_cb2.handle();
153 secondary_cb2.begin();
154 vk::CmdCopyBuffer(scb2, buffer_a.handle(), buffer_c.handle(), 1, &front2front);
155 secondary_cb2.end();
156 m_errorMonitor->VerifyNotFound();
157
158 m_errorMonitor->ExpectSuccess();
159 VkCommandBufferObj secondary_cb3(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
160 VkCommandBuffer scb3 = secondary_cb3.handle();
161 secondary_cb3.begin();
162 secondary_cb3.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 0,
163 nullptr);
164 secondary_cb3.end();
165 m_errorMonitor->VerifyNotFound();
166
167 m_errorMonitor->ExpectSuccess();
168 VkCommandBufferObj secondary_cb4(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
169 VkCommandBuffer scb4 = secondary_cb4.handle();
170 secondary_cb4.begin();
171 vk::CmdCopyBuffer(scb4, buffer_b.handle(), buffer_c.handle(), 1, &front2front);
172 secondary_cb4.end();
173 m_errorMonitor->VerifyNotFound();
174
175 // One secondary CB hazard with active command buffer
176 m_errorMonitor->ExpectSuccess();
John Zulaufee17cce2021-04-15 18:21:38 -0600177 m_commandBuffer->reset();
178 m_commandBuffer->begin();
179 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &front2front);
180 m_errorMonitor->VerifyNotFound();
181 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
John Zulaufcbf67cf2021-04-26 21:06:32 -0600182 vk::CmdExecuteCommands(cb, 1, &scb1);
John Zulaufee17cce2021-04-15 18:21:38 -0600183 m_errorMonitor->VerifyFound();
184 m_commandBuffer->end();
185
John Zulaufcbf67cf2021-04-26 21:06:32 -0600186 // Two secondary CB hazard with each other
John Zulaufee17cce2021-04-15 18:21:38 -0600187 m_commandBuffer->reset();
John Zulaufcbf67cf2021-04-26 21:06:32 -0600188 m_commandBuffer->begin();
189 m_errorMonitor->VerifyNotFound();
190 // This is also a "SYNC-HAZARD-WRITE_AFTER_WRITE" present, but only the first hazard is reported.
191 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
192 {
193 VkCommandBuffer two_cbs[2] = {scb1, scb2};
194 vk::CmdExecuteCommands(cb, 2, two_cbs);
195 }
196 m_errorMonitor->VerifyFound();
197 m_commandBuffer->end();
John Zulaufee17cce2021-04-15 18:21:38 -0600198
John Zulaufcbf67cf2021-04-26 21:06:32 -0600199 // Two secondary CB hazard with each other
200 m_commandBuffer->reset();
201 m_commandBuffer->begin();
202 m_errorMonitor->VerifyNotFound();
203 {
204 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
205 VkCommandBuffer two_cbs[2] = {scb1, scb4};
206 vk::CmdExecuteCommands(cb, 2, two_cbs);
207 m_errorMonitor->VerifyFound();
208 }
209 m_commandBuffer->end();
210
211 // Add a secondary CB with a barrier
212 m_commandBuffer->reset();
213 m_commandBuffer->begin();
214 {
215 m_errorMonitor->ExpectSuccess();
216 VkCommandBuffer three_cbs[3] = {scb1, scb3, scb4};
217 vk::CmdExecuteCommands(cb, 3, three_cbs);
218 m_errorMonitor->VerifyNotFound();
219 }
220 m_commandBuffer->end();
221
222 m_commandBuffer->reset();
Jeremy Gebben170781d2020-11-19 16:21:21 -0700223 // CmdWriteBufferMarkerAMD
224 if (has_amd_buffer_maker) {
225 auto fpCmdWriteBufferMarkerAMD =
226 (PFN_vkCmdWriteBufferMarkerAMD)vk::GetDeviceProcAddr(m_device->device(), "vkCmdWriteBufferMarkerAMD");
227 if (!fpCmdWriteBufferMarkerAMD) {
228 printf("%s Test requires unsupported vkCmdWriteBufferMarkerAMD feature. Skipped.\n", kSkipPrefix);
229 } else {
230 m_errorMonitor->ExpectSuccess();
231 m_commandBuffer->reset();
232 m_commandBuffer->begin();
233 fpCmdWriteBufferMarkerAMD(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, buffer_a.handle(), 0, 1);
234 m_commandBuffer->end();
235 m_errorMonitor->VerifyNotFound();
236
237 m_commandBuffer->reset();
238 m_commandBuffer->begin();
239 vk::CmdCopyBuffer(cb, buffer_b.handle(), buffer_a.handle(), 1, &region);
240 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
241 fpCmdWriteBufferMarkerAMD(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, buffer_a.handle(), 0, 1);
242 m_errorMonitor->VerifyFound();
243 m_commandBuffer->end();
244 }
245 } else {
246 printf("%s Test requires unsupported vkCmdWriteBufferMarkerAMD feature. Skipped.\n", kSkipPrefix);
247 }
248}
249
Jeremy Gebben5c1bb2d2021-02-15 08:58:04 -0700250TEST_F(VkSyncValTest, Sync2BufferCopyHazards) {
251 SetTargetApiVersion(VK_API_VERSION_1_2);
252 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
253 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME)) {
254 m_device_extension_names.push_back(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME);
255 } else {
256 printf("%s Synchronization2 not supported, skipping test\n", kSkipPrefix);
257 return;
258 }
259
260 if (!CheckSynchronization2SupportAndInitState(this)) {
261 printf("%s Synchronization2 not supported, skipping test\n", kSkipPrefix);
262 return;
263 }
264 auto fpCmdPipelineBarrier2KHR = (PFN_vkCmdPipelineBarrier2KHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdPipelineBarrier2KHR");
265
266 VkBufferObj buffer_a;
267 VkBufferObj buffer_b;
268 VkBufferObj buffer_c;
269 VkMemoryPropertyFlags mem_prop = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
270 buffer_a.init_as_src_and_dst(*m_device, 256, mem_prop);
271 buffer_b.init_as_src_and_dst(*m_device, 256, mem_prop);
272 buffer_c.init_as_src_and_dst(*m_device, 256, mem_prop);
273
274 VkBufferCopy region = {0, 0, 256};
275 VkBufferCopy front2front = {0, 0, 128};
276 VkBufferCopy front2back = {0, 128, 128};
277 VkBufferCopy back2back = {128, 128, 128};
278
279 auto cb = m_commandBuffer->handle();
280 m_commandBuffer->begin();
281
282 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &region);
283
284 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
285 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &region);
286 m_errorMonitor->VerifyFound();
287
288 // Use the barrier to clean up the WAW, and try again. (and show that validation is accounting for the barrier effect too.)
289 {
290 auto buffer_barrier = lvl_init_struct<VkBufferMemoryBarrier2KHR>();
291 buffer_barrier.srcStageMask = VK_PIPELINE_STAGE_2_COPY_BIT_KHR;
292 buffer_barrier.dstStageMask = VK_PIPELINE_STAGE_2_COPY_BIT_KHR;
293 buffer_barrier.srcAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT_KHR;
294 buffer_barrier.dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR;
295 buffer_barrier.buffer = buffer_a.handle();
296 buffer_barrier.offset = 0;
297 buffer_barrier.size = 256;
298 auto dep_info = lvl_init_struct<VkDependencyInfoKHR>();
299 dep_info.bufferMemoryBarrierCount = 1;
300 dep_info.pBufferMemoryBarriers = &buffer_barrier;
301 fpCmdPipelineBarrier2KHR(cb, &dep_info);
302 }
303
304 m_errorMonitor->ExpectSuccess();
305 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &front2front);
306 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &back2back);
307 m_errorMonitor->VerifyNotFound();
308
309 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
310 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &front2back);
311 m_errorMonitor->VerifyFound();
312
313 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
314 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_b.handle(), 1, &region);
315 m_errorMonitor->VerifyFound();
316
317 // NOTE: Since the previous command skips in validation, the state update is never done, and the validation layer thus doesn't
318 // record the write operation to b. So we'll need to repeat it successfully to set up for the *next* test.
319
320 // Use the barrier to clean up the WAW, and try again. (and show that validation is accounting for the barrier effect too.)
321 {
322 auto mem_barrier = lvl_init_struct<VkMemoryBarrier2KHR>();
323 mem_barrier.srcStageMask = VK_PIPELINE_STAGE_2_COPY_BIT_KHR;
324 mem_barrier.dstStageMask = VK_PIPELINE_STAGE_2_COPY_BIT_KHR;
325 mem_barrier.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR;
326 mem_barrier.dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR;
327 auto dep_info = lvl_init_struct<VkDependencyInfoKHR>();
328 dep_info.memoryBarrierCount = 1;
329 dep_info.pMemoryBarriers = &mem_barrier;
330 fpCmdPipelineBarrier2KHR(cb, &dep_info);
331 m_errorMonitor->ExpectSuccess();
332
333 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_c.handle(), buffer_b.handle(), 1, &region);
334 m_errorMonitor->VerifyNotFound();
335
336 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
337 mem_barrier.srcAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT_KHR; // Protect C but not B
338 mem_barrier.dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR;
339 fpCmdPipelineBarrier2KHR(cb, &dep_info);
340 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_b.handle(), buffer_c.handle(), 1, &region);
341 m_errorMonitor->VerifyFound();
342
343 m_commandBuffer->end();
344 }
345}
346
Jeremy Gebben170781d2020-11-19 16:21:21 -0700347TEST_F(VkSyncValTest, SyncCopyOptimalImageHazards) {
348 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
349 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
350
351 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
352 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
353 VkImageObj image_a(m_device);
354 auto image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 2, format, usage, VK_IMAGE_TILING_OPTIMAL);
355 image_a.Init(image_ci);
356 ASSERT_TRUE(image_a.initialized());
357
358 VkImageObj image_b(m_device);
359 image_b.Init(image_ci);
360 ASSERT_TRUE(image_b.initialized());
361
362 VkImageObj image_c(m_device);
363 image_c.Init(image_ci);
364 ASSERT_TRUE(image_c.initialized());
365
366 VkImageSubresourceLayers layers_all{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 2};
367 VkImageSubresourceLayers layers_0{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
368 VkImageSubresourceLayers layers_1{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1};
369 VkImageSubresourceRange full_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 2};
370 VkOffset3D zero_offset{0, 0, 0};
371 VkOffset3D half_offset{64, 64, 0};
372 VkExtent3D full_extent{128, 128, 1}; // <-- image type is 2D
373 VkExtent3D half_extent{64, 64, 1}; // <-- image type is 2D
374
375 VkImageCopy full_region = {layers_all, zero_offset, layers_all, zero_offset, full_extent};
376 VkImageCopy region_0_to_0 = {layers_0, zero_offset, layers_0, zero_offset, full_extent};
377 VkImageCopy region_0_to_1 = {layers_0, zero_offset, layers_1, zero_offset, full_extent};
378 VkImageCopy region_1_to_1 = {layers_1, zero_offset, layers_1, zero_offset, full_extent};
379 VkImageCopy region_0_front = {layers_0, zero_offset, layers_0, zero_offset, half_extent};
380 VkImageCopy region_0_back = {layers_0, half_offset, layers_0, half_offset, half_extent};
381
382 m_commandBuffer->begin();
383
384 image_c.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
385 image_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
386 image_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
387
388 auto cb = m_commandBuffer->handle();
389
390 vk::CmdCopyImage(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
391
392 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
393 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
394 m_errorMonitor->VerifyFound();
395
396 // Use the barrier to clean up the WAW, and try again. (and show that validation is accounting for the barrier effect too.)
Mark Lobodzinski07d0a612020-12-30 15:42:31 -0700397 auto image_barrier = LvlInitStruct<VkImageMemoryBarrier>();
Jeremy Gebben170781d2020-11-19 16:21:21 -0700398 image_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
399 image_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
400 image_barrier.image = image_a.handle();
401 image_barrier.subresourceRange = full_subresource_range;
402 image_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
403 image_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
404 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1,
405 &image_barrier);
406
407 m_errorMonitor->ExpectSuccess();
408 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_0_to_0);
409 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_1_to_1);
410 m_errorMonitor->VerifyNotFound();
411
412 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
413 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_0_to_1);
414 m_errorMonitor->VerifyFound();
415
416 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
417 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
418 m_errorMonitor->VerifyFound();
419
420 // NOTE: Since the previous command skips in validation, the state update is never done, and the validation layer thus doesn't
421 // record the write operation to b. So we'll need to repeat it successfully to set up for the *next* test.
422
423 // Use the barrier to clean up the WAW, and try again. (and show that validation is accounting for the barrier effect too.)
Mark Lobodzinski07d0a612020-12-30 15:42:31 -0700424 auto mem_barrier = LvlInitStruct<VkMemoryBarrier>();
Jeremy Gebben170781d2020-11-19 16:21:21 -0700425 mem_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
426 mem_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
427 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1, &mem_barrier, 0, nullptr, 0,
428 nullptr);
429 m_errorMonitor->ExpectSuccess();
430 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
431 m_errorMonitor->VerifyNotFound();
432
433 // Use barrier to protect last reader, but not last writer...
434 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
435 mem_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; // Protects C but not B
436 mem_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
437 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1, &mem_barrier, 0, nullptr, 0,
438 nullptr);
439 vk::CmdCopyImage(cb, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
440 m_errorMonitor->VerifyFound();
441
442 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_0_front);
443 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
444 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_0_front);
445 m_errorMonitor->VerifyFound();
446
447 m_errorMonitor->ExpectSuccess();
448 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_0_back);
449 m_errorMonitor->VerifyNotFound();
450
451 m_commandBuffer->end();
452
453 // CmdResolveImage
454 VkImageFormatProperties formProps = {{0, 0, 0}, 0, 0, 0, 0};
455 vk::GetPhysicalDeviceImageFormatProperties(m_device->phy().handle(), VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TYPE_2D,
456 VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 0, &formProps);
457
458 if (!(formProps.sampleCounts & VK_SAMPLE_COUNT_2_BIT)) {
459 printf("%s CmdResolveImage Test requires unsupported VK_SAMPLE_COUNT_2_BIT feature. Skipped.\n", kSkipPrefix);
460 } else {
461 m_errorMonitor->ExpectSuccess();
462 VkImageObj image_s2_a(m_device), image_s2_b(m_device);
463 image_ci.samples = VK_SAMPLE_COUNT_2_BIT;
464 image_s2_a.Init(image_ci);
465 ASSERT_TRUE(image_s2_a.initialized());
466
467 image_s2_b.Init(image_ci);
468 ASSERT_TRUE(image_s2_b.initialized());
469
470 VkImageResolve r_full_region = {layers_all, zero_offset, layers_all, zero_offset, full_extent};
471
472 m_commandBuffer->reset();
473 m_commandBuffer->begin();
474 image_s2_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
475 image_s2_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
476 vk::CmdResolveImage(cb, image_s2_a.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
477 &r_full_region);
478 m_commandBuffer->end();
479 m_errorMonitor->VerifyNotFound();
480
481 m_commandBuffer->reset();
482 m_commandBuffer->begin();
483 vk::CmdCopyImage(cb, image_s2_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_s2_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
484 &full_region);
485 vk::CmdCopyImage(cb, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
486
487 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
488 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
489 vk::CmdResolveImage(cb, image_s2_a.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
490 &r_full_region);
491 m_errorMonitor->VerifyFound();
492
493 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
494 vk::CmdResolveImage(cb, image_s2_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
495 &r_full_region);
496 m_errorMonitor->VerifyFound();
497 m_commandBuffer->end();
498 }
499}
500
Jeremy Gebben5c1bb2d2021-02-15 08:58:04 -0700501TEST_F(VkSyncValTest, Sync2CopyOptimalImageHazards) {
502 SetTargetApiVersion(VK_API_VERSION_1_2);
503 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
504 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME)) {
505 m_device_extension_names.push_back(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME);
506 } else {
507 printf("%s Synchronization2 not supported, skipping test\n", kSkipPrefix);
508 return;
509 }
510
511 if (!CheckSynchronization2SupportAndInitState(this)) {
512 printf("%s Synchronization2 not supported, skipping test\n", kSkipPrefix);
513 return;
514 }
515 auto fpCmdPipelineBarrier2KHR = (PFN_vkCmdPipelineBarrier2KHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdPipelineBarrier2KHR");
516
517 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
518 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
519 VkImageObj image_a(m_device);
520 auto image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 2, format, usage, VK_IMAGE_TILING_OPTIMAL);
521 image_a.Init(image_ci);
522 ASSERT_TRUE(image_a.initialized());
523
524 VkImageObj image_b(m_device);
525 image_b.Init(image_ci);
526 ASSERT_TRUE(image_b.initialized());
527
528 VkImageObj image_c(m_device);
529 image_c.Init(image_ci);
530 ASSERT_TRUE(image_c.initialized());
531
532 VkImageSubresourceLayers layers_all{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 2};
533 VkImageSubresourceLayers layers_0{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
534 VkImageSubresourceLayers layers_1{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1};
535 VkImageSubresourceRange full_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 2};
536 VkOffset3D zero_offset{0, 0, 0};
537 VkOffset3D half_offset{64, 64, 0};
538 VkExtent3D full_extent{128, 128, 1}; // <-- image type is 2D
539 VkExtent3D half_extent{64, 64, 1}; // <-- image type is 2D
540
541 VkImageCopy full_region = {layers_all, zero_offset, layers_all, zero_offset, full_extent};
542 VkImageCopy region_0_to_0 = {layers_0, zero_offset, layers_0, zero_offset, full_extent};
543 VkImageCopy region_0_to_1 = {layers_0, zero_offset, layers_1, zero_offset, full_extent};
544 VkImageCopy region_1_to_1 = {layers_1, zero_offset, layers_1, zero_offset, full_extent};
545 VkImageCopy region_0_front = {layers_0, zero_offset, layers_0, zero_offset, half_extent};
546 VkImageCopy region_0_back = {layers_0, half_offset, layers_0, half_offset, half_extent};
547
548 m_commandBuffer->begin();
549
550 image_c.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
551 image_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
552 image_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
553
554 auto cb = m_commandBuffer->handle();
555
556 vk::CmdCopyImage(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
557
558 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
559 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
560 m_errorMonitor->VerifyFound();
561
562 // Use the barrier to clean up the WAW, and try again. (and show that validation is accounting for the barrier effect too.)
563 {
564 auto image_barrier = lvl_init_struct<VkImageMemoryBarrier2KHR>();
565 image_barrier.srcStageMask = VK_PIPELINE_STAGE_2_COPY_BIT_KHR;
566 image_barrier.dstStageMask = VK_PIPELINE_STAGE_2_COPY_BIT_KHR;
567 image_barrier.srcAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT_KHR;
568 image_barrier.dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR;
569 image_barrier.image = image_a.handle();
570 image_barrier.subresourceRange = full_subresource_range;
571 image_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
572 image_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
573 auto dep_info = lvl_init_struct<VkDependencyInfoKHR>();
574 dep_info.imageMemoryBarrierCount = 1;
575 dep_info.pImageMemoryBarriers = &image_barrier;
576 fpCmdPipelineBarrier2KHR(cb, &dep_info);
577 }
578
579 m_errorMonitor->ExpectSuccess();
580 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_0_to_0);
581 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_1_to_1);
582 m_errorMonitor->VerifyNotFound();
583
584 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
585 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_0_to_1);
586 m_errorMonitor->VerifyFound();
587
588 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
589 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
590 m_errorMonitor->VerifyFound();
591
592 // NOTE: Since the previous command skips in validation, the state update is never done, and the validation layer thus doesn't
593 // record the write operation to b. So we'll need to repeat it successfully to set up for the *next* test.
594
595 // Use the barrier to clean up the WAW, and try again. (and show that validation is accounting for the barrier effect too.)
596 {
597 auto mem_barrier = lvl_init_struct<VkMemoryBarrier2KHR>();
598 mem_barrier.srcStageMask = VK_PIPELINE_STAGE_2_COPY_BIT_KHR;
599 mem_barrier.dstStageMask = VK_PIPELINE_STAGE_2_COPY_BIT_KHR;
600 mem_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
601 mem_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
602 auto dep_info = lvl_init_struct<VkDependencyInfoKHR>();
603 dep_info.memoryBarrierCount = 1;
604 dep_info.pMemoryBarriers = &mem_barrier;
605 fpCmdPipelineBarrier2KHR(cb, &dep_info);
606 m_errorMonitor->ExpectSuccess();
607 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
608 m_errorMonitor->VerifyNotFound();
609
610 // Use barrier to protect last reader, but not last writer...
611 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
612 mem_barrier.srcAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT_KHR; // Protects C but not B
613 mem_barrier.dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR;
614 fpCmdPipelineBarrier2KHR(cb, &dep_info);
615 vk::CmdCopyImage(cb, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
616 m_errorMonitor->VerifyFound();
617 }
618
619 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_0_front);
620 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
621 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_0_front);
622 m_errorMonitor->VerifyFound();
623
624 m_errorMonitor->ExpectSuccess();
625 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_0_back);
626 m_errorMonitor->VerifyNotFound();
627
628 m_commandBuffer->end();
629}
630
Jeremy Gebben170781d2020-11-19 16:21:21 -0700631TEST_F(VkSyncValTest, SyncCopyOptimalMultiPlanarHazards) {
632 // TODO: Add code to enable sync validation
633 // Enable KHR multiplane req'd extensions
634 bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
635 VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION);
636 if (mp_extensions) {
637 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
638 }
639 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
Mike Schuchardt7cc57842021-09-15 10:49:59 -0700640 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE_1_EXTENSION_NAME);
Jeremy Gebben170781d2020-11-19 16:21:21 -0700641 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
642 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
643 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
644 if (mp_extensions) {
Mike Schuchardt7cc57842021-09-15 10:49:59 -0700645 m_device_extension_names.push_back(VK_KHR_MAINTENANCE_1_EXTENSION_NAME);
Jeremy Gebben170781d2020-11-19 16:21:21 -0700646 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
647 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
648 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
649 } else {
650 printf("%s test requires KHR multiplane extensions, not available. Skipping.\n", kSkipPrefix);
651 return;
652 }
653
654 ASSERT_NO_FATAL_FAILURE(InitState());
655
656 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
657 VkFormat format = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM;
658 VkImageObj image_a(m_device);
659 const auto image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 2, format, usage, VK_IMAGE_TILING_OPTIMAL);
660 // Verify format
661 bool supported = ImageFormatAndFeaturesSupported(instance(), gpu(), image_ci,
662 VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT);
663 if (!supported) {
664 printf("%s Multiplane image format not supported. Skipping test.\n", kSkipPrefix);
665 return; // Assume there's low ROI on searching for different mp formats
666 }
667
668 image_a.Init(image_ci);
669 VkImageObj image_b(m_device);
670 image_b.Init(image_ci);
671 VkImageObj image_c(m_device);
672 image_c.Init(image_ci);
673
674 VkImageSubresourceLayers layer_all_plane0{VK_IMAGE_ASPECT_PLANE_0_BIT_KHR, 0, 0, 2};
675 VkImageSubresourceLayers layer0_plane0{VK_IMAGE_ASPECT_PLANE_0_BIT_KHR, 0, 0, 1};
676 VkImageSubresourceLayers layer0_plane1{VK_IMAGE_ASPECT_PLANE_1_BIT_KHR, 0, 0, 1};
677 VkImageSubresourceLayers layer1_plane1{VK_IMAGE_ASPECT_PLANE_1_BIT_KHR, 0, 1, 1};
678 VkImageSubresourceRange full_subresource_range{
679 VK_IMAGE_ASPECT_PLANE_0_BIT_KHR | VK_IMAGE_ASPECT_PLANE_1_BIT_KHR | VK_IMAGE_ASPECT_PLANE_2_BIT_KHR, 0, 1, 0, 2};
680 VkOffset3D zero_offset{0, 0, 0};
681 VkOffset3D one_four_offset{32, 32, 0};
682 VkExtent3D full_extent{128, 128, 1}; // <-- image type is 2D
683 VkExtent3D half_extent{64, 64, 1}; // <-- image type is 2D
684 VkExtent3D one_four_extent{32, 32, 1}; // <-- image type is 2D
685
686 VkImageCopy region_all_plane0_to_all_plane0 = {layer_all_plane0, zero_offset, layer_all_plane0, zero_offset, full_extent};
687 VkImageCopy region_layer0_plane0_to_layer0_plane0 = {layer0_plane0, zero_offset, layer0_plane0, zero_offset, full_extent};
688 VkImageCopy region_layer0_plane0_to_layer0_plane1 = {layer0_plane0, zero_offset, layer0_plane1, zero_offset, half_extent};
689 VkImageCopy region_layer1_plane1_to_layer1_plane1_front = {layer1_plane1, zero_offset, layer1_plane1, zero_offset,
690 one_four_extent};
691 VkImageCopy region_layer1_plane1_to_layer1_plane1_back = {layer1_plane1, one_four_offset, layer1_plane1, one_four_offset,
692 one_four_extent};
693
694 m_commandBuffer->begin();
695
696 image_c.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
697 image_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
698 image_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
699
700 auto cb = m_commandBuffer->handle();
701
702 vk::CmdCopyImage(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
703 &region_all_plane0_to_all_plane0);
704
705 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
706 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
707 &region_all_plane0_to_all_plane0);
708 m_errorMonitor->VerifyFound();
709
710 // Use the barrier to clean up the WAW, and try again. (and show that validation is accounting for the barrier effect too.)
Mark Lobodzinski07d0a612020-12-30 15:42:31 -0700711 auto image_barrier = LvlInitStruct<VkImageMemoryBarrier>();
Jeremy Gebben170781d2020-11-19 16:21:21 -0700712 image_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
713 image_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
714 image_barrier.image = image_a.handle();
715 image_barrier.subresourceRange = full_subresource_range;
716 image_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
717 image_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
718 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1,
719 &image_barrier);
720
721 m_errorMonitor->ExpectSuccess();
722 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
723 &region_layer0_plane0_to_layer0_plane0);
724 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
725 &region_layer0_plane0_to_layer0_plane1);
726 m_errorMonitor->VerifyNotFound();
727
728 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
729 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
730 &region_layer0_plane0_to_layer0_plane1);
731 m_errorMonitor->VerifyFound();
732
733 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
734 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
735 &region_all_plane0_to_all_plane0);
736 m_errorMonitor->VerifyFound();
737
738 // NOTE: Since the previous command skips in validation, the state update is never done, and the validation layer thus doesn't
739 // record the write operation to b. So we'll need to repeat it successfully to set up for the *next* test.
740
741 // Use the barrier to clean up the WAW, and try again. (and show that validation is accounting for the barrier effect too.)
Mark Lobodzinski07d0a612020-12-30 15:42:31 -0700742 auto mem_barrier = LvlInitStruct<VkMemoryBarrier>();
Jeremy Gebben170781d2020-11-19 16:21:21 -0700743 mem_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
744 mem_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
745 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1, &mem_barrier, 0, nullptr, 0,
746 nullptr);
747 m_errorMonitor->ExpectSuccess();
748 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
749 &region_all_plane0_to_all_plane0);
750 m_errorMonitor->VerifyNotFound();
751
752 // Use barrier to protect last reader, but not last writer...
753 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
754 mem_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; // Protects C but not B
755 mem_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
756 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1, &mem_barrier, 0, nullptr, 0,
757 nullptr);
758 vk::CmdCopyImage(cb, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
759 &region_all_plane0_to_all_plane0);
760 m_errorMonitor->VerifyFound();
761
762 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
763 &region_layer1_plane1_to_layer1_plane1_front);
764 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
765 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
766 &region_layer1_plane1_to_layer1_plane1_front);
767 m_errorMonitor->VerifyFound();
768
769 m_errorMonitor->ExpectSuccess();
770 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
771 &region_layer1_plane1_to_layer1_plane1_back);
772 m_errorMonitor->VerifyNotFound();
773
774 m_commandBuffer->end();
775}
776
777TEST_F(VkSyncValTest, SyncCopyLinearImageHazards) {
778 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
779 ASSERT_NO_FATAL_FAILURE(InitState());
780
781 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
782 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
783 VkImageObj image_a(m_device);
784 const auto image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 1, format, usage, VK_IMAGE_TILING_LINEAR);
785 image_a.Init(image_ci);
786 VkImageObj image_b(m_device);
787 image_b.Init(image_ci);
788 VkImageObj image_c(m_device);
789 image_c.Init(image_ci);
790
791 VkImageSubresourceLayers layers_all{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
792 VkImageSubresourceRange full_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
793 VkOffset3D zero_offset{0, 0, 0};
794 VkOffset3D half_offset{64, 64, 0};
795 VkExtent3D full_extent{128, 128, 1}; // <-- image type is 2D
796 VkExtent3D half_extent{64, 64, 1}; // <-- image type is 2D
797
798 VkImageCopy full_region = {layers_all, zero_offset, layers_all, zero_offset, full_extent};
799 VkImageCopy region_front = {layers_all, zero_offset, layers_all, zero_offset, half_extent};
800 VkImageCopy region_back = {layers_all, half_offset, layers_all, half_offset, half_extent};
801
802 m_commandBuffer->begin();
803
804 image_c.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
805 image_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
806 image_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
807
808 auto cb = m_commandBuffer->handle();
809
810 vk::CmdCopyImage(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
811
812 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
813 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
814 m_errorMonitor->VerifyFound();
815
816 // Use the barrier to clean up the WAW, and try again. (and show that validation is accounting for the barrier effect too.)
Mark Lobodzinski07d0a612020-12-30 15:42:31 -0700817 auto image_barrier = LvlInitStruct<VkImageMemoryBarrier>();
Jeremy Gebben170781d2020-11-19 16:21:21 -0700818 image_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
819 image_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
820 image_barrier.image = image_b.handle();
821 image_barrier.subresourceRange = full_subresource_range;
822 image_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
823 image_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
824 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1,
825 &image_barrier);
826
827 m_errorMonitor->ExpectSuccess();
828 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
829 m_errorMonitor->VerifyNotFound();
830
831 // Use barrier to protect last reader, but not last writer...
832 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
833 image_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; // Protects C but not B
834 image_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
835 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1,
836 &image_barrier);
837 vk::CmdCopyImage(cb, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
838 m_errorMonitor->VerifyFound();
839
840 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_front);
841 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
842 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_front);
843 m_errorMonitor->VerifyFound();
844
845 m_errorMonitor->ExpectSuccess();
846 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_back);
847 m_errorMonitor->VerifyNotFound();
848}
849
850TEST_F(VkSyncValTest, SyncCopyLinearMultiPlanarHazards) {
851 // TODO: Add code to enable sync validation
852 // Enable KHR multiplane req'd extensions
853 bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
854 VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION);
855 if (mp_extensions) {
856 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
857 }
858 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
Mike Schuchardt7cc57842021-09-15 10:49:59 -0700859 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE_1_EXTENSION_NAME);
Jeremy Gebben170781d2020-11-19 16:21:21 -0700860 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
861 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
862 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
863 if (mp_extensions) {
Mike Schuchardt7cc57842021-09-15 10:49:59 -0700864 m_device_extension_names.push_back(VK_KHR_MAINTENANCE_1_EXTENSION_NAME);
Jeremy Gebben170781d2020-11-19 16:21:21 -0700865 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
866 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
867 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
868 } else {
869 printf("%s test requires KHR multiplane extensions, not available. Skipping.\n", kSkipPrefix);
870 return;
871 }
872
873 ASSERT_NO_FATAL_FAILURE(InitState());
874
875 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
876 VkFormat format = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM;
877 VkImageObj image_a(m_device);
878 const auto image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 1, format, usage, VK_IMAGE_TILING_LINEAR);
879 // Verify format
880 bool supported = ImageFormatAndFeaturesSupported(instance(), gpu(), image_ci,
881 VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT);
882 if (!supported) {
883 printf("%s Multiplane image format not supported. Skipping test.\n", kSkipPrefix);
884 return; // Assume there's low ROI on searching for different mp formats
885 }
886
887 image_a.Init(image_ci);
888 VkImageObj image_b(m_device);
889 image_b.Init(image_ci);
890 VkImageObj image_c(m_device);
891 image_c.Init(image_ci);
892
893 VkImageSubresourceLayers layer_all_plane0{VK_IMAGE_ASPECT_PLANE_0_BIT_KHR, 0, 0, 1};
894 VkImageSubresourceLayers layer_all_plane1{VK_IMAGE_ASPECT_PLANE_1_BIT_KHR, 0, 0, 1};
895 VkImageSubresourceRange full_subresource_range{
896 VK_IMAGE_ASPECT_PLANE_0_BIT_KHR | VK_IMAGE_ASPECT_PLANE_1_BIT_KHR | VK_IMAGE_ASPECT_PLANE_2_BIT_KHR, 0, 1, 0, 1};
897 VkOffset3D zero_offset{0, 0, 0};
898 VkOffset3D one_four_offset{32, 32, 0};
899 VkExtent3D full_extent{128, 128, 1}; // <-- image type is 2D
900 VkExtent3D half_extent{64, 64, 1}; // <-- image type is 2D
901 VkExtent3D one_four_extent{32, 32, 1}; // <-- image type is 2D
902
903 VkImageCopy region_plane0_to_plane0 = {layer_all_plane0, zero_offset, layer_all_plane0, zero_offset, full_extent};
904 VkImageCopy region_plane0_to_plane1 = {layer_all_plane0, zero_offset, layer_all_plane1, zero_offset, half_extent};
905 VkImageCopy region_plane1_to_plane1_front = {layer_all_plane1, zero_offset, layer_all_plane1, zero_offset, one_four_extent};
906 VkImageCopy region_plane1_to_plane1_back = {layer_all_plane1, one_four_offset, layer_all_plane1, one_four_offset,
907 one_four_extent};
908
909 m_commandBuffer->begin();
910
911 image_c.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
912 image_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
913 image_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
914
915 auto cb = m_commandBuffer->handle();
916
917 vk::CmdCopyImage(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
918 &region_plane0_to_plane0);
919
920 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
921 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
922 &region_plane0_to_plane0);
923 m_errorMonitor->VerifyFound();
924
925 // Use the barrier to clean up the WAW, and try again. (and show that validation is accounting for the barrier effect too.)
Mark Lobodzinski07d0a612020-12-30 15:42:31 -0700926 auto image_barrier = LvlInitStruct<VkImageMemoryBarrier>();
Jeremy Gebben170781d2020-11-19 16:21:21 -0700927 image_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
928 image_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
929 image_barrier.image = image_a.handle();
930 image_barrier.subresourceRange = full_subresource_range;
931 image_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
932 image_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
933 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1,
934 &image_barrier);
935
936 m_errorMonitor->ExpectSuccess();
937 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
938 &region_plane0_to_plane0);
939 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
940 &region_plane0_to_plane1);
941 m_errorMonitor->VerifyNotFound();
942
943 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
944 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
945 &region_plane0_to_plane1);
946 m_errorMonitor->VerifyFound();
947
948 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
949 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
950 &region_plane0_to_plane0);
951 m_errorMonitor->VerifyFound();
952
953 // NOTE: Since the previous command skips in validation, the state update is never done, and the validation layer thus doesn't
954 // record the write operation to b. So we'll need to repeat it successfully to set up for the *next* test.
955
956 // Use the barrier to clean up the WAW, and try again. (and show that validation is accounting for the barrier effect too.)
Mark Lobodzinski07d0a612020-12-30 15:42:31 -0700957 auto mem_barrier = LvlInitStruct<VkMemoryBarrier>();
Jeremy Gebben170781d2020-11-19 16:21:21 -0700958 mem_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
959 mem_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
960 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1, &mem_barrier, 0, nullptr, 0,
961 nullptr);
962 m_errorMonitor->ExpectSuccess();
963 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
964 &region_plane0_to_plane0);
965 m_errorMonitor->VerifyNotFound();
966
967 // Use barrier to protect last reader, but not last writer...
968 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
969 mem_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; // Protects C but not B
970 mem_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
971 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1, &mem_barrier, 0, nullptr, 0,
972 nullptr);
973 vk::CmdCopyImage(cb, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
974 &region_plane0_to_plane0);
975 m_errorMonitor->VerifyFound();
976
977 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
978 &region_plane1_to_plane1_front);
979 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
980 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
981 &region_plane1_to_plane1_front);
982 m_errorMonitor->VerifyFound();
983
984 m_errorMonitor->ExpectSuccess();
985 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
986 &region_plane1_to_plane1_back);
987 m_errorMonitor->VerifyNotFound();
988
989 m_commandBuffer->end();
990}
991
992TEST_F(VkSyncValTest, SyncCopyBufferImageHazards) {
993 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
994 ASSERT_NO_FATAL_FAILURE(InitState());
995
996 VkBufferObj buffer_a, buffer_b;
997 VkMemoryPropertyFlags mem_prop = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
998 buffer_a.init_as_src_and_dst(*m_device, 2048, mem_prop);
999 buffer_b.init_as_src_and_dst(*m_device, 2048, mem_prop);
1000
1001 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1002 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
1003 VkImageObj image_a(m_device), image_b(m_device);
1004 const auto image_ci = VkImageObj::ImageCreateInfo2D(32, 32, 1, 2, format, usage, VK_IMAGE_TILING_OPTIMAL);
1005 image_a.Init(image_ci);
1006 image_b.Init(image_ci);
1007
1008 VkImageSubresourceLayers layers_0{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
1009 VkImageSubresourceLayers layers_1{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1};
1010 VkOffset3D zero_offset{0, 0, 0};
1011 VkOffset3D half_offset{16, 16, 0};
1012 VkExtent3D half_extent{16, 16, 1}; // <-- image type is 2D
1013
1014 VkBufferImageCopy region_buffer_front_image_0_front = {0, 16, 16, layers_0, zero_offset, half_extent};
1015 VkBufferImageCopy region_buffer_front_image_1_front = {0, 16, 16, layers_1, zero_offset, half_extent};
1016 VkBufferImageCopy region_buffer_front_image_1_back = {0, 16, 16, layers_1, half_offset, half_extent};
1017 VkBufferImageCopy region_buffer_back_image_0_front = {1024, 16, 16, layers_0, zero_offset, half_extent};
1018 VkBufferImageCopy region_buffer_back_image_0_back = {1024, 16, 16, layers_0, half_offset, half_extent};
1019 VkBufferImageCopy region_buffer_back_image_1_front = {1024, 16, 16, layers_1, zero_offset, half_extent};
1020 VkBufferImageCopy region_buffer_back_image_1_back = {1024, 16, 16, layers_1, half_offset, half_extent};
1021
1022 m_commandBuffer->begin();
1023 image_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1024 image_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1025
1026 auto cb = m_commandBuffer->handle();
1027 vk::CmdCopyBufferToImage(cb, buffer_a.handle(), image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1028 &region_buffer_front_image_0_front);
1029
1030 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1031 vk::CmdCopyBufferToImage(cb, buffer_a.handle(), image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1032 &region_buffer_front_image_0_front);
1033 m_errorMonitor->VerifyFound();
1034
1035 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1036 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1037 vk::CmdCopyImageToBuffer(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_a.handle(), 1,
1038 &region_buffer_front_image_0_front);
1039 m_errorMonitor->VerifyFound();
1040
1041 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1042 vk::CmdCopyImageToBuffer(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_a.handle(), 1,
1043 &region_buffer_back_image_0_front);
1044 m_errorMonitor->VerifyFound();
1045
1046 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1047 vk::CmdCopyImageToBuffer(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_a.handle(), 1,
1048 &region_buffer_front_image_1_front);
1049 m_errorMonitor->VerifyFound();
1050
1051 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1052 vk::CmdCopyImageToBuffer(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_a.handle(), 1,
1053 &region_buffer_front_image_1_back);
1054 m_errorMonitor->VerifyFound();
1055
1056 m_errorMonitor->ExpectSuccess();
1057 vk::CmdCopyImageToBuffer(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_a.handle(), 1, &region_buffer_back_image_0_back);
1058 m_errorMonitor->VerifyNotFound();
1059
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07001060 auto buffer_barrier = LvlInitStruct<VkBufferMemoryBarrier>();
Jeremy Gebben170781d2020-11-19 16:21:21 -07001061 buffer_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1062 buffer_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1063 buffer_barrier.buffer = buffer_a.handle();
1064 buffer_barrier.offset = 1024;
1065 buffer_barrier.size = 2048;
1066 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, &buffer_barrier, 0,
1067 nullptr);
1068
1069 m_errorMonitor->ExpectSuccess();
1070 vk::CmdCopyImageToBuffer(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_a.handle(), 1,
1071 &region_buffer_back_image_1_front);
1072 m_errorMonitor->VerifyNotFound();
1073
1074 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, &buffer_barrier, 0,
1075 nullptr);
1076
1077 m_errorMonitor->ExpectSuccess();
1078 vk::CmdCopyImageToBuffer(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_a.handle(), 1, &region_buffer_back_image_1_back);
1079 m_errorMonitor->VerifyNotFound();
1080
1081 vk::CmdCopyImageToBuffer(cb, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_b.handle(), 1,
1082 &region_buffer_front_image_0_front);
1083
1084 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1085 vk::CmdCopyImageToBuffer(cb, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_b.handle(), 1,
1086 &region_buffer_front_image_0_front);
1087 m_errorMonitor->VerifyFound();
1088
1089 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1090 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1091 vk::CmdCopyBufferToImage(cb, buffer_b.handle(), image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1092 &region_buffer_front_image_0_front);
1093 m_errorMonitor->VerifyFound();
1094
1095 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1096 vk::CmdCopyBufferToImage(cb, buffer_b.handle(), image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1097 &region_buffer_back_image_0_front);
1098 m_errorMonitor->VerifyFound();
1099
1100 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1101 vk::CmdCopyBufferToImage(cb, buffer_b.handle(), image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1102 &region_buffer_front_image_1_front);
1103 m_errorMonitor->VerifyFound();
1104
1105 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1106 vk::CmdCopyBufferToImage(cb, buffer_b.handle(), image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1107 &region_buffer_front_image_1_back);
1108 m_errorMonitor->VerifyFound();
1109
1110 m_errorMonitor->ExpectSuccess();
1111 vk::CmdCopyBufferToImage(cb, buffer_b.handle(), image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_buffer_back_image_0_back);
1112 m_errorMonitor->VerifyNotFound();
1113
1114 buffer_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
1115 buffer_barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
1116 buffer_barrier.buffer = buffer_b.handle();
1117 buffer_barrier.offset = 1024;
1118 buffer_barrier.size = 2048;
1119 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, &buffer_barrier, 0,
1120 nullptr);
1121
1122 m_errorMonitor->ExpectSuccess();
1123 vk::CmdCopyBufferToImage(cb, buffer_b.handle(), image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1124 &region_buffer_back_image_1_front);
1125 m_errorMonitor->VerifyNotFound();
1126
1127 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, &buffer_barrier, 0,
1128 nullptr);
1129
1130 m_errorMonitor->ExpectSuccess();
1131 vk::CmdCopyBufferToImage(cb, buffer_b.handle(), image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_buffer_back_image_1_back);
1132 m_errorMonitor->VerifyNotFound();
1133
1134 m_commandBuffer->end();
1135}
1136
1137TEST_F(VkSyncValTest, SyncBlitImageHazards) {
1138 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
1139 ASSERT_NO_FATAL_FAILURE(InitState());
1140
1141 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1142 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
1143 VkImageObj image_a(m_device), image_b(m_device);
1144 const auto image_ci = VkImageObj::ImageCreateInfo2D(32, 32, 1, 2, format, usage, VK_IMAGE_TILING_OPTIMAL);
1145 image_a.Init(image_ci);
1146 image_b.Init(image_ci);
1147
1148 VkImageSubresourceLayers layers_0{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
1149 VkImageSubresourceLayers layers_1{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1};
1150 VkOffset3D zero_offset{0, 0, 0};
1151 VkOffset3D half_0_offset{16, 16, 0};
1152 VkOffset3D half_1_offset{16, 16, 1};
1153 VkOffset3D full_offset{32, 32, 1};
1154 VkImageBlit region_0_front_1_front = {layers_0, {zero_offset, half_1_offset}, layers_1, {zero_offset, half_1_offset}};
1155 VkImageBlit region_1_front_0_front = {layers_1, {zero_offset, half_1_offset}, layers_0, {zero_offset, half_1_offset}};
1156 VkImageBlit region_1_back_0_back = {layers_1, {half_0_offset, full_offset}, layers_0, {half_0_offset, full_offset}};
1157
1158 m_commandBuffer->begin();
1159 image_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1160 image_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1161
1162 auto cb = m_commandBuffer->handle();
1163
1164 vk::CmdBlitImage(cb, image_a.image(), VK_IMAGE_LAYOUT_GENERAL, image_b.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
1165 &region_0_front_1_front, VK_FILTER_NEAREST);
1166
1167 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1168 vk::CmdBlitImage(cb, image_a.image(), VK_IMAGE_LAYOUT_GENERAL, image_b.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
1169 &region_0_front_1_front, VK_FILTER_NEAREST);
1170 m_errorMonitor->VerifyFound();
1171
1172 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1173 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1174 vk::CmdBlitImage(cb, image_b.image(), VK_IMAGE_LAYOUT_GENERAL, image_a.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
1175 &region_1_front_0_front, VK_FILTER_NEAREST);
1176 m_errorMonitor->VerifyFound();
1177
1178 m_errorMonitor->ExpectSuccess();
1179 vk::CmdBlitImage(cb, image_b.image(), VK_IMAGE_LAYOUT_GENERAL, image_a.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
1180 &region_1_back_0_back, VK_FILTER_NEAREST);
1181 m_errorMonitor->VerifyNotFound();
1182
1183 m_commandBuffer->end();
1184}
1185
1186TEST_F(VkSyncValTest, SyncRenderPassBeginTransitionHazard) {
1187 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
1188 ASSERT_NO_FATAL_FAILURE(InitState());
John Zulaufbb373682021-10-05 17:21:40 -06001189 const VkSubpassDependency external_subpass_dependency = {VK_SUBPASS_EXTERNAL,
1190 0,
1191 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
1192 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
1193 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1194 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1195 VK_DEPENDENCY_BY_REGION_BIT};
1196 m_additionalSubpassDependencies.push_back(external_subpass_dependency);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001197 ASSERT_NO_FATAL_FAILURE(InitRenderTarget(2));
1198
1199 // Render Target Information
1200 auto width = static_cast<uint32_t>(m_width);
1201 auto height = static_cast<uint32_t>(m_height);
1202 auto *rt_0 = m_renderTargets[0].get();
1203 auto *rt_1 = m_renderTargets[1].get();
1204
1205 // Other buffers with which to interact
1206 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1207 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
1208 VkImageObj image_a(m_device), image_b(m_device);
1209 const auto image_ci = VkImageObj::ImageCreateInfo2D(width, height, 1, 1, format, usage, VK_IMAGE_TILING_OPTIMAL);
1210 image_a.Init(image_ci);
1211 image_b.Init(image_ci);
1212
1213 VkOffset3D zero_offset{0, 0, 0};
1214 VkExtent3D full_extent{width, height, 1}; // <-- image type is 2D
1215 VkImageSubresourceLayers layer_color{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
1216 VkImageCopy region_to_copy = {layer_color, zero_offset, layer_color, zero_offset, full_extent};
1217
1218 auto cb = m_commandBuffer->handle();
1219
1220 m_errorMonitor->ExpectSuccess();
1221 m_commandBuffer->begin();
1222 image_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1223 image_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1224 rt_0->SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1225 rt_1->SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1226
1227 rt_0->SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1228 vk::CmdCopyImage(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, rt_0->handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_to_copy);
1229 m_errorMonitor->VerifyNotFound();
1230
1231 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1232 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); // This fails so the driver call is skip and no end is valid
1233 m_errorMonitor->VerifyFound();
1234
1235 m_errorMonitor->ExpectSuccess();
1236 // Use the barrier to clean up the WAW, and try again. (and show that validation is accounting for the barrier effect too.)
1237 VkImageSubresourceRange rt_full_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07001238 auto image_barrier = LvlInitStruct<VkImageMemoryBarrier>();
Jeremy Gebben170781d2020-11-19 16:21:21 -07001239 image_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
John Zulaufbb373682021-10-05 17:21:40 -06001240 image_barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
Jeremy Gebben170781d2020-11-19 16:21:21 -07001241 image_barrier.image = rt_0->handle();
1242 image_barrier.subresourceRange = rt_full_subresource_range;
1243 image_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
1244 image_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
John Zulaufbb373682021-10-05 17:21:40 -06001245 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0,
1246 nullptr, 1, &image_barrier);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001247 vk::CmdCopyImage(cb, rt_1->handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_to_copy);
1248 m_errorMonitor->VerifyNotFound();
1249
1250 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1251 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); // This fails so the driver call is skip and no end is valid
1252 m_errorMonitor->VerifyFound();
1253
1254 m_errorMonitor->ExpectSuccess();
1255 // A global execution barrier that the implict external dependency can chain with should work...
1256 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, 0,
1257 nullptr);
1258
1259 // With the barrier above, the layout transition has a chained execution sync operation, and the default
1260 // implict VkSubpassDependency safes the load op clear vs. the layout transition...
1261 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1262 m_commandBuffer->EndRenderPass();
1263 m_errorMonitor->VerifyNotFound();
1264}
1265
1266TEST_F(VkSyncValTest, SyncCmdDispatchDrawHazards) {
1267 // TODO: Add code to enable sync validation
1268 SetTargetApiVersion(VK_API_VERSION_1_2);
1269
1270 // Enable VK_KHR_draw_indirect_count for KHR variants
1271 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
1272 VkPhysicalDeviceVulkan12Features features12 = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, nullptr};
1273 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME)) {
1274 m_device_extension_names.push_back(VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME);
1275 if (DeviceValidationVersion() >= VK_API_VERSION_1_2) {
1276 features12.drawIndirectCount = VK_TRUE;
1277 }
1278 }
1279 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features12, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
1280 bool has_khr_indirect = DeviceExtensionEnabled(VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME);
1281 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1282
1283 VkImageUsageFlags image_usage_combine = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
1284 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1285 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
1286 VkImageObj image_c_a(m_device), image_c_b(m_device);
1287 const auto image_c_ci = VkImageObj::ImageCreateInfo2D(16, 16, 1, 1, format, image_usage_combine, VK_IMAGE_TILING_OPTIMAL);
1288 image_c_a.Init(image_c_ci);
1289 image_c_b.Init(image_c_ci);
1290
1291 VkImageView imageview_c = image_c_a.targetView(format);
1292 VkImageUsageFlags image_usage_storage =
1293 VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1294 VkImageObj image_s_a(m_device), image_s_b(m_device);
1295 const auto image_s_ci = VkImageObj::ImageCreateInfo2D(16, 16, 1, 1, format, image_usage_storage, VK_IMAGE_TILING_OPTIMAL);
1296 image_s_a.Init(image_s_ci);
1297 image_s_b.Init(image_s_ci);
1298 image_s_a.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1299 image_s_b.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1300
1301 VkImageView imageview_s = image_s_a.targetView(format);
1302
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001303 vk_testing::Sampler sampler_s, sampler_c;
Jeremy Gebben170781d2020-11-19 16:21:21 -07001304 VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001305 sampler_s.init(*m_device, sampler_ci);
1306 sampler_c.init(*m_device, sampler_ci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001307
1308 VkBufferObj buffer_a, buffer_b;
1309 VkMemoryPropertyFlags mem_prop = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
1310 VkBufferUsageFlags buffer_usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT |
1311 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1312 buffer_a.init(*m_device, buffer_a.create_info(2048, buffer_usage, nullptr), mem_prop);
1313 buffer_b.init(*m_device, buffer_b.create_info(2048, buffer_usage, nullptr), mem_prop);
1314
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001315 vk_testing::BufferView bufferview;
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07001316 auto bvci = LvlInitStruct<VkBufferViewCreateInfo>();
Jeremy Gebben170781d2020-11-19 16:21:21 -07001317 bvci.buffer = buffer_a.handle();
1318 bvci.format = VK_FORMAT_R32_SFLOAT;
1319 bvci.offset = 0;
1320 bvci.range = VK_WHOLE_SIZE;
1321
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001322 bufferview.init(*m_device, bvci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001323
1324 OneOffDescriptorSet descriptor_set(m_device,
1325 {
1326 {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
1327 {1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr},
1328 {2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_ALL, nullptr},
1329 {3, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
1330 });
1331
sfricke-samsung36428462021-02-10 01:23:34 -08001332 descriptor_set.WriteDescriptorBufferInfo(0, buffer_a.handle(), 0, 2048);
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001333 descriptor_set.WriteDescriptorImageInfo(1, imageview_c, sampler_c.handle(), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
Jeremy Gebben170781d2020-11-19 16:21:21 -07001334 VK_IMAGE_LAYOUT_GENERAL);
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001335 descriptor_set.WriteDescriptorImageInfo(2, imageview_s, sampler_s.handle(), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_IMAGE_LAYOUT_GENERAL);
1336 descriptor_set.WriteDescriptorBufferView(3, bufferview.handle());
Jeremy Gebben170781d2020-11-19 16:21:21 -07001337 descriptor_set.UpdateDescriptorSets();
1338
1339 // Dispatch
sfricke-samsung1c0b96a2021-07-08 22:24:09 -07001340 std::string csSource = R"glsl(
1341 #version 450
1342 layout(set=0, binding=0) uniform foo { float x; } ub0;
1343 layout(set=0, binding=1) uniform sampler2D cis1;
1344 layout(set=0, binding=2, rgba8) uniform readonly image2D si2;
1345 layout(set=0, binding=3, r32f) uniform readonly imageBuffer stb3;
1346 void main(){
1347 vec4 vColor4;
1348 vColor4.x = ub0.x;
1349 vColor4 = texture(cis1, vec2(0));
1350 vColor4 = imageLoad(si2, ivec2(0));
1351 vColor4 = imageLoad(stb3, 0);
1352 }
1353 )glsl";
Jeremy Gebben170781d2020-11-19 16:21:21 -07001354
John Zulaufbe8562b2020-12-15 14:21:01 -07001355 VkEventObj event;
1356 event.init(*m_device, VkEventObj::create_info(0));
1357 VkEvent event_handle = event.handle();
1358
Jeremy Gebben170781d2020-11-19 16:21:21 -07001359 CreateComputePipelineHelper pipe(*this);
1360 pipe.InitInfo();
1361 pipe.cs_.reset(new VkShaderObj(m_device, csSource.c_str(), VK_SHADER_STAGE_COMPUTE_BIT, this));
1362 pipe.InitState();
1363 pipe.pipeline_layout_ = VkPipelineLayoutObj(m_device, {&descriptor_set.layout_});
1364 pipe.CreateComputePipeline();
1365
1366 m_commandBuffer->begin();
1367
1368 VkBufferCopy buffer_region = {0, 0, 2048};
1369 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_b.handle(), buffer_a.handle(), 1, &buffer_region);
1370
1371 VkImageSubresourceLayers layer{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
1372 VkOffset3D zero_offset{0, 0, 0};
1373 VkExtent3D full_extent{16, 16, 1};
1374 VkImageCopy image_region = {layer, zero_offset, layer, zero_offset, full_extent};
1375 vk::CmdCopyImage(m_commandBuffer->handle(), image_c_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_c_a.handle(),
1376 VK_IMAGE_LAYOUT_GENERAL, 1, &image_region);
1377 vk::CmdCopyImage(m_commandBuffer->handle(), image_s_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_s_a.handle(),
1378 VK_IMAGE_LAYOUT_GENERAL, 1, &image_region);
1379
1380 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_);
1381 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_layout_.handle(), 0, 1,
1382 &descriptor_set.set_, 0, nullptr);
1383
1384 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1385 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1386 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1387 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1388 vk::CmdDispatch(m_commandBuffer->handle(), 1, 1, 1);
1389 m_errorMonitor->VerifyFound();
1390
1391 m_commandBuffer->end();
1392 m_commandBuffer->reset();
1393 m_commandBuffer->begin();
1394
1395 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_);
1396 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_layout_.handle(), 0, 1,
1397 &descriptor_set.set_, 0, nullptr);
1398 vk::CmdDispatch(m_commandBuffer->handle(), 1, 1, 1);
1399
1400 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1401 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_b.handle(), buffer_a.handle(), 1, &buffer_region);
1402 m_errorMonitor->VerifyFound();
1403
1404 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1405 vk::CmdCopyImage(m_commandBuffer->handle(), image_c_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_c_a.handle(),
1406 VK_IMAGE_LAYOUT_GENERAL, 1, &image_region);
1407 m_errorMonitor->VerifyFound();
1408
1409 m_commandBuffer->end();
1410 m_commandBuffer->reset();
1411
1412 // DispatchIndirect
1413 m_errorMonitor->ExpectSuccess();
1414 VkBufferObj buffer_dispatchIndirect, buffer_dispatchIndirect2;
1415 buffer_usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1416 buffer_dispatchIndirect.init(
1417 *m_device, buffer_dispatchIndirect.create_info(sizeof(VkDispatchIndirectCommand), buffer_usage, nullptr), mem_prop);
1418 buffer_dispatchIndirect2.init(
1419 *m_device, buffer_dispatchIndirect2.create_info(sizeof(VkDispatchIndirectCommand), buffer_usage, nullptr), mem_prop);
1420 m_commandBuffer->begin();
1421 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_);
1422 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_layout_.handle(), 0, 1,
1423 &descriptor_set.set_, 0, nullptr);
1424 vk::CmdDispatchIndirect(m_commandBuffer->handle(), buffer_dispatchIndirect.handle(), 0);
1425 m_commandBuffer->end();
1426 m_errorMonitor->VerifyNotFound();
1427
1428 m_commandBuffer->reset();
1429 m_commandBuffer->begin();
1430
1431 buffer_region = {0, 0, sizeof(VkDispatchIndirectCommand)};
1432 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_dispatchIndirect2.handle(), buffer_dispatchIndirect.handle(), 1,
1433 &buffer_region);
1434 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_);
1435 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_layout_.handle(), 0, 1,
1436 &descriptor_set.set_, 0, nullptr);
1437 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1438 vk::CmdDispatchIndirect(m_commandBuffer->handle(), buffer_dispatchIndirect.handle(), 0);
1439 m_errorMonitor->VerifyFound();
1440 m_commandBuffer->end();
1441
1442 // Draw
1443 m_errorMonitor->ExpectSuccess();
1444 const float vbo_data[3] = {1.f, 0.f, 1.f};
1445 VkVertexInputAttributeDescription VertexInputAttributeDescription = {0, 0, VK_FORMAT_R32G32B32_SFLOAT, sizeof(vbo_data)};
1446 VkVertexInputBindingDescription VertexInputBindingDescription = {0, sizeof(vbo_data), VK_VERTEX_INPUT_RATE_VERTEX};
1447 VkBufferObj vbo, vbo2;
1448 buffer_usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1449 vbo.init(*m_device, vbo.create_info(sizeof(vbo_data), buffer_usage, nullptr), mem_prop);
1450 vbo2.init(*m_device, vbo2.create_info(sizeof(vbo_data), buffer_usage, nullptr), mem_prop);
1451
1452 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
1453 VkShaderObj fs(m_device, csSource.c_str(), VK_SHADER_STAGE_FRAGMENT_BIT, this);
1454
1455 CreatePipelineHelper g_pipe(*this);
1456 g_pipe.InitInfo();
1457 g_pipe.InitState();
1458 g_pipe.vi_ci_.pVertexBindingDescriptions = &VertexInputBindingDescription;
1459 g_pipe.vi_ci_.vertexBindingDescriptionCount = 1;
1460 g_pipe.vi_ci_.pVertexAttributeDescriptions = &VertexInputAttributeDescription;
1461 g_pipe.vi_ci_.vertexAttributeDescriptionCount = 1;
1462 g_pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
1463 g_pipe.pipeline_layout_ = VkPipelineLayoutObj(m_device, {&descriptor_set.layout_});
1464 ASSERT_VK_SUCCESS(g_pipe.CreateGraphicsPipeline());
1465
1466 m_commandBuffer->reset();
1467 m_commandBuffer->begin();
1468 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1469 VkDeviceSize offset = 0;
1470 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1471
1472 VkViewport viewport = {0, 0, 16, 16, 0, 1};
1473 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1474 VkRect2D scissor = {{0, 0}, {16, 16}};
1475 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1476
1477 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1478 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1479 &descriptor_set.set_, 0, nullptr);
1480 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1481 m_commandBuffer->EndRenderPass();
1482 m_commandBuffer->end();
1483 m_errorMonitor->VerifyNotFound();
1484
1485 m_commandBuffer->reset();
1486 m_commandBuffer->begin();
1487
1488 buffer_region = {0, 0, sizeof(vbo_data)};
1489 vk::CmdCopyBuffer(m_commandBuffer->handle(), vbo2.handle(), vbo.handle(), 1, &buffer_region);
1490
1491 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1492 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1493 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1494 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1495 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1496 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1497 &descriptor_set.set_, 0, nullptr);
1498
1499 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1500 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1501 m_errorMonitor->VerifyFound();
1502
1503 m_commandBuffer->EndRenderPass();
1504 m_commandBuffer->end();
1505
John Zulaufbe8562b2020-12-15 14:21:01 -07001506 // Repeat the draw test with a WaitEvent to protect it.
1507 m_errorMonitor->ExpectSuccess();
1508 m_commandBuffer->reset();
1509 m_commandBuffer->begin();
1510
1511 vk::CmdCopyBuffer(m_commandBuffer->handle(), vbo2.handle(), vbo.handle(), 1, &buffer_region);
1512
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07001513 auto vbo_barrier = LvlInitStruct<VkBufferMemoryBarrier>();
John Zulaufbe8562b2020-12-15 14:21:01 -07001514 vbo_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1515 vbo_barrier.dstAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
1516 vbo_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1517 vbo_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1518 vbo_barrier.buffer = vbo.handle();
1519 vbo_barrier.offset = buffer_region.dstOffset;
1520 vbo_barrier.size = buffer_region.size;
1521
1522 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
1523
1524 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1525 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1526 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1527 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1528 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1529 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1530 &descriptor_set.set_, 0, nullptr);
1531
1532 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0, nullptr, 1,
1533 &vbo_barrier, 0, nullptr);
1534 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1535
1536 m_commandBuffer->EndRenderPass();
1537 m_commandBuffer->end();
1538 m_errorMonitor->VerifyNotFound();
1539
Jeremy Gebben170781d2020-11-19 16:21:21 -07001540 // DrawIndexed
1541 m_errorMonitor->ExpectSuccess();
1542 const float ibo_data[3] = {0.f, 0.f, 0.f};
1543 VkBufferObj ibo, ibo2;
1544 buffer_usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1545 ibo.init(*m_device, ibo.create_info(sizeof(ibo_data), buffer_usage, nullptr), mem_prop);
1546 ibo2.init(*m_device, ibo2.create_info(sizeof(ibo_data), buffer_usage, nullptr), mem_prop);
1547
1548 m_commandBuffer->reset();
1549 m_commandBuffer->begin();
1550 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1551 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1552 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), ibo.handle(), 0, VK_INDEX_TYPE_UINT16);
1553 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1554 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1555
1556 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1557 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1558 &descriptor_set.set_, 0, nullptr);
1559 m_commandBuffer->DrawIndexed(3, 1, 0, 0, 0);
1560 m_commandBuffer->EndRenderPass();
1561 m_commandBuffer->end();
1562 m_errorMonitor->VerifyNotFound();
1563
1564 m_commandBuffer->reset();
1565 m_commandBuffer->begin();
1566
1567 buffer_region = {0, 0, sizeof(ibo_data)};
1568 vk::CmdCopyBuffer(m_commandBuffer->handle(), ibo2.handle(), ibo.handle(), 1, &buffer_region);
1569
1570 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1571 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1572 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), ibo.handle(), 0, VK_INDEX_TYPE_UINT16);
1573 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1574 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1575 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1576 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1577 &descriptor_set.set_, 0, nullptr);
1578
1579 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1580 m_commandBuffer->DrawIndexed(3, 1, 0, 0, 0);
1581 m_errorMonitor->VerifyFound();
1582
1583 m_commandBuffer->EndRenderPass();
1584 m_commandBuffer->end();
1585
1586 // DrawIndirect
1587 m_errorMonitor->ExpectSuccess();
1588 VkBufferObj buffer_drawIndirect, buffer_drawIndirect2;
1589 buffer_usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1590 buffer_drawIndirect.init(*m_device, buffer_drawIndirect.create_info(sizeof(VkDrawIndirectCommand), buffer_usage, nullptr),
1591 mem_prop);
1592 buffer_drawIndirect2.init(*m_device, buffer_drawIndirect2.create_info(sizeof(VkDrawIndirectCommand), buffer_usage, nullptr),
1593 mem_prop);
1594
1595 m_commandBuffer->reset();
1596 m_commandBuffer->begin();
1597 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1598 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1599 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1600 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1601
1602 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1603 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1604 &descriptor_set.set_, 0, nullptr);
1605 vk::CmdDrawIndirect(m_commandBuffer->handle(), buffer_drawIndirect.handle(), 0, 1, sizeof(VkDrawIndirectCommand));
1606 m_commandBuffer->EndRenderPass();
1607 m_commandBuffer->end();
1608 m_errorMonitor->VerifyNotFound();
1609
1610 m_commandBuffer->reset();
1611 m_commandBuffer->begin();
1612
1613 buffer_region = {0, 0, sizeof(VkDrawIndirectCommand)};
1614 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_drawIndirect2.handle(), buffer_drawIndirect.handle(), 1, &buffer_region);
1615
1616 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1617 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1618 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1619 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1620 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1621 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1622 &descriptor_set.set_, 0, nullptr);
1623
1624 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1625 vk::CmdDrawIndirect(m_commandBuffer->handle(), buffer_drawIndirect.handle(), 0, 1, sizeof(VkDrawIndirectCommand));
1626 m_errorMonitor->VerifyFound();
1627
1628 m_commandBuffer->EndRenderPass();
1629 m_commandBuffer->end();
1630
1631 // DrawIndexedIndirect
1632 m_errorMonitor->ExpectSuccess();
1633 VkBufferObj buffer_drawIndexedIndirect, buffer_drawIndexedIndirect2;
1634 buffer_usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1635 buffer_drawIndexedIndirect.init(
1636 *m_device, buffer_drawIndexedIndirect.create_info(sizeof(VkDrawIndexedIndirectCommand), buffer_usage, nullptr), mem_prop);
1637 buffer_drawIndexedIndirect2.init(
1638 *m_device, buffer_drawIndexedIndirect2.create_info(sizeof(VkDrawIndexedIndirectCommand), buffer_usage, nullptr), mem_prop);
1639
1640 m_commandBuffer->reset();
1641 m_commandBuffer->begin();
1642 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1643 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1644 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), ibo.handle(), 0, VK_INDEX_TYPE_UINT16);
1645 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1646 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1647
1648 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1649 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1650 &descriptor_set.set_, 0, nullptr);
1651 vk::CmdDrawIndexedIndirect(m_commandBuffer->handle(), buffer_drawIndirect.handle(), 0, 1, sizeof(VkDrawIndexedIndirectCommand));
1652 m_commandBuffer->EndRenderPass();
1653 m_commandBuffer->end();
1654 m_errorMonitor->VerifyNotFound();
1655
1656 m_commandBuffer->reset();
1657 m_commandBuffer->begin();
1658
1659 buffer_region = {0, 0, sizeof(VkDrawIndexedIndirectCommand)};
1660 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_drawIndexedIndirect2.handle(), buffer_drawIndexedIndirect.handle(), 1,
1661 &buffer_region);
1662
1663 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1664 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1665 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), ibo.handle(), 0, VK_INDEX_TYPE_UINT16);
1666 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1667 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1668 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1669 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1670 &descriptor_set.set_, 0, nullptr);
1671
1672 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1673 vk::CmdDrawIndexedIndirect(m_commandBuffer->handle(), buffer_drawIndexedIndirect.handle(), 0, 1,
1674 sizeof(VkDrawIndexedIndirectCommand));
1675 m_errorMonitor->VerifyFound();
1676
1677 m_commandBuffer->EndRenderPass();
1678 m_commandBuffer->end();
1679
1680 if (has_khr_indirect) {
1681 // DrawIndirectCount
1682 auto fpCmdDrawIndirectCountKHR =
1683 (PFN_vkCmdDrawIndirectCount)vk::GetDeviceProcAddr(m_device->device(), "vkCmdDrawIndirectCountKHR");
1684 if (!fpCmdDrawIndirectCountKHR) {
1685 printf("%s Test requires unsupported vkCmdDrawIndirectCountKHR feature. Skipped.\n", kSkipPrefix);
1686 } else {
1687 m_errorMonitor->ExpectSuccess();
1688 VkBufferObj buffer_count, buffer_count2;
1689 buffer_usage =
1690 VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1691 buffer_count.init(*m_device, buffer_count.create_info(sizeof(uint32_t), buffer_usage, nullptr), mem_prop);
1692 buffer_count2.init(*m_device, buffer_count2.create_info(sizeof(uint32_t), buffer_usage, nullptr), mem_prop);
1693
1694 m_commandBuffer->reset();
1695 m_commandBuffer->begin();
1696 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1697 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1698 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1699 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1700
1701 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1702 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(),
1703 0, 1, &descriptor_set.set_, 0, nullptr);
1704 fpCmdDrawIndirectCountKHR(m_commandBuffer->handle(), buffer_drawIndirect.handle(), 0, buffer_count.handle(), 0, 1,
1705 sizeof(VkDrawIndirectCommand));
1706 m_commandBuffer->EndRenderPass();
1707 m_commandBuffer->end();
1708 m_errorMonitor->VerifyNotFound();
1709
1710 m_commandBuffer->reset();
1711 m_commandBuffer->begin();
1712
1713 buffer_region = {0, 0, sizeof(uint32_t)};
1714 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_count2.handle(), buffer_count.handle(), 1, &buffer_region);
1715
1716 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1717 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1718 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1719 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1720 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1721 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(),
1722 0, 1, &descriptor_set.set_, 0, nullptr);
1723
1724 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1725 fpCmdDrawIndirectCountKHR(m_commandBuffer->handle(), buffer_drawIndirect.handle(), 0, buffer_count.handle(), 0, 1,
1726 sizeof(VkDrawIndirectCommand));
1727 m_errorMonitor->VerifyFound();
1728
1729 m_commandBuffer->EndRenderPass();
1730 m_commandBuffer->end();
1731 }
1732
1733 // DrawIndexedIndirectCount
1734 auto fpCmdDrawIndexIndirectCountKHR =
1735 (PFN_vkCmdDrawIndirectCount)vk::GetDeviceProcAddr(m_device->device(), "vkCmdDrawIndexedIndirectCountKHR");
1736 if (!fpCmdDrawIndexIndirectCountKHR) {
1737 printf("%s Test requires unsupported vkCmdDrawIndexedIndirectCountKHR feature. Skipped.\n", kSkipPrefix);
1738 } else {
1739 m_errorMonitor->ExpectSuccess();
1740 VkBufferObj buffer_count, buffer_count2;
1741 buffer_usage =
1742 VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1743 buffer_count.init(*m_device, buffer_count.create_info(sizeof(uint32_t), buffer_usage, nullptr), mem_prop);
1744 buffer_count2.init(*m_device, buffer_count2.create_info(sizeof(uint32_t), buffer_usage, nullptr), mem_prop);
1745
1746 m_commandBuffer->reset();
1747 m_commandBuffer->begin();
1748 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1749 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1750 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), ibo.handle(), 0, VK_INDEX_TYPE_UINT16);
1751 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1752 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1753
1754 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1755 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(),
1756 0, 1, &descriptor_set.set_, 0, nullptr);
1757 fpCmdDrawIndexIndirectCountKHR(m_commandBuffer->handle(), buffer_drawIndexedIndirect.handle(), 0, buffer_count.handle(),
1758 0, 1, sizeof(VkDrawIndexedIndirectCommand));
1759 m_commandBuffer->EndRenderPass();
1760 m_commandBuffer->end();
1761 m_errorMonitor->VerifyNotFound();
1762
1763 m_commandBuffer->reset();
1764 m_commandBuffer->begin();
1765
1766 buffer_region = {0, 0, sizeof(uint32_t)};
1767 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_count2.handle(), buffer_count.handle(), 1, &buffer_region);
1768
1769 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1770 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1771 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), ibo.handle(), 0, VK_INDEX_TYPE_UINT16);
1772 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1773 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1774 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1775 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(),
1776 0, 1, &descriptor_set.set_, 0, nullptr);
1777
1778 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1779 fpCmdDrawIndexIndirectCountKHR(m_commandBuffer->handle(), buffer_drawIndexedIndirect.handle(), 0, buffer_count.handle(),
1780 0, 1, sizeof(VkDrawIndexedIndirectCommand));
1781 m_errorMonitor->VerifyFound();
1782
1783 m_commandBuffer->EndRenderPass();
1784 m_commandBuffer->end();
1785 }
1786 } else {
1787 printf("%s Test requires unsupported vkCmdDrawIndirectCountKHR & vkDrawIndexedIndirectCountKHR feature. Skipped.\n",
1788 kSkipPrefix);
1789 }
1790}
1791
1792TEST_F(VkSyncValTest, SyncCmdClear) {
1793 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
1794 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
1795 // CmdClearColorImage
1796 m_errorMonitor->ExpectSuccess();
1797 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1798 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
1799 VkImageObj image_a(m_device), image_b(m_device);
1800 auto image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 1, format, usage, VK_IMAGE_TILING_OPTIMAL);
1801 image_a.Init(image_ci);
1802 image_b.Init(image_ci);
1803
1804 VkImageSubresourceLayers layers_all{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
1805 VkOffset3D zero_offset{0, 0, 0};
1806 VkExtent3D full_extent{128, 128, 1}; // <-- image type is 2D
1807 VkImageSubresourceRange full_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
1808
1809 VkImageCopy full_region = {layers_all, zero_offset, layers_all, zero_offset, full_extent};
1810
1811 m_commandBuffer->begin();
1812
1813 image_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1814 image_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1815
1816 auto cb = m_commandBuffer->handle();
1817 VkClearColorValue ccv = {};
1818 vk::CmdClearColorImage(m_commandBuffer->handle(), image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &full_subresource_range);
1819 m_commandBuffer->end();
1820 m_errorMonitor->VerifyNotFound();
1821
1822 m_commandBuffer->reset();
1823 m_commandBuffer->begin();
1824 vk::CmdCopyImage(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
1825
1826 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1827 vk::CmdClearColorImage(m_commandBuffer->handle(), image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &full_subresource_range);
1828 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1829 vk::CmdClearColorImage(m_commandBuffer->handle(), image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &full_subresource_range);
1830 m_errorMonitor->VerifyFound();
1831
1832 m_commandBuffer->end();
1833
1834 // CmdClearDepthStencilImage
1835 format = FindSupportedDepthStencilFormat(gpu());
1836 if (!format) {
1837 printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix);
1838 return;
1839 }
1840 m_errorMonitor->ExpectSuccess();
1841 VkImageObj image_ds_a(m_device), image_ds_b(m_device);
1842 image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 1, format, usage, VK_IMAGE_TILING_OPTIMAL);
1843 image_ds_a.Init(image_ci);
1844 image_ds_b.Init(image_ci);
1845
1846 const VkImageAspectFlags ds_aspect = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
1847 image_ds_a.SetLayout(ds_aspect, VK_IMAGE_LAYOUT_GENERAL);
1848 image_ds_b.SetLayout(ds_aspect, VK_IMAGE_LAYOUT_GENERAL);
1849
1850 m_commandBuffer->begin();
1851 const VkClearDepthStencilValue clear_value = {};
1852 VkImageSubresourceRange ds_range = {ds_aspect, 0, 1, 0, 1};
1853
1854 vk::CmdClearDepthStencilImage(cb, image_ds_a.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1, &ds_range);
1855 m_commandBuffer->end();
1856 m_errorMonitor->VerifyNotFound();
1857
1858 VkImageSubresourceLayers ds_layers_all{ds_aspect, 0, 0, 1};
1859 VkImageCopy ds_full_region = {ds_layers_all, zero_offset, ds_layers_all, zero_offset, full_extent};
1860
1861 m_commandBuffer->reset();
1862 m_commandBuffer->begin();
1863 vk::CmdCopyImage(cb, image_ds_a.handle(), VK_IMAGE_LAYOUT_GENERAL, image_ds_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1864 &ds_full_region);
1865
1866 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1867 vk::CmdClearDepthStencilImage(m_commandBuffer->handle(), image_ds_a.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1,
1868 &ds_range);
1869 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1870 vk::CmdClearDepthStencilImage(m_commandBuffer->handle(), image_ds_b.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1,
1871 &ds_range);
1872 m_errorMonitor->VerifyFound();
1873
1874 m_commandBuffer->end();
1875}
1876
1877TEST_F(VkSyncValTest, SyncCmdQuery) {
1878 // CmdCopyQueryPoolResults
1879 m_errorMonitor->ExpectSuccess();
1880 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
1881 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
1882 if (IsPlatform(kNexusPlayer)) {
1883 printf("%s This test should not run on Nexus Player\n", kSkipPrefix);
1884 return;
1885 }
1886 if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) {
1887 printf("%s Queue family needs to have multiple queues to run this test.\n", kSkipPrefix);
1888 return;
1889 }
1890 uint32_t queue_count;
1891 vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_count, NULL);
Jeremy Gebbend2573fc2021-05-12 17:17:38 -06001892 std::vector<VkQueueFamilyProperties> queue_props(queue_count);
1893 vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_count, queue_props.data());
Jeremy Gebben170781d2020-11-19 16:21:21 -07001894 if (queue_props[m_device->graphics_queue_node_index_].timestampValidBits == 0) {
1895 printf("%s Device graphic queue has timestampValidBits of 0, skipping.\n", kSkipPrefix);
1896 return;
1897 }
1898
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001899 vk_testing::QueryPool query_pool;
Jeremy Gebben170781d2020-11-19 16:21:21 -07001900 VkQueryPoolCreateInfo query_pool_create_info{};
1901 query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
1902 query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
1903 query_pool_create_info.queryCount = 1;
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001904 query_pool.init(*m_device, query_pool_create_info);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001905
1906 VkBufferObj buffer_a, buffer_b;
1907 VkMemoryPropertyFlags mem_prop = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
1908 buffer_a.init_as_src_and_dst(*m_device, 256, mem_prop);
1909 buffer_b.init_as_src_and_dst(*m_device, 256, mem_prop);
1910
1911 VkBufferCopy region = {0, 0, 256};
1912
1913 auto cb = m_commandBuffer->handle();
1914 m_commandBuffer->begin();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001915 vk::CmdResetQueryPool(cb, query_pool.handle(), 0, 1);
1916 vk::CmdWriteTimestamp(cb, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool.handle(), 0);
1917 vk::CmdCopyQueryPoolResults(cb, query_pool.handle(), 0, 1, buffer_a.handle(), 0, 0, VK_QUERY_RESULT_WAIT_BIT);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001918 m_commandBuffer->end();
1919 m_errorMonitor->VerifyNotFound();
1920
1921 m_commandBuffer->reset();
1922 m_commandBuffer->begin();
1923 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &region);
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001924 vk::CmdResetQueryPool(cb, query_pool.handle(), 0, 1);
1925 vk::CmdWriteTimestamp(cb, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool.handle(), 0);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001926 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001927 vk::CmdCopyQueryPoolResults(cb, query_pool.handle(), 0, 1, buffer_a.handle(), 0, 256, VK_QUERY_RESULT_WAIT_BIT);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001928 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001929 vk::CmdCopyQueryPoolResults(cb, query_pool.handle(), 0, 1, buffer_b.handle(), 0, 256, VK_QUERY_RESULT_WAIT_BIT);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001930 m_commandBuffer->end();
1931 m_errorMonitor->VerifyFound();
1932
1933 // TODO:Track VkQueryPool
1934 // TODO:CmdWriteTimestamp
Jeremy Gebben170781d2020-11-19 16:21:21 -07001935}
1936
1937TEST_F(VkSyncValTest, SyncCmdDrawDepthStencil) {
1938 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
1939 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
1940 m_errorMonitor->ExpectSuccess();
1941
1942 const auto format_ds = FindSupportedDepthStencilFormat(gpu());
1943 if (!format_ds) {
1944 printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix);
1945 return;
1946 }
1947 const auto format_dp = FindSupportedDepthOnlyFormat(gpu());
1948 if (!format_dp) {
1949 printf("%s No only Depth format found. Skipped.\n", kSkipPrefix);
1950 return;
1951 }
1952 const auto format_st = FindSupportedStencilOnlyFormat(gpu());
1953 if (!format_st) {
1954 printf("%s No only Stencil format found. Skipped.\n", kSkipPrefix);
1955 return;
1956 }
1957
1958 VkDepthStencilObj image_ds(m_device), image_dp(m_device), image_st(m_device);
1959 image_ds.Init(m_device, 16, 16, format_ds);
1960 image_dp.Init(m_device, 16, 16, format_dp);
1961 image_st.Init(m_device, 16, 16, format_st);
1962
1963 VkRenderpassObj rp_ds(m_device, format_ds, true), rp_dp(m_device, format_dp, true), rp_st(m_device, format_st, true);
1964
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001965 vk_testing::Framebuffer fb_ds, fb_dp, fb_st;
Jeremy Gebben170781d2020-11-19 16:21:21 -07001966 VkFramebufferCreateInfo fbci = {
1967 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp_ds.handle(), 1, image_ds.BindInfo(), 16, 16, 1};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001968 fb_ds.init(*m_device, fbci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001969 fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp_dp.handle(), 1, image_dp.BindInfo(), 16, 16, 1};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001970 fb_dp.init(*m_device, fbci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001971 fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp_st.handle(), 1, image_st.BindInfo(), 16, 16, 1};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001972 fb_st.init(*m_device, fbci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001973
1974 VkStencilOpState stencil = {};
1975 stencil.failOp = VK_STENCIL_OP_KEEP;
1976 stencil.passOp = VK_STENCIL_OP_KEEP;
1977 stencil.depthFailOp = VK_STENCIL_OP_KEEP;
1978 stencil.compareOp = VK_COMPARE_OP_NEVER;
1979
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07001980 auto ds_ci = LvlInitStruct<VkPipelineDepthStencilStateCreateInfo>();
Jeremy Gebben170781d2020-11-19 16:21:21 -07001981 ds_ci.depthTestEnable = VK_TRUE;
1982 ds_ci.depthWriteEnable = VK_TRUE;
1983 ds_ci.depthCompareOp = VK_COMPARE_OP_NEVER;
1984 ds_ci.stencilTestEnable = VK_TRUE;
1985 ds_ci.front = stencil;
1986 ds_ci.back = stencil;
1987
1988 CreatePipelineHelper g_pipe_ds(*this), g_pipe_dp(*this), g_pipe_st(*this);
1989 g_pipe_ds.InitInfo();
1990 g_pipe_ds.gp_ci_.renderPass = rp_ds.handle();
1991 g_pipe_ds.gp_ci_.pDepthStencilState = &ds_ci;
1992 g_pipe_ds.InitState();
1993 ASSERT_VK_SUCCESS(g_pipe_ds.CreateGraphicsPipeline());
1994 g_pipe_dp.InitInfo();
1995 g_pipe_dp.gp_ci_.renderPass = rp_dp.handle();
1996 ds_ci.stencilTestEnable = VK_FALSE;
1997 g_pipe_dp.gp_ci_.pDepthStencilState = &ds_ci;
1998 g_pipe_dp.InitState();
1999 ASSERT_VK_SUCCESS(g_pipe_dp.CreateGraphicsPipeline());
2000 g_pipe_st.InitInfo();
2001 g_pipe_st.gp_ci_.renderPass = rp_st.handle();
2002 ds_ci.depthTestEnable = VK_FALSE;
2003 ds_ci.stencilTestEnable = VK_TRUE;
2004 g_pipe_st.gp_ci_.pDepthStencilState = &ds_ci;
2005 g_pipe_st.InitState();
2006 ASSERT_VK_SUCCESS(g_pipe_st.CreateGraphicsPipeline());
2007
2008 m_commandBuffer->begin();
2009 m_renderPassBeginInfo.renderArea = {{0, 0}, {16, 16}};
2010 m_renderPassBeginInfo.pClearValues = nullptr;
2011 m_renderPassBeginInfo.clearValueCount = 0;
2012
2013 m_renderPassBeginInfo.renderPass = rp_ds.handle();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002014 m_renderPassBeginInfo.framebuffer = fb_ds.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002015 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2016 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_ds.pipeline_);
2017 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
2018 m_commandBuffer->EndRenderPass();
2019
2020 m_renderPassBeginInfo.renderPass = rp_dp.handle();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002021 m_renderPassBeginInfo.framebuffer = fb_dp.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002022 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2023 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_dp.pipeline_);
2024 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
2025 m_commandBuffer->EndRenderPass();
2026
2027 m_renderPassBeginInfo.renderPass = rp_st.handle();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002028 m_renderPassBeginInfo.framebuffer = fb_st.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002029 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2030 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_st.pipeline_);
2031 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
2032 m_commandBuffer->EndRenderPass();
2033
2034 m_commandBuffer->end();
2035 m_errorMonitor->VerifyNotFound();
2036
2037 m_commandBuffer->reset();
2038 m_commandBuffer->begin();
2039
2040 VkImageCopy copyRegion;
2041 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
2042 copyRegion.srcSubresource.mipLevel = 0;
2043 copyRegion.srcSubresource.baseArrayLayer = 0;
2044 copyRegion.srcSubresource.layerCount = 1;
2045 copyRegion.srcOffset = {0, 0, 0};
2046 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
2047 copyRegion.dstSubresource.mipLevel = 0;
2048 copyRegion.dstSubresource.baseArrayLayer = 0;
2049 copyRegion.dstSubresource.layerCount = 1;
2050 copyRegion.dstOffset = {0, 0, 0};
2051 copyRegion.extent = {16, 16, 1};
2052
2053 m_commandBuffer->CopyImage(image_ds.handle(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, image_dp.handle(),
2054 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 1, &copyRegion);
2055
2056 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
2057 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
2058 m_commandBuffer->CopyImage(image_ds.handle(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, image_st.handle(),
2059 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 1, &copyRegion);
2060 m_renderPassBeginInfo.renderPass = rp_ds.handle();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002061 m_renderPassBeginInfo.framebuffer = fb_ds.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002062 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
2063 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2064 m_errorMonitor->VerifyFound();
2065 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2066 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_ds.pipeline_);
2067 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
2068 m_commandBuffer->EndRenderPass();
2069
2070 m_renderPassBeginInfo.renderPass = rp_dp.handle();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002071 m_renderPassBeginInfo.framebuffer = fb_dp.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002072 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
2073 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2074 m_errorMonitor->VerifyFound();
2075 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2076 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_dp.pipeline_);
2077 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
2078 m_commandBuffer->EndRenderPass();
2079
2080 m_renderPassBeginInfo.renderPass = rp_st.handle();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002081 m_renderPassBeginInfo.framebuffer = fb_st.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002082 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
2083 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2084 m_errorMonitor->VerifyFound();
2085 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2086 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_st.pipeline_);
2087 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
2088 m_commandBuffer->EndRenderPass();
2089
2090 m_commandBuffer->end();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002091}
2092
John Zulaufd57a36b2021-08-16 10:34:44 -06002093
Jeremy Gebben170781d2020-11-19 16:21:21 -07002094TEST_F(VkSyncValTest, RenderPassLoadHazardVsInitialLayout) {
2095 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
John Zulaufd57a36b2021-08-16 10:34:44 -06002096 bool do_none_load_op_test = false;
2097 if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_LOAD_STORE_OP_NONE_EXTENSION_NAME)) {
2098 m_device_extension_names.push_back(VK_EXT_LOAD_STORE_OP_NONE_EXTENSION_NAME);
2099 do_none_load_op_test = true;
2100 }
2101
Jeremy Gebben170781d2020-11-19 16:21:21 -07002102 ASSERT_NO_FATAL_FAILURE(InitState());
2103 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2104
2105 VkImageUsageFlags usage_color = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
2106 VkImageUsageFlags usage_input = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
2107 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
2108 VkImageObj image_color(m_device), image_input(m_device);
2109 auto image_ci = VkImageObj::ImageCreateInfo2D(32, 32, 1, 1, format, usage_color, VK_IMAGE_TILING_OPTIMAL);
2110 image_color.Init(image_ci);
2111 image_ci.usage = usage_input;
2112 image_input.Init(image_ci);
2113 VkImageView attachments[] = {image_color.targetView(format), image_input.targetView(format)};
2114
John Zulaufd57a36b2021-08-16 10:34:44 -06002115 VkAttachmentDescription attachmentDescriptions[] = {
Jeremy Gebben170781d2020-11-19 16:21:21 -07002116 // Result attachment
2117 {(VkAttachmentDescriptionFlags)0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR,
2118 VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
2119 VK_IMAGE_LAYOUT_UNDEFINED, // Here causes DesiredError that SYNC-HAZARD-NONE in BeginRenderPass.
2120 // It should be VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
2121 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
2122 // Input attachment
2123 {(VkAttachmentDescriptionFlags)0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD,
2124 VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
2125 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL}};
2126
2127 const VkAttachmentReference resultAttachmentRef = {0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
2128 const VkAttachmentReference inputAttachmentRef = {1u, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};
2129
2130 const VkSubpassDescription subpassDescription = {(VkSubpassDescriptionFlags)0,
2131 VK_PIPELINE_BIND_POINT_GRAPHICS,
2132 1u,
2133 &inputAttachmentRef,
2134 1u,
2135 &resultAttachmentRef,
2136 0,
2137 0,
2138 0u,
2139 0};
2140
2141 const VkSubpassDependency subpassDependency = {VK_SUBPASS_EXTERNAL,
2142 0,
2143 VK_PIPELINE_STAGE_TRANSFER_BIT,
2144 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
2145 VK_ACCESS_TRANSFER_WRITE_BIT,
2146 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | VK_ACCESS_SHADER_READ_BIT,
2147 VK_DEPENDENCY_BY_REGION_BIT};
2148
2149 const VkRenderPassCreateInfo renderPassInfo = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
2150 0,
2151 (VkRenderPassCreateFlags)0,
2152 2u,
2153 attachmentDescriptions,
2154 1u,
2155 &subpassDescription,
2156 1u,
2157 &subpassDependency};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002158 vk_testing::RenderPass rp;
2159 rp.init(*m_device, renderPassInfo);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002160
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002161 vk_testing::Framebuffer fb;
2162 VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp.handle(), 2, attachments, 32, 32, 1};
2163 fb.init(*m_device, fbci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002164
2165 image_input.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
2166
2167 m_commandBuffer->begin();
2168
2169 m_renderPassBeginInfo.renderArea = {{0, 0}, {32, 32}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002170 m_renderPassBeginInfo.renderPass = rp.handle();
2171 m_renderPassBeginInfo.framebuffer = fb.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002172
2173 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
2174 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
2175 // Even though we have no accesses prior, the layout transition *is* an access, so load can be validated vs. layout transition
2176 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2177 m_errorMonitor->VerifyFound();
John Zulaufd57a36b2021-08-16 10:34:44 -06002178
2179 vk_testing::RenderPass rp_no_load_store;
2180 if (do_none_load_op_test) {
2181 m_errorMonitor->ExpectSuccess();
2182 attachmentDescriptions[0].loadOp = VK_ATTACHMENT_LOAD_OP_NONE_EXT;
2183 attachmentDescriptions[0].storeOp = VK_ATTACHMENT_STORE_OP_NONE_EXT;
2184 attachmentDescriptions[1].loadOp = VK_ATTACHMENT_LOAD_OP_NONE_EXT;
2185 attachmentDescriptions[1].storeOp = VK_ATTACHMENT_STORE_OP_NONE_EXT;
2186 rp_no_load_store.init(*m_device, renderPassInfo);
2187 m_renderPassBeginInfo.renderPass = rp_no_load_store.handle();
2188 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2189 m_commandBuffer->EndRenderPass();
2190 m_errorMonitor->VerifyNotFound();
2191 } else {
2192 printf("%s VK_EXT_load_store_op_none not supported, skipping sub-test\n", kSkipPrefix);
2193 }
Jeremy Gebben170781d2020-11-19 16:21:21 -07002194}
2195
2196TEST_F(VkSyncValTest, SyncRenderPassWithWrongDepthStencilInitialLayout) {
2197 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
2198 ASSERT_NO_FATAL_FAILURE(InitState());
2199 if (IsPlatform(kNexusPlayer)) {
2200 printf("%s This test should not run on Nexus Player\n", kSkipPrefix);
2201 return;
2202 }
2203
2204 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2205
2206 VkFormat color_format = VK_FORMAT_R8G8B8A8_UNORM;
2207 VkFormat ds_format = FindSupportedDepthStencilFormat(gpu());
2208 if (!ds_format) {
2209 printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix);
2210 return;
2211 }
2212 VkImageUsageFlags usage_color = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
2213 VkImageUsageFlags usage_ds = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
2214 VkImageObj image_color(m_device), image_color2(m_device);
2215 auto image_ci = VkImageObj::ImageCreateInfo2D(32, 32, 1, 1, color_format, usage_color, VK_IMAGE_TILING_OPTIMAL);
2216 image_color.Init(image_ci);
2217 image_color2.Init(image_ci);
2218 VkDepthStencilObj image_ds(m_device);
2219 image_ds.Init(m_device, 32, 32, ds_format, usage_ds);
2220
2221 const VkAttachmentDescription colorAttachmentDescription = {(VkAttachmentDescriptionFlags)0,
2222 color_format,
2223 VK_SAMPLE_COUNT_1_BIT,
2224 VK_ATTACHMENT_LOAD_OP_CLEAR,
2225 VK_ATTACHMENT_STORE_OP_STORE,
2226 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2227 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2228 VK_IMAGE_LAYOUT_UNDEFINED,
2229 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
2230
2231 const VkAttachmentDescription depthStencilAttachmentDescription = {
2232 (VkAttachmentDescriptionFlags)0, ds_format, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR,
2233 VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE,
2234 VK_IMAGE_LAYOUT_UNDEFINED, // Here causes DesiredError that SYNC-HAZARD-WRITE_AFTER_WRITE in BeginRenderPass.
2235 // It should be VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
2236 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
2237
2238 std::vector<VkAttachmentDescription> attachmentDescriptions;
2239 attachmentDescriptions.push_back(colorAttachmentDescription);
2240 attachmentDescriptions.push_back(depthStencilAttachmentDescription);
2241
2242 const VkAttachmentReference colorAttachmentRef = {0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
2243
2244 const VkAttachmentReference depthStencilAttachmentRef = {1u, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
2245
2246 const VkSubpassDescription subpassDescription = {(VkSubpassDescriptionFlags)0,
2247 VK_PIPELINE_BIND_POINT_GRAPHICS,
2248 0u,
2249 0,
2250 1u,
2251 &colorAttachmentRef,
2252 0,
2253 &depthStencilAttachmentRef,
2254 0u,
2255 0};
2256
2257 const VkRenderPassCreateInfo renderPassInfo = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
2258 0,
2259 (VkRenderPassCreateFlags)0,
2260 (uint32_t)attachmentDescriptions.size(),
2261 &attachmentDescriptions[0],
2262 1u,
2263 &subpassDescription,
2264 0u,
2265 0};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002266 vk_testing::RenderPass rp;
2267 rp.init(*m_device, renderPassInfo);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002268
2269 VkImageView fb_attachments[] = {image_color.targetView(color_format),
2270 image_ds.targetView(ds_format, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)};
2271 const VkFramebufferCreateInfo fbci = {
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002272 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, 0, 0u, rp.handle(), 2u, fb_attachments, 32, 32, 1u,
Jeremy Gebben170781d2020-11-19 16:21:21 -07002273 };
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002274 vk_testing::Framebuffer fb;
2275 fb.init(*m_device, fbci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002276 fb_attachments[0] = image_color2.targetView(color_format);
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002277 vk_testing::Framebuffer fb1;
2278 fb1.init(*m_device, fbci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002279
2280 CreatePipelineHelper g_pipe(*this);
2281 g_pipe.InitInfo();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002282 g_pipe.gp_ci_.renderPass = rp.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002283
2284 VkStencilOpState stencil = {};
2285 stencil.failOp = VK_STENCIL_OP_KEEP;
2286 stencil.passOp = VK_STENCIL_OP_KEEP;
2287 stencil.depthFailOp = VK_STENCIL_OP_KEEP;
2288 stencil.compareOp = VK_COMPARE_OP_NEVER;
2289
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07002290 auto ds_ci = LvlInitStruct<VkPipelineDepthStencilStateCreateInfo>();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002291 ds_ci.depthTestEnable = VK_TRUE;
2292 ds_ci.depthWriteEnable = VK_TRUE;
2293 ds_ci.depthCompareOp = VK_COMPARE_OP_NEVER;
2294 ds_ci.stencilTestEnable = VK_TRUE;
2295 ds_ci.front = stencil;
2296 ds_ci.back = stencil;
2297
2298 g_pipe.gp_ci_.pDepthStencilState = &ds_ci;
2299 g_pipe.InitState();
2300 ASSERT_VK_SUCCESS(g_pipe.CreateGraphicsPipeline());
2301
2302 m_commandBuffer->begin();
Tony-LunarG73f37032021-06-07 11:47:03 -06002303 VkClearValue clear = {};
2304 std::array<VkClearValue, 2> clear_values = { {clear, clear} };
2305 m_renderPassBeginInfo.pClearValues = clear_values.data();
2306 m_renderPassBeginInfo.clearValueCount = clear_values.size();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002307 m_renderPassBeginInfo.renderArea = {{0, 0}, {32, 32}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002308 m_renderPassBeginInfo.renderPass = rp.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002309
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002310 m_renderPassBeginInfo.framebuffer = fb.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002311 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2312 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
2313 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
2314 m_commandBuffer->EndRenderPass();
2315
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002316 m_renderPassBeginInfo.framebuffer = fb1.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002317
2318 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
2319 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2320 m_errorMonitor->VerifyFound();
2321}
2322
2323TEST_F(VkSyncValTest, SyncLayoutTransition) {
2324 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
2325 ASSERT_NO_FATAL_FAILURE(InitState());
2326 if (IsPlatform(kNexusPlayer)) {
2327 printf("%s This test should not run on Nexus Player\n", kSkipPrefix);
2328 return;
2329 }
2330
2331 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2332
2333 VkImageUsageFlags usage_color = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
2334 VkImageUsageFlags usage_input =
2335 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
2336 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
2337 VkImageObj image_color(m_device), image_input(m_device);
2338 auto image_ci = VkImageObj::ImageCreateInfo2D(64, 64, 1, 1, format, usage_input, VK_IMAGE_TILING_OPTIMAL);
2339 image_input.InitNoLayout(image_ci);
2340 image_ci.usage = usage_color;
2341 image_color.InitNoLayout(image_ci);
2342 VkImageView view_input = image_input.targetView(format);
2343 VkImageView view_color = image_color.targetView(format);
2344 VkImageView attachments[] = {view_color, view_input};
2345
2346 const VkAttachmentDescription fbAttachment = {
2347 0u,
2348 format,
2349 VK_SAMPLE_COUNT_1_BIT,
2350 VK_ATTACHMENT_LOAD_OP_CLEAR,
2351 VK_ATTACHMENT_STORE_OP_STORE,
2352 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2353 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2354 VK_IMAGE_LAYOUT_UNDEFINED,
2355 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
2356 };
2357
2358 std::vector<VkAttachmentDescription> attachmentDescs;
2359 attachmentDescs.push_back(fbAttachment);
2360
2361 // Add it as a frame buffer attachment.
2362 const VkAttachmentDescription inputAttachment = {
2363 0u,
2364 format,
2365 VK_SAMPLE_COUNT_1_BIT,
2366 VK_ATTACHMENT_LOAD_OP_LOAD,
2367 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2368 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2369 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2370 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
2371 VK_IMAGE_LAYOUT_GENERAL,
2372 };
2373 attachmentDescs.push_back(inputAttachment);
2374
2375 std::vector<VkAttachmentReference> inputAttachments;
2376 const VkAttachmentReference inputRef = {
2377 1u,
2378 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
2379 };
2380 inputAttachments.push_back(inputRef);
2381
2382 const VkAttachmentReference colorRef = {
2383 0u,
2384 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
2385 };
2386 const std::vector<VkAttachmentReference> colorAttachments(1u, colorRef);
2387
2388 const VkSubpassDescription subpass = {
2389 0u,
2390 VK_PIPELINE_BIND_POINT_GRAPHICS,
2391 static_cast<uint32_t>(inputAttachments.size()),
2392 inputAttachments.data(),
2393 static_cast<uint32_t>(colorAttachments.size()),
2394 colorAttachments.data(),
2395 0u,
2396 nullptr,
2397 0u,
2398 nullptr,
2399 };
2400 const std::vector<VkSubpassDescription> subpasses(1u, subpass);
2401
2402 const VkRenderPassCreateInfo renderPassInfo = {
2403 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
2404 nullptr,
2405 0u,
2406 static_cast<uint32_t>(attachmentDescs.size()),
2407 attachmentDescs.data(),
2408 static_cast<uint32_t>(subpasses.size()),
2409 subpasses.data(),
2410 0u,
2411 nullptr,
2412 };
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002413 vk_testing::RenderPass rp;
2414 rp.init(*m_device, renderPassInfo);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002415
2416 const VkFramebufferCreateInfo fbci = {
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002417 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, 0, 0u, rp.handle(), 2u, attachments, 64, 64, 1u,
Jeremy Gebben170781d2020-11-19 16:21:21 -07002418 };
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002419 vk_testing::Framebuffer fb;
2420 fb.init(*m_device, fbci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002421
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002422 vk_testing::Sampler sampler;
Jeremy Gebben170781d2020-11-19 16:21:21 -07002423 VkSamplerCreateInfo sampler_info = SafeSaneSamplerCreateInfo();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002424 sampler.init(*m_device, sampler_info);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002425
sfricke-samsung1c0b96a2021-07-08 22:24:09 -07002426 char const *fsSource = R"glsl(
2427 #version 450
2428 layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;
2429 void main() {
2430 vec4 color = subpassLoad(x);
2431 }
2432 )glsl";
Jeremy Gebben170781d2020-11-19 16:21:21 -07002433
2434 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
2435 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
2436
2437 CreatePipelineHelper g_pipe(*this);
2438 g_pipe.InitInfo();
2439 g_pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
2440 g_pipe.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002441 g_pipe.gp_ci_.renderPass = rp.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002442 g_pipe.InitState();
2443 ASSERT_VK_SUCCESS(g_pipe.CreateGraphicsPipeline());
2444
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002445 g_pipe.descriptor_set_->WriteDescriptorImageInfo(0, view_input, sampler.handle(), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002446 g_pipe.descriptor_set_->UpdateDescriptorSets();
2447
2448 m_commandBuffer->begin();
2449 auto cb = m_commandBuffer->handle();
2450 VkClearColorValue ccv = {};
2451 VkImageSubresourceRange full_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
2452
2453 const VkImageMemoryBarrier preClearBarrier = {
2454 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, 0, 0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
2455 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, 0, image_input.handle(), full_subresource_range,
2456 };
2457 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u,
2458 &preClearBarrier);
2459
2460 vk::CmdClearColorImage(m_commandBuffer->handle(), image_input.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &ccv, 1,
2461 &full_subresource_range);
2462
2463 const VkImageMemoryBarrier postClearBarrier = {
2464 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
2465 0,
2466 VK_ACCESS_TRANSFER_WRITE_BIT,
2467 VK_ACCESS_SHADER_READ_BIT,
2468 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
2469 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
2470 0,
2471 0,
2472 image_input.handle(),
2473 full_subresource_range,
2474 };
2475 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u, nullptr, 0u, nullptr,
2476 1u, &postClearBarrier);
2477
2478 m_renderPassBeginInfo.renderArea = {{0, 0}, {64, 64}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002479 m_renderPassBeginInfo.renderPass = rp.handle();
2480 m_renderPassBeginInfo.framebuffer = fb.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002481
2482 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2483 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
2484 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
2485 &g_pipe.descriptor_set_->set_, 0, nullptr);
2486
2487 // Positive test for ordering rules between load and input attachment usage
2488 m_errorMonitor->ExpectSuccess();
2489 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
2490
2491 // Positive test for store ordering vs. input attachment and dependency *to* external for layout transition
2492 m_commandBuffer->EndRenderPass();
2493 m_errorMonitor->VerifyNotFound();
2494
2495 // Catch a conflict with the input attachment final layout transition
2496 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
2497 vk::CmdClearColorImage(m_commandBuffer->handle(), image_input.handle(), VK_IMAGE_LAYOUT_GENERAL, &ccv, 1,
2498 &full_subresource_range);
2499 m_errorMonitor->VerifyFound();
2500}
2501
2502TEST_F(VkSyncValTest, SyncSubpassMultiDep) {
2503 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
2504 ASSERT_NO_FATAL_FAILURE(InitState());
2505 if (IsPlatform(kNexusPlayer)) {
2506 printf("%s This test should not run on Nexus Player\n", kSkipPrefix);
2507 return;
2508 }
2509
2510 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2511
2512 VkImageUsageFlags usage_color = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
2513 VkImageUsageFlags usage_input =
2514 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
2515 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
2516 VkImageObj image_color(m_device), image_input(m_device);
2517 auto image_ci = VkImageObj::ImageCreateInfo2D(64, 64, 1, 1, format, usage_input, VK_IMAGE_TILING_OPTIMAL);
2518 image_input.InitNoLayout(image_ci);
2519 image_ci.usage = usage_color;
2520 image_color.InitNoLayout(image_ci);
2521 VkImageView view_input = image_input.targetView(format);
2522 VkImageView view_color = image_color.targetView(format);
2523 VkImageView attachments[] = {view_color, view_input};
2524 VkImageSubresourceRange full_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
2525 VkImageSubresourceLayers mip_0_layer_0{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
2526 VkOffset3D image_zero{0, 0, 0};
2527 VkExtent3D image_size{64, 64, 1};
2528 VkImageCopy full_region{mip_0_layer_0, image_zero, mip_0_layer_0, image_zero, image_size};
2529
2530 const VkAttachmentDescription fbAttachment = {
2531 0u,
2532 format,
2533 VK_SAMPLE_COUNT_1_BIT,
2534 VK_ATTACHMENT_LOAD_OP_CLEAR,
2535 VK_ATTACHMENT_STORE_OP_STORE,
2536 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2537 VK_ATTACHMENT_STORE_OP_STORE,
2538 VK_IMAGE_LAYOUT_GENERAL,
2539 VK_IMAGE_LAYOUT_GENERAL,
2540 };
2541
2542 std::vector<VkAttachmentDescription> attachmentDescs;
2543 attachmentDescs.push_back(fbAttachment);
2544
2545 // Add it as a frame buffer attachment.
2546 const VkAttachmentDescription inputAttachment = {
2547 0u,
2548 format,
2549 VK_SAMPLE_COUNT_1_BIT,
2550 VK_ATTACHMENT_LOAD_OP_LOAD,
2551 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2552 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2553 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2554 VK_IMAGE_LAYOUT_GENERAL,
2555 VK_IMAGE_LAYOUT_GENERAL,
2556 };
2557 attachmentDescs.push_back(inputAttachment);
2558
2559 std::vector<VkAttachmentReference> inputAttachments;
2560 const VkAttachmentReference inputRef = {
2561 1u,
2562 VK_IMAGE_LAYOUT_GENERAL,
2563 };
2564 inputAttachments.push_back(inputRef);
2565
2566 const VkAttachmentReference colorRef = {
2567 0u,
2568 VK_IMAGE_LAYOUT_GENERAL,
2569 };
2570 const std::vector<VkAttachmentReference> colorAttachments(1u, colorRef);
2571
2572 const VkSubpassDescription subpass = {
2573 0u,
2574 VK_PIPELINE_BIND_POINT_GRAPHICS,
2575 static_cast<uint32_t>(inputAttachments.size()),
2576 inputAttachments.data(),
2577 static_cast<uint32_t>(colorAttachments.size()),
2578 colorAttachments.data(),
2579 0u,
2580 nullptr,
2581 0u,
2582 nullptr,
2583 };
2584 const std::vector<VkSubpassDescription> subpasses(1u, subpass);
2585
2586 std::vector<VkSubpassDependency> subpass_dep_postive;
2587 subpass_dep_postive.push_back({VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_TRANSFER_BIT,
2588 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2589 VK_DEPENDENCY_VIEW_LOCAL_BIT});
2590 subpass_dep_postive.push_back({VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_TRANSFER_BIT,
2591 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_TRANSFER_WRITE_BIT,
2592 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, VK_DEPENDENCY_VIEW_LOCAL_BIT});
2593 subpass_dep_postive.push_back({0, VK_SUBPASS_EXTERNAL, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2594 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2595 VK_ACCESS_TRANSFER_READ_BIT, VK_DEPENDENCY_VIEW_LOCAL_BIT});
2596 subpass_dep_postive.push_back({0, VK_SUBPASS_EXTERNAL, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2597 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2598 VK_ACCESS_TRANSFER_WRITE_BIT, VK_DEPENDENCY_VIEW_LOCAL_BIT});
2599
2600 VkRenderPassCreateInfo renderPassInfo = {
2601 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
2602 nullptr,
2603 0u,
2604 static_cast<uint32_t>(attachmentDescs.size()),
2605 attachmentDescs.data(),
2606 static_cast<uint32_t>(subpasses.size()),
2607 subpasses.data(),
2608 static_cast<uint32_t>(subpass_dep_postive.size()),
2609 subpass_dep_postive.data(),
2610 };
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002611 vk_testing::RenderPass rp_positive;
2612 rp_positive.init(*m_device, renderPassInfo);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002613
2614 std::vector<VkSubpassDependency> subpass_dep_negative;
2615 subpass_dep_negative.push_back({VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_TRANSFER_BIT,
2616 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2617 VK_DEPENDENCY_VIEW_LOCAL_BIT});
2618 // Show that the two barriers do *not* chain by breaking the positive barrier into two bits.
2619 subpass_dep_negative.push_back({VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_TRANSFER_BIT,
2620 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, 0,
2621 VK_DEPENDENCY_VIEW_LOCAL_BIT});
2622 subpass_dep_negative.push_back({VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2623 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
2624 VK_DEPENDENCY_VIEW_LOCAL_BIT});
2625
2626 renderPassInfo.dependencyCount = static_cast<uint32_t>(subpass_dep_negative.size());
2627 renderPassInfo.pDependencies = subpass_dep_negative.data();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002628 vk_testing::RenderPass rp_negative;
2629 rp_negative.init(*m_device, renderPassInfo);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002630
2631 // rp_postive and rp_negative should be compatible for the same fb object
2632 const VkFramebufferCreateInfo fbci = {
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002633 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, 0, 0u, rp_positive.handle(), 2u, attachments, 64, 64, 1u,
Jeremy Gebben170781d2020-11-19 16:21:21 -07002634 };
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002635 vk_testing::Framebuffer fb;
2636 fb.init(*m_device, fbci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002637
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002638 vk_testing::Sampler sampler;
Jeremy Gebben170781d2020-11-19 16:21:21 -07002639 VkSamplerCreateInfo sampler_info = SafeSaneSamplerCreateInfo();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002640 sampler.init(*m_device, sampler_info);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002641
sfricke-samsung1c0b96a2021-07-08 22:24:09 -07002642 char const *fsSource = R"glsl(
2643 #version 450
2644 layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;
2645 void main() {
2646 vec4 color = subpassLoad(x);
2647 }
2648 )glsl";
Jeremy Gebben170781d2020-11-19 16:21:21 -07002649
2650 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
2651 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
2652
2653 CreatePipelineHelper g_pipe(*this);
2654 g_pipe.InitInfo();
2655 g_pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
2656 g_pipe.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002657 g_pipe.gp_ci_.renderPass = rp_positive.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002658 g_pipe.InitState();
2659 ASSERT_VK_SUCCESS(g_pipe.CreateGraphicsPipeline());
2660
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002661 g_pipe.descriptor_set_->WriteDescriptorImageInfo(0, view_input, sampler.handle(), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002662 g_pipe.descriptor_set_->UpdateDescriptorSets();
2663
2664 m_commandBuffer->begin();
2665 auto cb = m_commandBuffer->handle();
2666 VkClearColorValue ccv = {};
2667
2668 const VkImageMemoryBarrier xferDestBarrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
2669 nullptr,
2670 VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT,
2671 VK_ACCESS_TRANSFER_WRITE_BIT,
2672 VK_IMAGE_LAYOUT_GENERAL,
2673 VK_IMAGE_LAYOUT_GENERAL,
2674 VK_QUEUE_FAMILY_IGNORED,
2675 VK_QUEUE_FAMILY_IGNORED,
2676 VK_NULL_HANDLE,
2677 full_subresource_range};
2678 const VkImageMemoryBarrier xferDestToSrcBarrier = {
2679 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
2680 nullptr,
2681 VK_ACCESS_TRANSFER_WRITE_BIT,
2682 VK_ACCESS_TRANSFER_READ_BIT,
2683 VK_IMAGE_LAYOUT_GENERAL,
2684 VK_IMAGE_LAYOUT_GENERAL,
2685 VK_QUEUE_FAMILY_IGNORED,
2686 VK_QUEUE_FAMILY_IGNORED,
2687 VK_NULL_HANDLE,
2688 full_subresource_range,
2689 };
2690
2691 VkImageMemoryBarrier preClearBarrier = xferDestBarrier;
2692 preClearBarrier.image = image_color.handle();
2693
2694 VkImageMemoryBarrier preCopyBarriers[2] = {xferDestToSrcBarrier, xferDestBarrier};
2695 preCopyBarriers[0].image = image_color.handle();
2696 preCopyBarriers[1].image = image_input.handle();
2697 // Positive test for ordering rules between load and input attachment usage
2698 m_errorMonitor->ExpectSuccess();
2699
2700 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u,
2701 &preClearBarrier);
2702
2703 vk::CmdClearColorImage(m_commandBuffer->handle(), image_color.handle(), VK_IMAGE_LAYOUT_GENERAL, &ccv, 1,
2704 &full_subresource_range);
2705
2706 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 2u,
2707 preCopyBarriers);
2708
2709 vk::CmdCopyImage(m_commandBuffer->handle(), image_color.handle(), VK_IMAGE_LAYOUT_GENERAL, image_input.handle(),
2710 VK_IMAGE_LAYOUT_GENERAL, 1u, &full_region);
2711
2712 // No post copy image barrier, we are testing the subpass dependencies
2713
2714 m_renderPassBeginInfo.renderArea = {{0, 0}, {64, 64}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002715 m_renderPassBeginInfo.renderPass = rp_positive.handle();
2716 m_renderPassBeginInfo.framebuffer = fb.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002717
2718 // Postive renderpass multidependency test
2719 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2720 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
2721 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
2722 &g_pipe.descriptor_set_->set_, 0, nullptr);
2723
2724 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
2725
2726 // Positive test for store ordering vs. input attachment and dependency *to* external for layout transition
2727 m_commandBuffer->EndRenderPass();
2728 // m_errorMonitor->VerifyNotFound();
2729
2730 vk::CmdCopyImage(m_commandBuffer->handle(), image_color.handle(), VK_IMAGE_LAYOUT_GENERAL, image_input.handle(),
2731 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &full_region);
2732 m_errorMonitor->VerifyNotFound();
2733
2734 m_renderPassBeginInfo.renderArea = {{0, 0}, {64, 64}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002735 m_renderPassBeginInfo.renderPass = rp_negative.handle();
2736 m_renderPassBeginInfo.framebuffer = fb.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002737
2738 // Postive renderpass multidependency test, will fail IFF the dependencies are acting indepently.
2739 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "SYNC-HAZARD-READ_AFTER_WRITE");
2740 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2741 m_errorMonitor->VerifyFound();
2742}
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002743
2744TEST_F(VkSyncValTest, RenderPassAsyncHazard) {
2745 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
2746 ASSERT_NO_FATAL_FAILURE(InitState());
2747
Nathaniel Cesariof9cd1a82021-07-24 08:48:55 -06002748 if (IsPlatform(kPixel3) || IsPlatform(kPixel3aXL)) {
2749 printf("%s Temporarily disabling on Pixel 3 and Pixel 3a XL due to driver crash\n", kSkipPrefix);
2750 return;
2751 }
2752
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002753 // overall set up:
2754 // subpass 0:
2755 // write image 0
2756 // subpass 1:
2757 // read image 0
2758 // write image 1
2759 // subpass 2:
2760 // read image 0
2761 // write image 2
2762 // subpass 3:
2763 // read image 0
2764 // write image 3
2765 //
2766 // subpasses 1 & 2 can run in parallel but both should depend on 0
2767 // subpass 3 must run after 1 & 2 because otherwise the store operation will
2768 // race with the reads in the other subpasses.
2769
2770 constexpr VkFormat kFormat = VK_FORMAT_R8G8B8A8_UNORM;
2771 constexpr uint32_t kWidth = 32, kHeight = 32;
2772 constexpr uint32_t kNumImages = 4;
2773
2774 VkImageCreateInfo src_img_info = {};
2775 src_img_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2776 src_img_info.pNext = NULL;
2777 src_img_info.flags = 0;
2778 src_img_info.imageType = VK_IMAGE_TYPE_2D;
2779 src_img_info.format = kFormat;
2780 src_img_info.extent = {kWidth, kHeight, 1};
2781 src_img_info.mipLevels = 1;
2782 src_img_info.arrayLayers = 1;
2783 src_img_info.samples = VK_SAMPLE_COUNT_2_BIT;
2784 src_img_info.tiling = VK_IMAGE_TILING_OPTIMAL;
2785 src_img_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
2786 src_img_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2787 src_img_info.queueFamilyIndexCount = 0;
2788 src_img_info.pQueueFamilyIndices = nullptr;
2789 src_img_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2790
2791 VkImageCreateInfo dst_img_info = {};
2792 dst_img_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2793 dst_img_info.pNext = nullptr;
2794 dst_img_info.flags = 0;
2795 dst_img_info.imageType = VK_IMAGE_TYPE_2D;
2796 dst_img_info.format = kFormat;
2797 dst_img_info.extent = {kWidth, kHeight, 1};
2798 dst_img_info.mipLevels = 1;
2799 dst_img_info.arrayLayers = 1;
2800 dst_img_info.samples = VK_SAMPLE_COUNT_1_BIT;
2801 dst_img_info.tiling = VK_IMAGE_TILING_OPTIMAL;
2802 dst_img_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
2803 dst_img_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2804 dst_img_info.queueFamilyIndexCount = 0;
2805 dst_img_info.pQueueFamilyIndices = nullptr;
2806 dst_img_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2807
2808 std::vector<std::unique_ptr<VkImageObj>> images;
2809 for (uint32_t i = 0; i < kNumImages; i++) {
2810 images.emplace_back(new VkImageObj(m_device));
2811 }
2812 images[0]->Init(src_img_info);
2813 for (uint32_t i = 1; i < images.size(); i++) {
2814 images[i]->Init(dst_img_info);
2815 }
2816
2817 std::array<VkImageView, kNumImages> attachments{};
2818 std::array<VkAttachmentDescription, kNumImages> attachment_descriptions{};
2819 std::array<VkAttachmentReference, kNumImages> color_refs{};
2820 std::array<VkImageMemoryBarrier, kNumImages> img_barriers{};
2821
2822 for (uint32_t i = 0; i < attachments.size(); i++) {
2823 attachments[i] = images[i]->targetView(kFormat);
2824 attachment_descriptions[i] = {};
2825 attachment_descriptions[i].flags = 0;
2826 attachment_descriptions[i].format = kFormat;
2827 attachment_descriptions[i].samples = VK_SAMPLE_COUNT_1_BIT;
2828 attachment_descriptions[i].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
2829 attachment_descriptions[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
2830 attachment_descriptions[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
2831 attachment_descriptions[i].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
2832 attachment_descriptions[i].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
2833 attachment_descriptions[i].finalLayout =
2834 (i == 0) ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
2835
2836 color_refs[i] = {i, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
2837
2838 img_barriers[i].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
2839 img_barriers[i].srcAccessMask = 0;
2840 img_barriers[i].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
2841 img_barriers[i].oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2842 img_barriers[i].newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
2843 img_barriers[i].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
2844 img_barriers[i].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
2845 img_barriers[i].image = images[i]->handle();
2846 img_barriers[i].subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS};
2847 }
2848
2849 const VkAttachmentReference input_ref{0u, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};
2850
2851 std::array<std::array<uint32_t, 2>, kNumImages - 1> preserve_subpass{{{2, 3}, {1, 3}, {1, 2}}};
2852
2853 std::array<VkSubpassDescription, kNumImages> subpasses{};
2854
2855 subpasses[0].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
2856 subpasses[0].inputAttachmentCount = 0;
2857 subpasses[0].pInputAttachments = nullptr;
2858 subpasses[0].colorAttachmentCount = 1;
2859 subpasses[0].pColorAttachments = &color_refs[0];
2860
2861 for (uint32_t i = 1; i < subpasses.size(); i++) {
2862 subpasses[i].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
2863 subpasses[i].inputAttachmentCount = 1;
2864 subpasses[i].pInputAttachments = &input_ref;
2865 subpasses[i].colorAttachmentCount = 1;
2866 subpasses[i].pColorAttachments = &color_refs[1];
2867 subpasses[i].preserveAttachmentCount = preserve_subpass[i - 1].size();
2868 subpasses[i].pPreserveAttachments = preserve_subpass[i - 1].data();
2869 }
2870
2871 VkRenderPassCreateInfo renderpass_info = {};
2872 renderpass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
2873 renderpass_info.pNext = nullptr;
2874 renderpass_info.flags = 0;
2875 renderpass_info.attachmentCount = attachment_descriptions.size();
2876 renderpass_info.pAttachments = attachment_descriptions.data();
2877 renderpass_info.subpassCount = subpasses.size();
2878 renderpass_info.pSubpasses = subpasses.data();
2879 renderpass_info.dependencyCount = 0;
2880 renderpass_info.pDependencies = nullptr;
2881
2882 VkFramebufferCreateInfo fbci = {};
2883 fbci.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
2884 fbci.pNext = nullptr;
2885 fbci.flags = 0;
2886 fbci.attachmentCount = attachments.size();
2887 fbci.pAttachments = attachments.data();
2888 fbci.width = kWidth;
2889 fbci.height = kHeight;
2890 fbci.layers = 1;
2891
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002892 vk_testing::Sampler sampler;
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002893 VkSamplerCreateInfo sampler_info = SafeSaneSamplerCreateInfo();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002894 sampler.init(*m_device, sampler_info);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002895
sfricke-samsung1c0b96a2021-07-08 22:24:09 -07002896 char const *fsSource = R"glsl(
2897 #version 450
2898 layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;
2899 void main() {
2900 vec4 color = subpassLoad(x);
2901 }
2902 )glsl";
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002903
2904 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
2905 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
2906
2907 VkClearValue clear = {};
2908 clear.color = m_clear_color;
Tony-LunarG73f37032021-06-07 11:47:03 -06002909 std::array<VkClearValue, 4> clear_values = {{clear, clear, clear, clear}};
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002910
2911 // run the renderpass with no dependencies
2912 {
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002913 vk_testing::RenderPass rp;
2914 vk_testing::Framebuffer fb;
2915 rp.init(*m_device, renderpass_info);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002916
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002917 fbci.renderPass = rp.handle();
2918 fb.init(*m_device, fbci);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002919
2920 CreatePipelineHelper g_pipe_0(*this);
2921 g_pipe_0.InitInfo();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002922 g_pipe_0.gp_ci_.renderPass = rp.handle();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002923 g_pipe_0.InitState();
2924 ASSERT_VK_SUCCESS(g_pipe_0.CreateGraphicsPipeline());
2925
2926 CreatePipelineHelper g_pipe_12(*this);
2927 g_pipe_12.InitInfo();
2928 g_pipe_12.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
2929 g_pipe_12.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002930 g_pipe_12.gp_ci_.renderPass = rp.handle();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002931 g_pipe_12.InitState();
2932 ASSERT_VK_SUCCESS(g_pipe_12.CreateGraphicsPipeline());
2933
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002934 g_pipe_12.descriptor_set_->WriteDescriptorImageInfo(0, attachments[0], sampler.handle(), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002935 g_pipe_12.descriptor_set_->UpdateDescriptorSets();
2936
2937 m_commandBuffer->begin();
2938
2939 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
2940 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0, nullptr, img_barriers.size(),
2941 img_barriers.data());
2942
2943 m_renderPassBeginInfo.renderArea = {{0, 0}, {16, 16}};
2944 m_renderPassBeginInfo.pClearValues = clear_values.data();
2945 m_renderPassBeginInfo.clearValueCount = clear_values.size();
2946
2947 m_renderPassBeginInfo.renderArea = {{0, 0}, {kWidth, kHeight}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002948 m_renderPassBeginInfo.renderPass = rp.handle();
2949 m_renderPassBeginInfo.framebuffer = fb.handle();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002950
2951 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
2952 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_);
2953 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_layout_.handle(), 0,
2954 1, &g_pipe_0.descriptor_set_->set_, 0, NULL);
2955
2956 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
2957
2958 for (uint32_t i = 1; i < subpasses.size(); i++) {
2959 vk::CmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
2960 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_12.pipeline_);
2961 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS,
2962 g_pipe_12.pipeline_layout_.handle(), 0, 1, &g_pipe_12.descriptor_set_->set_, 0, NULL);
2963
2964 // we're racing the writes from subpass 0 with our shader reads
2965 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ-RACING-WRITE");
2966 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
2967 m_errorMonitor->VerifyFound();
2968 }
2969
2970 // we should get an error from async checking in both subpasses 2 & 3
2971 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE-RACING-WRITE");
2972 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE-RACING-WRITE");
2973 vk::CmdEndRenderPass(m_commandBuffer->handle());
2974 m_errorMonitor->VerifyFound();
2975
2976 m_commandBuffer->end();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002977 }
2978
2979 // add dependencies from subpass 0 to the others, which are necessary but not sufficient
2980 std::vector<VkSubpassDependency> subpass_dependencies;
2981 for (uint32_t i = 1; i < subpasses.size(); i++) {
2982 VkSubpassDependency dep{0,
2983 i,
2984 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2985 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
2986 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2987 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
2988 0};
2989 subpass_dependencies.push_back(dep);
2990 }
2991 renderpass_info.dependencyCount = subpass_dependencies.size();
2992 renderpass_info.pDependencies = subpass_dependencies.data();
2993
2994 {
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002995 vk_testing::RenderPass rp;
2996 vk_testing::Framebuffer fb;
2997 rp.init(*m_device, renderpass_info);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002998
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002999 fbci.renderPass = rp.handle();
3000 fb.init(*m_device, fbci);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003001
3002 CreatePipelineHelper g_pipe_0(*this);
3003 g_pipe_0.InitInfo();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06003004 g_pipe_0.gp_ci_.renderPass = rp.handle();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003005 g_pipe_0.InitState();
3006 ASSERT_VK_SUCCESS(g_pipe_0.CreateGraphicsPipeline());
3007
3008 CreatePipelineHelper g_pipe_12(*this);
3009 g_pipe_12.InitInfo();
3010 g_pipe_12.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
3011 g_pipe_12.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06003012 g_pipe_12.gp_ci_.renderPass = rp.handle();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003013 g_pipe_12.InitState();
3014 ASSERT_VK_SUCCESS(g_pipe_12.CreateGraphicsPipeline());
3015
Jeremy Gebben18ac1052021-08-12 11:07:32 -06003016 g_pipe_12.descriptor_set_->WriteDescriptorImageInfo(0, attachments[0], sampler.handle(), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003017 g_pipe_12.descriptor_set_->UpdateDescriptorSets();
3018
3019 m_commandBuffer->begin();
3020
3021 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
3022 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0, nullptr, img_barriers.size(),
3023 img_barriers.data());
3024
3025 m_renderPassBeginInfo.renderArea = {{0, 0}, {16, 16}};
3026 m_renderPassBeginInfo.pClearValues = clear_values.data();
3027 m_renderPassBeginInfo.clearValueCount = clear_values.size();
3028
3029 m_renderPassBeginInfo.renderArea = {{0, 0}, {kWidth, kHeight}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06003030 m_renderPassBeginInfo.renderPass = rp.handle();
3031 m_renderPassBeginInfo.framebuffer = fb.handle();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003032
3033 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
3034 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_);
3035 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_layout_.handle(), 0,
3036 1, &g_pipe_0.descriptor_set_->set_, 0, NULL);
3037
3038 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
3039
3040 m_errorMonitor->ExpectSuccess();
3041 for (uint32_t i = 1; i < subpasses.size(); i++) {
3042 vk::CmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
3043 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_12.pipeline_);
3044 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS,
3045 g_pipe_12.pipeline_layout_.handle(), 0, 1, &g_pipe_12.descriptor_set_->set_, 0, NULL);
3046 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
3047 }
3048 m_errorMonitor->VerifyNotFound();
3049 // expect this error because 2 subpasses could try to do the store operation
3050 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE-RACING-WRITE");
3051 // ... and this one because the store could happen during a shader read from another subpass
3052 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE-RACING-READ");
3053 vk::CmdEndRenderPass(m_commandBuffer->handle());
3054 m_errorMonitor->VerifyFound();
3055
3056 m_commandBuffer->end();
3057
3058 m_errorMonitor->VerifyFound();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003059 }
3060
3061 // try again with correct dependencies to make subpass 3 depend on 1 & 2
3062 for (uint32_t i = 1; i < (subpasses.size() - 1); i++) {
3063 VkSubpassDependency dep{i,
3064 static_cast<uint32_t>(subpasses.size() - 1),
3065 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
3066 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
3067 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
3068 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
3069 0};
3070 subpass_dependencies.push_back(dep);
3071 }
3072 renderpass_info.dependencyCount = subpass_dependencies.size();
3073 renderpass_info.pDependencies = subpass_dependencies.data();
3074 {
Jeremy Gebben18ac1052021-08-12 11:07:32 -06003075 vk_testing::RenderPass rp;
3076 vk_testing::Framebuffer fb;
3077 rp.init(*m_device, renderpass_info);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003078
Jeremy Gebben18ac1052021-08-12 11:07:32 -06003079 fbci.renderPass = rp.handle();
3080 fb.init(*m_device, fbci);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003081
3082 CreatePipelineHelper g_pipe_0(*this);
3083 g_pipe_0.InitInfo();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06003084 g_pipe_0.gp_ci_.renderPass = rp.handle();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003085 g_pipe_0.InitState();
3086 ASSERT_VK_SUCCESS(g_pipe_0.CreateGraphicsPipeline());
3087
3088 CreatePipelineHelper g_pipe_12(*this);
3089 g_pipe_12.InitInfo();
3090 g_pipe_12.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
3091 g_pipe_12.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06003092 g_pipe_12.gp_ci_.renderPass = rp.handle();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003093 g_pipe_12.InitState();
3094 ASSERT_VK_SUCCESS(g_pipe_12.CreateGraphicsPipeline());
3095
Jeremy Gebben18ac1052021-08-12 11:07:32 -06003096 g_pipe_12.descriptor_set_->WriteDescriptorImageInfo(0, attachments[0], sampler.handle(), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003097 g_pipe_12.descriptor_set_->UpdateDescriptorSets();
3098
3099 m_errorMonitor->ExpectSuccess();
3100 m_commandBuffer->begin();
3101 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
3102 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0, nullptr, img_barriers.size(),
3103 img_barriers.data());
3104
3105 m_renderPassBeginInfo.renderArea = {{0, 0}, {16, 16}};
3106 m_renderPassBeginInfo.pClearValues = clear_values.data();
3107 m_renderPassBeginInfo.clearValueCount = clear_values.size();
3108
3109 m_renderPassBeginInfo.renderArea = {{0, 0}, {kWidth, kHeight}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06003110 m_renderPassBeginInfo.renderPass = rp.handle();
3111 m_renderPassBeginInfo.framebuffer = fb.handle();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003112
3113 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
3114 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_);
3115 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_layout_.handle(), 0,
3116 1, &g_pipe_0.descriptor_set_->set_, 0, NULL);
3117
3118 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
3119
3120 for (uint32_t i = 1; i < subpasses.size(); i++) {
3121 vk::CmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
3122 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_12.pipeline_);
3123 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS,
3124 g_pipe_12.pipeline_layout_.handle(), 0, 1, &g_pipe_12.descriptor_set_->set_, 0, NULL);
3125 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
3126 }
3127
3128 vk::CmdEndRenderPass(m_commandBuffer->handle());
3129
3130 m_commandBuffer->end();
3131
3132 m_errorMonitor->VerifyNotFound();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003133 }
3134}
John Zulauf025ee442020-12-15 11:44:19 -07003135
3136TEST_F(VkSyncValTest, SyncEventsBufferCopy) {
3137 TEST_DESCRIPTION("Check Set/Wait protection for a variety of use cases using buffer copies");
3138 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
3139 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
3140
3141 VkBufferObj buffer_a;
3142 VkBufferObj buffer_b;
3143 VkBufferObj buffer_c;
3144 VkMemoryPropertyFlags mem_prop = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
3145 buffer_a.init_as_src_and_dst(*m_device, 256, mem_prop);
3146 buffer_b.init_as_src_and_dst(*m_device, 256, mem_prop);
3147 buffer_c.init_as_src_and_dst(*m_device, 256, mem_prop);
3148
3149 VkBufferCopy region = {0, 0, 256};
3150 VkBufferCopy front2front = {0, 0, 128};
3151 VkBufferCopy front2back = {0, 128, 128};
3152 VkBufferCopy back2back = {128, 128, 128};
3153
3154 VkEventObj event;
3155 event.init(*m_device, VkEventObj::create_info(0));
3156 VkEvent event_handle = event.handle();
3157
3158 auto cb = m_commandBuffer->handle();
3159 m_commandBuffer->begin();
3160
3161 // Copy after set for WAR (note we are writing to the back half of c but only reading from the front
3162 m_errorMonitor->ExpectSuccess();
3163 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &region);
3164 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3165 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_c.handle(), 1, &back2back);
3166 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3167 nullptr, 0, nullptr);
3168 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &front2front);
3169 m_errorMonitor->VerifyNotFound();
3170 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
3171 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &front2back);
3172 m_errorMonitor->VerifyFound();
3173 m_commandBuffer->end();
3174
3175 // WAR prevented
3176 m_commandBuffer->reset();
3177 m_commandBuffer->begin();
3178 m_errorMonitor->ExpectSuccess();
3179 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &region);
3180 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3181 // Just protect against WAR, only need a sync barrier.
3182 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3183 nullptr, 0, nullptr);
3184 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &region);
3185 m_errorMonitor->VerifyNotFound();
3186
3187 // Wait shouldn't prevent this WAW though, as it's only a synchronization barrier
3188 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
3189 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_b.handle(), 1, &region);
3190 m_errorMonitor->VerifyFound();
3191 m_commandBuffer->end();
3192
3193 // Prevent WAR and WAW
3194 m_commandBuffer->reset();
3195 m_commandBuffer->begin();
3196 m_errorMonitor->ExpectSuccess();
3197 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &region);
3198 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07003199 auto mem_barrier_waw = LvlInitStruct<VkMemoryBarrier>();
John Zulauf025ee442020-12-15 11:44:19 -07003200 mem_barrier_waw.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3201 mem_barrier_waw.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3202 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 1,
3203 &mem_barrier_waw, 0, nullptr, 0, nullptr);
3204 // The WAW should be safe (on a memory barrier)
3205 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_b.handle(), 1, &region);
3206 // The WAR should also be safe (on a sync barrier)
3207 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &region);
3208 m_errorMonitor->VerifyNotFound();
3209 m_commandBuffer->end();
3210
3211 // Barrier range check for WAW
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07003212 auto buffer_barrier_front_waw = LvlInitStruct<VkBufferMemoryBarrier>();
John Zulauf025ee442020-12-15 11:44:19 -07003213 buffer_barrier_front_waw.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3214 buffer_barrier_front_waw.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3215 buffer_barrier_front_waw.buffer = buffer_b.handle();
3216 buffer_barrier_front_waw.offset = front2front.dstOffset;
3217 buffer_barrier_front_waw.size = front2front.size;
3218
3219 // Front safe, back WAW
3220 m_commandBuffer->reset();
3221 m_commandBuffer->begin();
3222 m_errorMonitor->ExpectSuccess();
3223 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &region);
3224 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3225 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 1,
3226 &buffer_barrier_front_waw, 0, nullptr);
3227 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &front2front);
3228 m_errorMonitor->VerifyNotFound();
3229 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
3230 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &back2back);
3231 m_errorMonitor->VerifyFound();
3232 m_commandBuffer->end();
3233}
3234
3235TEST_F(VkSyncValTest, SyncEventsCopyImageHazards) {
3236 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
3237 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
3238
3239 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3240 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
3241 VkImageObj image_a(m_device);
3242 auto image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 2, format, usage, VK_IMAGE_TILING_OPTIMAL);
3243 image_a.Init(image_ci);
3244 ASSERT_TRUE(image_a.initialized());
3245
3246 VkImageObj image_b(m_device);
3247 image_b.Init(image_ci);
3248 ASSERT_TRUE(image_b.initialized());
3249
3250 VkImageObj image_c(m_device);
3251 image_c.Init(image_ci);
3252 ASSERT_TRUE(image_c.initialized());
3253
3254 VkEventObj event;
3255 event.init(*m_device, VkEventObj::create_info(0));
3256 VkEvent event_handle = event.handle();
3257
3258 VkImageSubresourceLayers layers_all{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 2};
3259 VkImageSubresourceLayers layers_0{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
3260 VkImageSubresourceLayers layers_1{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1};
3261 VkImageSubresourceRange layers_0_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
3262 VkOffset3D zero_offset{0, 0, 0};
3263 VkOffset3D half_offset{64, 64, 0};
3264 VkExtent3D full_extent{128, 128, 1}; // <-- image type is 2D
3265 VkExtent3D half_extent{64, 64, 1}; // <-- image type is 2D
3266
3267 VkImageCopy full_region = {layers_all, zero_offset, layers_all, zero_offset, full_extent};
3268 VkImageCopy region_0_to_0 = {layers_0, zero_offset, layers_0, zero_offset, full_extent};
3269 VkImageCopy region_1_to_1 = {layers_1, zero_offset, layers_1, zero_offset, full_extent};
3270 VkImageCopy region_0_q0toq0 = {layers_0, zero_offset, layers_0, zero_offset, half_extent};
3271 VkImageCopy region_0_q0toq3 = {layers_0, zero_offset, layers_0, half_offset, half_extent};
3272 VkImageCopy region_0_q3toq3 = {layers_0, half_offset, layers_0, half_offset, half_extent};
3273
3274 auto cb = m_commandBuffer->handle();
3275 auto copy_general = [cb](const VkImageObj &from, const VkImageObj &to, const VkImageCopy &region) {
3276 vk::CmdCopyImage(cb, from.handle(), VK_IMAGE_LAYOUT_GENERAL, to.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
3277 };
3278
3279 auto set_layouts = [this, &image_a, &image_b, &image_c]() {
3280 image_c.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
3281 image_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
3282 image_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
3283 };
3284
John Zulaufdd462092020-12-18 12:00:35 -07003285 // Scope check. One access in, one access not
John Zulauf025ee442020-12-15 11:44:19 -07003286 m_commandBuffer->begin();
3287 set_layouts();
3288 m_errorMonitor->ExpectSuccess();
3289 copy_general(image_a, image_b, full_region);
3290 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3291 copy_general(image_a, image_c, region_0_q3toq3);
3292 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3293 nullptr, 0, nullptr);
3294 copy_general(image_c, image_a, region_0_q0toq0);
3295 m_errorMonitor->VerifyNotFound();
3296 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
3297 copy_general(image_c, image_a, region_0_q0toq3);
3298 m_errorMonitor->VerifyFound();
3299 m_commandBuffer->end();
3300
3301 // WAR prevented
3302 m_commandBuffer->reset();
3303 m_commandBuffer->begin();
3304 set_layouts();
3305 m_errorMonitor->ExpectSuccess();
3306 copy_general(image_a, image_b, full_region);
3307 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3308 // Just protect against WAR, only need a sync barrier.
3309 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3310 nullptr, 0, nullptr);
3311 copy_general(image_c, image_a, full_region);
3312 m_errorMonitor->VerifyNotFound();
3313
3314 // Wait shouldn't prevent this WAW though, as it's only a synchronization barrier
3315 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
3316 copy_general(image_c, image_b, full_region);
3317 m_errorMonitor->VerifyFound();
3318 m_commandBuffer->end();
3319
3320 // Prevent WAR and WAW
3321 m_commandBuffer->reset();
3322 m_commandBuffer->begin();
3323 m_errorMonitor->ExpectSuccess();
3324 set_layouts();
3325 copy_general(image_a, image_b, full_region);
3326 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07003327 auto mem_barrier_waw = LvlInitStruct<VkMemoryBarrier>();
John Zulauf025ee442020-12-15 11:44:19 -07003328 mem_barrier_waw.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3329 mem_barrier_waw.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3330 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 1,
3331 &mem_barrier_waw, 0, nullptr, 0, nullptr);
3332 // The WAW should be safe (on a memory barrier)
3333 copy_general(image_c, image_b, full_region);
3334 // The WAR should also be safe (on a sync barrier)
3335 copy_general(image_c, image_a, full_region);
3336 m_errorMonitor->VerifyNotFound();
3337 m_commandBuffer->end();
3338
3339 // Barrier range check for WAW
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07003340 auto image_barrier_region0_waw = LvlInitStruct<VkImageMemoryBarrier>();
John Zulauf025ee442020-12-15 11:44:19 -07003341 image_barrier_region0_waw.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3342 image_barrier_region0_waw.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3343 image_barrier_region0_waw.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
3344 image_barrier_region0_waw.newLayout = VK_IMAGE_LAYOUT_GENERAL;
3345 image_barrier_region0_waw.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
3346 image_barrier_region0_waw.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
3347 image_barrier_region0_waw.image = image_b.handle();
3348 image_barrier_region0_waw.subresourceRange = layers_0_subresource_range;
3349
3350 // Region 0 safe, back WAW
3351 m_commandBuffer->reset();
3352 m_commandBuffer->begin();
3353 set_layouts();
3354 m_errorMonitor->ExpectSuccess();
3355 copy_general(image_a, image_b, full_region);
3356 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3357 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3358 nullptr, 1, &image_barrier_region0_waw);
3359 copy_general(image_a, image_b, region_0_to_0);
3360 m_errorMonitor->VerifyNotFound();
3361 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
3362 copy_general(image_a, image_b, region_1_to_1);
3363 m_errorMonitor->VerifyFound();
3364 m_commandBuffer->end();
3365}
John Zulauf4b5e4632020-12-15 11:48:59 -07003366
3367TEST_F(VkSyncValTest, SyncEventsCommandHazards) {
3368 TEST_DESCRIPTION("Check Set/Reset/Wait command hazard checking");
3369 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
3370 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
3371
3372 VkEventObj event;
3373 event.init(*m_device, VkEventObj::create_info(0));
3374
3375 const VkEvent event_handle = event.handle();
3376
3377 m_commandBuffer->begin();
3378 m_errorMonitor->ExpectSuccess();
3379 m_commandBuffer->ResetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3380 m_errorMonitor->VerifyNotFound();
3381
John Zulauf4edde622021-02-15 08:54:50 -07003382 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdResetEvent-event-03834");
John Zulauf4b5e4632020-12-15 11:48:59 -07003383 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdWaitEvents-srcStageMask-01158");
3384 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3385 nullptr, 0, nullptr);
3386 m_errorMonitor->VerifyFound();
3387 m_errorMonitor->ExpectSuccess();
3388 m_commandBuffer->end();
3389
3390 m_commandBuffer->begin();
3391 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3392 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, nullptr,
3393 0, nullptr, 0, nullptr);
3394 m_errorMonitor->VerifyNotFound();
3395 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-vkCmdResetEvent-missingbarrier-wait");
3396 m_commandBuffer->ResetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3397 m_errorMonitor->VerifyFound();
3398 m_errorMonitor->ExpectSuccess();
3399 m_commandBuffer->end();
3400
3401 m_commandBuffer->begin();
3402 m_commandBuffer->ResetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3403 m_errorMonitor->VerifyNotFound();
3404 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-vkCmdSetEvent-missingbarrier-reset");
3405 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3406 m_errorMonitor->VerifyFound();
3407
3408 m_errorMonitor->ExpectSuccess();
3409 m_commandBuffer->PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0U, 0, nullptr, 0,
3410 nullptr, 0, nullptr);
3411 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3412 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3413 nullptr, 0, nullptr);
3414 m_commandBuffer->ResetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3415 m_commandBuffer->PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0U, 0, nullptr, 0,
3416 nullptr, 0, nullptr);
3417 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3418 m_errorMonitor->VerifyNotFound();
3419
3420 // Need a barrier between set and a reset
3421 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-vkCmdResetEvent-missingbarrier-set");
3422 m_commandBuffer->ResetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3423 m_errorMonitor->VerifyFound();
3424 m_errorMonitor->ExpectSuccess();
3425 m_commandBuffer->end();
3426
3427 m_commandBuffer->begin();
3428 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3429 m_errorMonitor->VerifyNotFound();
3430 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-vkCmdSetEvent-missingbarrier-set");
3431 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3432 m_errorMonitor->VerifyFound();
3433
3434 m_commandBuffer->end();
3435}
ziga-lunarg3a16ff12021-07-30 12:09:55 +02003436
3437TEST_F(VkLayerTest, CmdWaitEvents2KHRUsedButSynchronizaion2Disabled) {
3438 TEST_DESCRIPTION("Using CmdWaitEvents2KHR when synchronization2 is not enabled");
3439
3440 ASSERT_NO_FATAL_FAILURE(InitFramework());
3441 if (!DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME)) {
3442 printf("%s Synchronization2 not supported, skipping test\n", kSkipPrefix);
3443 return;
3444 }
3445 if (!DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
3446 printf("%s %s not supported, skipping test\n", kSkipPrefix, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
3447 return;
3448 }
3449 m_device_extension_names.push_back(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME);
3450 m_device_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
3451 InitState();
3452
3453 auto fpCmdWaitEvents2KHR = (PFN_vkCmdWaitEvents2KHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdWaitEvents2KHR");
3454
3455 VkEventObj event;
3456 event.init(*m_device, VkEventObj::create_info(0));
3457 VkEvent event_handle = event.handle();
3458
3459 VkDependencyInfoKHR dependency_info = LvlInitStruct<VkDependencyInfoKHR>();
3460
3461 m_commandBuffer->begin();
3462 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdWaitEvents2KHR-synchronization2-03836");
3463 fpCmdWaitEvents2KHR(m_commandBuffer->handle(), 1, &event_handle, &dependency_info);
3464 m_errorMonitor->VerifyFound();
3465 m_commandBuffer->end();
3466}
ziga-lunarg15f450d2021-08-26 23:10:05 +02003467
3468TEST_F(VkLayerTest, Sync2FeatureDisabled) {
3469 TEST_DESCRIPTION("Call sync2 functions when the feature is disabled");
3470
3471 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
3472 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
3473 } else {
3474 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
3475 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
3476 return;
3477 }
3478 ASSERT_NO_FATAL_FAILURE(InitFramework());
3479 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME)) {
3480 m_device_extension_names.push_back(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME);
3481 } else {
3482 printf("%s Synchronization2 not supported, skipping test\n", kSkipPrefix);
3483 return;
3484 }
3485
3486 ASSERT_NO_FATAL_FAILURE(InitState());
3487
3488 VkPhysicalDeviceSynchronization2FeaturesKHR synchronization2 = LvlInitStruct<VkPhysicalDeviceSynchronization2FeaturesKHR>();
3489 synchronization2.synchronization2 = VK_FALSE; // Invalid
3490 auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&synchronization2);
3491 vk::GetPhysicalDeviceFeatures2(gpu(), &features2);
3492
3493 auto vkCmdPipelineBarrier2KHR =
3494 (PFN_vkCmdPipelineBarrier2KHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdPipelineBarrier2KHR");
3495 auto vkCmdResetEvent2KHR = (PFN_vkCmdResetEvent2KHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdResetEvent2KHR");
3496 auto vkCmdSetEvent2KHR = (PFN_vkCmdSetEvent2KHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetEvent2KHR");
3497 auto vkCmdWriteTimestamp2KHR =
3498 (PFN_vkCmdWriteTimestamp2KHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdWriteTimestamp2KHR");
3499
3500 bool timestamp = false;
3501
3502 uint32_t queue_count;
3503 vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_count, NULL);
3504 std::vector<VkQueueFamilyProperties> queue_props(queue_count);
3505 vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_count, queue_props.data());
3506 if (queue_props[m_device->graphics_queue_node_index_].timestampValidBits > 0) {
3507 timestamp = true;
3508 }
3509
3510 m_commandBuffer->begin();
3511
3512 VkDependencyInfoKHR dependency_info = LvlInitStruct<VkDependencyInfoKHR>();
3513
3514 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPipelineBarrier2KHR-synchronization2-03848");
3515 vkCmdPipelineBarrier2KHR(m_commandBuffer->handle(), &dependency_info);
3516 m_errorMonitor->VerifyFound();
3517
3518 VkEventCreateInfo eci = LvlInitStruct<VkEventCreateInfo>();
3519 vk_testing::Event event;
3520 event.init(*m_device, eci);
3521
3522 VkPipelineStageFlagBits2KHR stage = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR;
3523
3524 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResetEvent2KHR-synchronization2-03829");
3525 vkCmdResetEvent2KHR(m_commandBuffer->handle(), event.handle(), stage);
3526 m_errorMonitor->VerifyFound();
3527
3528 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetEvent2KHR-synchronization2-03824");
3529 vkCmdSetEvent2KHR(m_commandBuffer->handle(), event.handle(), &dependency_info);
3530 m_errorMonitor->VerifyFound();
3531
3532 if (timestamp) {
3533 VkQueryPoolCreateInfo qpci = LvlInitStruct<VkQueryPoolCreateInfo>();
3534 qpci.queryType = VK_QUERY_TYPE_TIMESTAMP;
3535 qpci.queryCount = 1;
3536
3537 vk_testing::QueryPool query_pool;
3538 query_pool.init(*m_device, qpci);
3539
3540 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdWriteTimestamp2KHR-synchronization2-03858");
3541 vkCmdWriteTimestamp2KHR(m_commandBuffer->handle(), stage, query_pool.handle(), 0);
3542 m_errorMonitor->VerifyFound();
3543 }
3544
3545 m_commandBuffer->end();
3546}