blob: 1b9966bcc1894eee0a54b52eb38eca7f548df889 [file] [log] [blame]
Jeremy Gebben170781d2020-11-19 16:21:21 -07001/*
sfricke-samsungae54c1e2022-01-21 05:35:21 -08002 * Copyright (c) 2015-2022 The Khronos Group Inc.
3 * Copyright (c) 2015-2022 Valve Corporation
4 * Copyright (c) 2015-2022 LunarG, Inc.
5 * Copyright (c) 2015-2022 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
John Zulaufe972b752021-05-04 15:47:17 -0600453 // Test secondary command buffers
454 // Create secondary buffers to use
455 m_errorMonitor->ExpectSuccess();
456 VkCommandBufferObj secondary_cb1(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
457 VkCommandBuffer scb1 = secondary_cb1.handle();
458 secondary_cb1.begin();
459 vk::CmdCopyImage(scb1, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
460 secondary_cb1.end();
461 m_errorMonitor->VerifyNotFound();
462
463 auto record_primary = [&]() {
464 m_commandBuffer->reset();
465 m_commandBuffer->begin();
466 vk::CmdCopyImage(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
467 vk::CmdExecuteCommands(cb, 1, &scb1);
468 m_commandBuffer->end();
469 };
470
471 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
472 record_primary();
473 m_errorMonitor->VerifyFound();
474
475 m_errorMonitor->ExpectSuccess();
476 // With a barrier...
477 secondary_cb1.reset();
478 secondary_cb1.begin();
479 vk::CmdPipelineBarrier(scb1, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1, &mem_barrier, 0, nullptr, 0,
480 nullptr);
481 vk::CmdCopyImage(scb1, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
482 secondary_cb1.end();
483 record_primary();
484 m_errorMonitor->VerifyNotFound();
485
486 auto image_transition_barrier = image_barrier;
487 image_transition_barrier.image = image_a.handle();
488 image_transition_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
489 image_transition_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
490
491 m_errorMonitor->ExpectSuccess();
492 secondary_cb1.reset();
493 secondary_cb1.begin();
494 // Use the wrong stage, get an error
495 vk::CmdPipelineBarrier(scb1, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, 1,
496 &image_transition_barrier);
497 secondary_cb1.end();
498 m_errorMonitor->VerifyNotFound();
499
500 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
501 record_primary();
502 m_errorMonitor->VerifyFound();
503
504 // CmdResolveImage hazard testing
Jeremy Gebben170781d2020-11-19 16:21:21 -0700505 VkImageFormatProperties formProps = {{0, 0, 0}, 0, 0, 0, 0};
506 vk::GetPhysicalDeviceImageFormatProperties(m_device->phy().handle(), VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TYPE_2D,
507 VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 0, &formProps);
508
509 if (!(formProps.sampleCounts & VK_SAMPLE_COUNT_2_BIT)) {
510 printf("%s CmdResolveImage Test requires unsupported VK_SAMPLE_COUNT_2_BIT feature. Skipped.\n", kSkipPrefix);
511 } else {
512 m_errorMonitor->ExpectSuccess();
513 VkImageObj image_s2_a(m_device), image_s2_b(m_device);
514 image_ci.samples = VK_SAMPLE_COUNT_2_BIT;
515 image_s2_a.Init(image_ci);
516 ASSERT_TRUE(image_s2_a.initialized());
517
518 image_s2_b.Init(image_ci);
519 ASSERT_TRUE(image_s2_b.initialized());
520
521 VkImageResolve r_full_region = {layers_all, zero_offset, layers_all, zero_offset, full_extent};
522
523 m_commandBuffer->reset();
524 m_commandBuffer->begin();
525 image_s2_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
526 image_s2_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
527 vk::CmdResolveImage(cb, image_s2_a.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
528 &r_full_region);
529 m_commandBuffer->end();
530 m_errorMonitor->VerifyNotFound();
531
532 m_commandBuffer->reset();
533 m_commandBuffer->begin();
534 vk::CmdCopyImage(cb, image_s2_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_s2_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
535 &full_region);
536 vk::CmdCopyImage(cb, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
537
538 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
539 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
540 vk::CmdResolveImage(cb, image_s2_a.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
541 &r_full_region);
542 m_errorMonitor->VerifyFound();
543
544 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
545 vk::CmdResolveImage(cb, image_s2_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
546 &r_full_region);
547 m_errorMonitor->VerifyFound();
548 m_commandBuffer->end();
549 }
550}
551
Jeremy Gebben5c1bb2d2021-02-15 08:58:04 -0700552TEST_F(VkSyncValTest, Sync2CopyOptimalImageHazards) {
553 SetTargetApiVersion(VK_API_VERSION_1_2);
554 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
555 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME)) {
556 m_device_extension_names.push_back(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME);
557 } else {
558 printf("%s Synchronization2 not supported, skipping test\n", kSkipPrefix);
559 return;
560 }
561
562 if (!CheckSynchronization2SupportAndInitState(this)) {
563 printf("%s Synchronization2 not supported, skipping test\n", kSkipPrefix);
564 return;
565 }
566 auto fpCmdPipelineBarrier2KHR = (PFN_vkCmdPipelineBarrier2KHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdPipelineBarrier2KHR");
567
568 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
569 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
570 VkImageObj image_a(m_device);
571 auto image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 2, format, usage, VK_IMAGE_TILING_OPTIMAL);
572 image_a.Init(image_ci);
573 ASSERT_TRUE(image_a.initialized());
574
575 VkImageObj image_b(m_device);
576 image_b.Init(image_ci);
577 ASSERT_TRUE(image_b.initialized());
578
579 VkImageObj image_c(m_device);
580 image_c.Init(image_ci);
581 ASSERT_TRUE(image_c.initialized());
582
583 VkImageSubresourceLayers layers_all{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 2};
584 VkImageSubresourceLayers layers_0{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
585 VkImageSubresourceLayers layers_1{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1};
586 VkImageSubresourceRange full_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 2};
587 VkOffset3D zero_offset{0, 0, 0};
588 VkOffset3D half_offset{64, 64, 0};
589 VkExtent3D full_extent{128, 128, 1}; // <-- image type is 2D
590 VkExtent3D half_extent{64, 64, 1}; // <-- image type is 2D
591
592 VkImageCopy full_region = {layers_all, zero_offset, layers_all, zero_offset, full_extent};
593 VkImageCopy region_0_to_0 = {layers_0, zero_offset, layers_0, zero_offset, full_extent};
594 VkImageCopy region_0_to_1 = {layers_0, zero_offset, layers_1, zero_offset, full_extent};
595 VkImageCopy region_1_to_1 = {layers_1, zero_offset, layers_1, zero_offset, full_extent};
596 VkImageCopy region_0_front = {layers_0, zero_offset, layers_0, zero_offset, half_extent};
597 VkImageCopy region_0_back = {layers_0, half_offset, layers_0, half_offset, half_extent};
598
599 m_commandBuffer->begin();
600
601 image_c.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
602 image_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
603 image_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
604
605 auto cb = m_commandBuffer->handle();
606
607 vk::CmdCopyImage(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
608
609 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
610 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
611 m_errorMonitor->VerifyFound();
612
613 // Use the barrier to clean up the WAW, and try again. (and show that validation is accounting for the barrier effect too.)
614 {
615 auto image_barrier = lvl_init_struct<VkImageMemoryBarrier2KHR>();
616 image_barrier.srcStageMask = VK_PIPELINE_STAGE_2_COPY_BIT_KHR;
617 image_barrier.dstStageMask = VK_PIPELINE_STAGE_2_COPY_BIT_KHR;
618 image_barrier.srcAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT_KHR;
619 image_barrier.dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR;
620 image_barrier.image = image_a.handle();
621 image_barrier.subresourceRange = full_subresource_range;
622 image_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
623 image_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
624 auto dep_info = lvl_init_struct<VkDependencyInfoKHR>();
625 dep_info.imageMemoryBarrierCount = 1;
626 dep_info.pImageMemoryBarriers = &image_barrier;
627 fpCmdPipelineBarrier2KHR(cb, &dep_info);
628 }
629
630 m_errorMonitor->ExpectSuccess();
631 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_0_to_0);
632 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_1_to_1);
633 m_errorMonitor->VerifyNotFound();
634
635 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
636 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_0_to_1);
637 m_errorMonitor->VerifyFound();
638
639 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
640 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
641 m_errorMonitor->VerifyFound();
642
643 // NOTE: Since the previous command skips in validation, the state update is never done, and the validation layer thus doesn't
644 // record the write operation to b. So we'll need to repeat it successfully to set up for the *next* test.
645
646 // Use the barrier to clean up the WAW, and try again. (and show that validation is accounting for the barrier effect too.)
647 {
648 auto mem_barrier = lvl_init_struct<VkMemoryBarrier2KHR>();
649 mem_barrier.srcStageMask = VK_PIPELINE_STAGE_2_COPY_BIT_KHR;
650 mem_barrier.dstStageMask = VK_PIPELINE_STAGE_2_COPY_BIT_KHR;
651 mem_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
652 mem_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
653 auto dep_info = lvl_init_struct<VkDependencyInfoKHR>();
654 dep_info.memoryBarrierCount = 1;
655 dep_info.pMemoryBarriers = &mem_barrier;
656 fpCmdPipelineBarrier2KHR(cb, &dep_info);
657 m_errorMonitor->ExpectSuccess();
658 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
659 m_errorMonitor->VerifyNotFound();
660
661 // Use barrier to protect last reader, but not last writer...
662 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
663 mem_barrier.srcAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT_KHR; // Protects C but not B
664 mem_barrier.dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR;
665 fpCmdPipelineBarrier2KHR(cb, &dep_info);
666 vk::CmdCopyImage(cb, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
667 m_errorMonitor->VerifyFound();
668 }
669
670 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_0_front);
671 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
672 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_0_front);
673 m_errorMonitor->VerifyFound();
674
675 m_errorMonitor->ExpectSuccess();
676 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_0_back);
677 m_errorMonitor->VerifyNotFound();
678
679 m_commandBuffer->end();
680}
681
Jeremy Gebben170781d2020-11-19 16:21:21 -0700682TEST_F(VkSyncValTest, SyncCopyOptimalMultiPlanarHazards) {
683 // TODO: Add code to enable sync validation
684 // Enable KHR multiplane req'd extensions
685 bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
686 VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION);
687 if (mp_extensions) {
688 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
689 }
690 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
Mike Schuchardt7cc57842021-09-15 10:49:59 -0700691 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE_1_EXTENSION_NAME);
Jeremy Gebben170781d2020-11-19 16:21:21 -0700692 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
693 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
694 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
695 if (mp_extensions) {
Mike Schuchardt7cc57842021-09-15 10:49:59 -0700696 m_device_extension_names.push_back(VK_KHR_MAINTENANCE_1_EXTENSION_NAME);
Jeremy Gebben170781d2020-11-19 16:21:21 -0700697 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
698 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
699 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
700 } else {
701 printf("%s test requires KHR multiplane extensions, not available. Skipping.\n", kSkipPrefix);
702 return;
703 }
704
705 ASSERT_NO_FATAL_FAILURE(InitState());
706
707 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
708 VkFormat format = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM;
709 VkImageObj image_a(m_device);
710 const auto image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 2, format, usage, VK_IMAGE_TILING_OPTIMAL);
711 // Verify format
712 bool supported = ImageFormatAndFeaturesSupported(instance(), gpu(), image_ci,
713 VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT);
714 if (!supported) {
715 printf("%s Multiplane image format not supported. Skipping test.\n", kSkipPrefix);
716 return; // Assume there's low ROI on searching for different mp formats
717 }
718
719 image_a.Init(image_ci);
720 VkImageObj image_b(m_device);
721 image_b.Init(image_ci);
722 VkImageObj image_c(m_device);
723 image_c.Init(image_ci);
724
725 VkImageSubresourceLayers layer_all_plane0{VK_IMAGE_ASPECT_PLANE_0_BIT_KHR, 0, 0, 2};
726 VkImageSubresourceLayers layer0_plane0{VK_IMAGE_ASPECT_PLANE_0_BIT_KHR, 0, 0, 1};
727 VkImageSubresourceLayers layer0_plane1{VK_IMAGE_ASPECT_PLANE_1_BIT_KHR, 0, 0, 1};
728 VkImageSubresourceLayers layer1_plane1{VK_IMAGE_ASPECT_PLANE_1_BIT_KHR, 0, 1, 1};
729 VkImageSubresourceRange full_subresource_range{
730 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};
731 VkOffset3D zero_offset{0, 0, 0};
732 VkOffset3D one_four_offset{32, 32, 0};
733 VkExtent3D full_extent{128, 128, 1}; // <-- image type is 2D
734 VkExtent3D half_extent{64, 64, 1}; // <-- image type is 2D
735 VkExtent3D one_four_extent{32, 32, 1}; // <-- image type is 2D
736
737 VkImageCopy region_all_plane0_to_all_plane0 = {layer_all_plane0, zero_offset, layer_all_plane0, zero_offset, full_extent};
738 VkImageCopy region_layer0_plane0_to_layer0_plane0 = {layer0_plane0, zero_offset, layer0_plane0, zero_offset, full_extent};
739 VkImageCopy region_layer0_plane0_to_layer0_plane1 = {layer0_plane0, zero_offset, layer0_plane1, zero_offset, half_extent};
740 VkImageCopy region_layer1_plane1_to_layer1_plane1_front = {layer1_plane1, zero_offset, layer1_plane1, zero_offset,
741 one_four_extent};
742 VkImageCopy region_layer1_plane1_to_layer1_plane1_back = {layer1_plane1, one_four_offset, layer1_plane1, one_four_offset,
743 one_four_extent};
744
745 m_commandBuffer->begin();
746
747 image_c.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
748 image_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
749 image_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
750
751 auto cb = m_commandBuffer->handle();
752
753 vk::CmdCopyImage(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
754 &region_all_plane0_to_all_plane0);
755
756 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
757 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
758 &region_all_plane0_to_all_plane0);
759 m_errorMonitor->VerifyFound();
760
761 // 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 -0700762 auto image_barrier = LvlInitStruct<VkImageMemoryBarrier>();
Jeremy Gebben170781d2020-11-19 16:21:21 -0700763 image_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
764 image_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
765 image_barrier.image = image_a.handle();
766 image_barrier.subresourceRange = full_subresource_range;
767 image_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
768 image_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
769 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1,
770 &image_barrier);
771
772 m_errorMonitor->ExpectSuccess();
773 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
774 &region_layer0_plane0_to_layer0_plane0);
775 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
776 &region_layer0_plane0_to_layer0_plane1);
777 m_errorMonitor->VerifyNotFound();
778
779 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
780 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
781 &region_layer0_plane0_to_layer0_plane1);
782 m_errorMonitor->VerifyFound();
783
784 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
785 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
786 &region_all_plane0_to_all_plane0);
787 m_errorMonitor->VerifyFound();
788
789 // NOTE: Since the previous command skips in validation, the state update is never done, and the validation layer thus doesn't
790 // record the write operation to b. So we'll need to repeat it successfully to set up for the *next* test.
791
792 // 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 -0700793 auto mem_barrier = LvlInitStruct<VkMemoryBarrier>();
Jeremy Gebben170781d2020-11-19 16:21:21 -0700794 mem_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
795 mem_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
796 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1, &mem_barrier, 0, nullptr, 0,
797 nullptr);
798 m_errorMonitor->ExpectSuccess();
799 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
800 &region_all_plane0_to_all_plane0);
801 m_errorMonitor->VerifyNotFound();
802
803 // Use barrier to protect last reader, but not last writer...
804 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
805 mem_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; // Protects C but not B
806 mem_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
807 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1, &mem_barrier, 0, nullptr, 0,
808 nullptr);
809 vk::CmdCopyImage(cb, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
810 &region_all_plane0_to_all_plane0);
811 m_errorMonitor->VerifyFound();
812
813 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
814 &region_layer1_plane1_to_layer1_plane1_front);
815 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
816 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
817 &region_layer1_plane1_to_layer1_plane1_front);
818 m_errorMonitor->VerifyFound();
819
820 m_errorMonitor->ExpectSuccess();
821 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
822 &region_layer1_plane1_to_layer1_plane1_back);
823 m_errorMonitor->VerifyNotFound();
824
825 m_commandBuffer->end();
826}
827
828TEST_F(VkSyncValTest, SyncCopyLinearImageHazards) {
829 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
830 ASSERT_NO_FATAL_FAILURE(InitState());
831
832 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
833 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
834 VkImageObj image_a(m_device);
835 const auto image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 1, format, usage, VK_IMAGE_TILING_LINEAR);
836 image_a.Init(image_ci);
837 VkImageObj image_b(m_device);
838 image_b.Init(image_ci);
839 VkImageObj image_c(m_device);
840 image_c.Init(image_ci);
841
842 VkImageSubresourceLayers layers_all{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
843 VkImageSubresourceRange full_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
844 VkOffset3D zero_offset{0, 0, 0};
845 VkOffset3D half_offset{64, 64, 0};
846 VkExtent3D full_extent{128, 128, 1}; // <-- image type is 2D
847 VkExtent3D half_extent{64, 64, 1}; // <-- image type is 2D
848
849 VkImageCopy full_region = {layers_all, zero_offset, layers_all, zero_offset, full_extent};
850 VkImageCopy region_front = {layers_all, zero_offset, layers_all, zero_offset, half_extent};
851 VkImageCopy region_back = {layers_all, half_offset, layers_all, half_offset, half_extent};
852
853 m_commandBuffer->begin();
854
855 image_c.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
856 image_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
857 image_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
858
859 auto cb = m_commandBuffer->handle();
860
861 vk::CmdCopyImage(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
862
863 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
864 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
865 m_errorMonitor->VerifyFound();
866
867 // 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 -0700868 auto image_barrier = LvlInitStruct<VkImageMemoryBarrier>();
Jeremy Gebben170781d2020-11-19 16:21:21 -0700869 image_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
870 image_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
871 image_barrier.image = image_b.handle();
872 image_barrier.subresourceRange = full_subresource_range;
873 image_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
874 image_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
875 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1,
876 &image_barrier);
877
878 m_errorMonitor->ExpectSuccess();
879 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
880 m_errorMonitor->VerifyNotFound();
881
882 // Use barrier to protect last reader, but not last writer...
883 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
884 image_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; // Protects C but not B
885 image_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
886 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1,
887 &image_barrier);
888 vk::CmdCopyImage(cb, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
889 m_errorMonitor->VerifyFound();
890
891 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_front);
892 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
893 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_front);
894 m_errorMonitor->VerifyFound();
895
896 m_errorMonitor->ExpectSuccess();
897 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_back);
898 m_errorMonitor->VerifyNotFound();
899}
900
901TEST_F(VkSyncValTest, SyncCopyLinearMultiPlanarHazards) {
902 // TODO: Add code to enable sync validation
903 // Enable KHR multiplane req'd extensions
904 bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
905 VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION);
906 if (mp_extensions) {
907 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
908 }
909 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
Mike Schuchardt7cc57842021-09-15 10:49:59 -0700910 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE_1_EXTENSION_NAME);
Jeremy Gebben170781d2020-11-19 16:21:21 -0700911 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
912 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
913 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
914 if (mp_extensions) {
Mike Schuchardt7cc57842021-09-15 10:49:59 -0700915 m_device_extension_names.push_back(VK_KHR_MAINTENANCE_1_EXTENSION_NAME);
Jeremy Gebben170781d2020-11-19 16:21:21 -0700916 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
917 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
918 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
919 } else {
920 printf("%s test requires KHR multiplane extensions, not available. Skipping.\n", kSkipPrefix);
921 return;
922 }
923
924 ASSERT_NO_FATAL_FAILURE(InitState());
925
926 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
927 VkFormat format = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM;
928 VkImageObj image_a(m_device);
929 const auto image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 1, format, usage, VK_IMAGE_TILING_LINEAR);
930 // Verify format
931 bool supported = ImageFormatAndFeaturesSupported(instance(), gpu(), image_ci,
932 VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT);
933 if (!supported) {
934 printf("%s Multiplane image format not supported. Skipping test.\n", kSkipPrefix);
935 return; // Assume there's low ROI on searching for different mp formats
936 }
937
938 image_a.Init(image_ci);
939 VkImageObj image_b(m_device);
940 image_b.Init(image_ci);
941 VkImageObj image_c(m_device);
942 image_c.Init(image_ci);
943
944 VkImageSubresourceLayers layer_all_plane0{VK_IMAGE_ASPECT_PLANE_0_BIT_KHR, 0, 0, 1};
945 VkImageSubresourceLayers layer_all_plane1{VK_IMAGE_ASPECT_PLANE_1_BIT_KHR, 0, 0, 1};
946 VkImageSubresourceRange full_subresource_range{
947 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};
948 VkOffset3D zero_offset{0, 0, 0};
949 VkOffset3D one_four_offset{32, 32, 0};
950 VkExtent3D full_extent{128, 128, 1}; // <-- image type is 2D
951 VkExtent3D half_extent{64, 64, 1}; // <-- image type is 2D
952 VkExtent3D one_four_extent{32, 32, 1}; // <-- image type is 2D
953
954 VkImageCopy region_plane0_to_plane0 = {layer_all_plane0, zero_offset, layer_all_plane0, zero_offset, full_extent};
955 VkImageCopy region_plane0_to_plane1 = {layer_all_plane0, zero_offset, layer_all_plane1, zero_offset, half_extent};
956 VkImageCopy region_plane1_to_plane1_front = {layer_all_plane1, zero_offset, layer_all_plane1, zero_offset, one_four_extent};
957 VkImageCopy region_plane1_to_plane1_back = {layer_all_plane1, one_four_offset, layer_all_plane1, one_four_offset,
958 one_four_extent};
959
960 m_commandBuffer->begin();
961
962 image_c.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
963 image_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
964 image_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
965
966 auto cb = m_commandBuffer->handle();
967
968 vk::CmdCopyImage(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
969 &region_plane0_to_plane0);
970
971 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
972 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
973 &region_plane0_to_plane0);
974 m_errorMonitor->VerifyFound();
975
976 // 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 -0700977 auto image_barrier = LvlInitStruct<VkImageMemoryBarrier>();
Jeremy Gebben170781d2020-11-19 16:21:21 -0700978 image_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
979 image_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
980 image_barrier.image = image_a.handle();
981 image_barrier.subresourceRange = full_subresource_range;
982 image_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
983 image_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
984 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1,
985 &image_barrier);
986
987 m_errorMonitor->ExpectSuccess();
988 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
989 &region_plane0_to_plane0);
990 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
991 &region_plane0_to_plane1);
992 m_errorMonitor->VerifyNotFound();
993
994 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
995 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
996 &region_plane0_to_plane1);
997 m_errorMonitor->VerifyFound();
998
999 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1000 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1001 &region_plane0_to_plane0);
1002 m_errorMonitor->VerifyFound();
1003
1004 // NOTE: Since the previous command skips in validation, the state update is never done, and the validation layer thus doesn't
1005 // record the write operation to b. So we'll need to repeat it successfully to set up for the *next* test.
1006
1007 // 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 -07001008 auto mem_barrier = LvlInitStruct<VkMemoryBarrier>();
Jeremy Gebben170781d2020-11-19 16:21:21 -07001009 mem_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1010 mem_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1011 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1, &mem_barrier, 0, nullptr, 0,
1012 nullptr);
1013 m_errorMonitor->ExpectSuccess();
1014 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1015 &region_plane0_to_plane0);
1016 m_errorMonitor->VerifyNotFound();
1017
1018 // Use barrier to protect last reader, but not last writer...
1019 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1020 mem_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; // Protects C but not B
1021 mem_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1022 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1, &mem_barrier, 0, nullptr, 0,
1023 nullptr);
1024 vk::CmdCopyImage(cb, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1025 &region_plane0_to_plane0);
1026 m_errorMonitor->VerifyFound();
1027
1028 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1029 &region_plane1_to_plane1_front);
1030 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1031 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1032 &region_plane1_to_plane1_front);
1033 m_errorMonitor->VerifyFound();
1034
1035 m_errorMonitor->ExpectSuccess();
1036 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1037 &region_plane1_to_plane1_back);
1038 m_errorMonitor->VerifyNotFound();
1039
1040 m_commandBuffer->end();
1041}
1042
1043TEST_F(VkSyncValTest, SyncCopyBufferImageHazards) {
1044 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
1045 ASSERT_NO_FATAL_FAILURE(InitState());
1046
1047 VkBufferObj buffer_a, buffer_b;
1048 VkMemoryPropertyFlags mem_prop = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
1049 buffer_a.init_as_src_and_dst(*m_device, 2048, mem_prop);
1050 buffer_b.init_as_src_and_dst(*m_device, 2048, mem_prop);
1051
1052 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1053 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
1054 VkImageObj image_a(m_device), image_b(m_device);
1055 const auto image_ci = VkImageObj::ImageCreateInfo2D(32, 32, 1, 2, format, usage, VK_IMAGE_TILING_OPTIMAL);
1056 image_a.Init(image_ci);
1057 image_b.Init(image_ci);
1058
1059 VkImageSubresourceLayers layers_0{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
1060 VkImageSubresourceLayers layers_1{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1};
1061 VkOffset3D zero_offset{0, 0, 0};
1062 VkOffset3D half_offset{16, 16, 0};
1063 VkExtent3D half_extent{16, 16, 1}; // <-- image type is 2D
1064
1065 VkBufferImageCopy region_buffer_front_image_0_front = {0, 16, 16, layers_0, zero_offset, half_extent};
1066 VkBufferImageCopy region_buffer_front_image_1_front = {0, 16, 16, layers_1, zero_offset, half_extent};
1067 VkBufferImageCopy region_buffer_front_image_1_back = {0, 16, 16, layers_1, half_offset, half_extent};
1068 VkBufferImageCopy region_buffer_back_image_0_front = {1024, 16, 16, layers_0, zero_offset, half_extent};
1069 VkBufferImageCopy region_buffer_back_image_0_back = {1024, 16, 16, layers_0, half_offset, half_extent};
1070 VkBufferImageCopy region_buffer_back_image_1_front = {1024, 16, 16, layers_1, zero_offset, half_extent};
1071 VkBufferImageCopy region_buffer_back_image_1_back = {1024, 16, 16, layers_1, half_offset, half_extent};
1072
1073 m_commandBuffer->begin();
1074 image_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1075 image_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1076
1077 auto cb = m_commandBuffer->handle();
1078 vk::CmdCopyBufferToImage(cb, buffer_a.handle(), image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1079 &region_buffer_front_image_0_front);
1080
1081 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1082 vk::CmdCopyBufferToImage(cb, buffer_a.handle(), image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1083 &region_buffer_front_image_0_front);
1084 m_errorMonitor->VerifyFound();
1085
1086 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1087 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1088 vk::CmdCopyImageToBuffer(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_a.handle(), 1,
1089 &region_buffer_front_image_0_front);
1090 m_errorMonitor->VerifyFound();
1091
1092 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1093 vk::CmdCopyImageToBuffer(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_a.handle(), 1,
1094 &region_buffer_back_image_0_front);
1095 m_errorMonitor->VerifyFound();
1096
1097 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1098 vk::CmdCopyImageToBuffer(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_a.handle(), 1,
1099 &region_buffer_front_image_1_front);
1100 m_errorMonitor->VerifyFound();
1101
1102 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1103 vk::CmdCopyImageToBuffer(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_a.handle(), 1,
1104 &region_buffer_front_image_1_back);
1105 m_errorMonitor->VerifyFound();
1106
1107 m_errorMonitor->ExpectSuccess();
1108 vk::CmdCopyImageToBuffer(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_a.handle(), 1, &region_buffer_back_image_0_back);
1109 m_errorMonitor->VerifyNotFound();
1110
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07001111 auto buffer_barrier = LvlInitStruct<VkBufferMemoryBarrier>();
Jeremy Gebben170781d2020-11-19 16:21:21 -07001112 buffer_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1113 buffer_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1114 buffer_barrier.buffer = buffer_a.handle();
1115 buffer_barrier.offset = 1024;
1116 buffer_barrier.size = 2048;
1117 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, &buffer_barrier, 0,
1118 nullptr);
1119
1120 m_errorMonitor->ExpectSuccess();
1121 vk::CmdCopyImageToBuffer(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_a.handle(), 1,
1122 &region_buffer_back_image_1_front);
1123 m_errorMonitor->VerifyNotFound();
1124
1125 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, &buffer_barrier, 0,
1126 nullptr);
1127
1128 m_errorMonitor->ExpectSuccess();
1129 vk::CmdCopyImageToBuffer(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_a.handle(), 1, &region_buffer_back_image_1_back);
1130 m_errorMonitor->VerifyNotFound();
1131
1132 vk::CmdCopyImageToBuffer(cb, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_b.handle(), 1,
1133 &region_buffer_front_image_0_front);
1134
1135 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1136 vk::CmdCopyImageToBuffer(cb, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_b.handle(), 1,
1137 &region_buffer_front_image_0_front);
1138 m_errorMonitor->VerifyFound();
1139
1140 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1141 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1142 vk::CmdCopyBufferToImage(cb, buffer_b.handle(), image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1143 &region_buffer_front_image_0_front);
1144 m_errorMonitor->VerifyFound();
1145
1146 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1147 vk::CmdCopyBufferToImage(cb, buffer_b.handle(), image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1148 &region_buffer_back_image_0_front);
1149 m_errorMonitor->VerifyFound();
1150
1151 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1152 vk::CmdCopyBufferToImage(cb, buffer_b.handle(), image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1153 &region_buffer_front_image_1_front);
1154 m_errorMonitor->VerifyFound();
1155
1156 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1157 vk::CmdCopyBufferToImage(cb, buffer_b.handle(), image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1158 &region_buffer_front_image_1_back);
1159 m_errorMonitor->VerifyFound();
1160
1161 m_errorMonitor->ExpectSuccess();
1162 vk::CmdCopyBufferToImage(cb, buffer_b.handle(), image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_buffer_back_image_0_back);
1163 m_errorMonitor->VerifyNotFound();
1164
1165 buffer_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
1166 buffer_barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
1167 buffer_barrier.buffer = buffer_b.handle();
1168 buffer_barrier.offset = 1024;
1169 buffer_barrier.size = 2048;
1170 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, &buffer_barrier, 0,
1171 nullptr);
1172
1173 m_errorMonitor->ExpectSuccess();
1174 vk::CmdCopyBufferToImage(cb, buffer_b.handle(), image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1175 &region_buffer_back_image_1_front);
1176 m_errorMonitor->VerifyNotFound();
1177
1178 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, &buffer_barrier, 0,
1179 nullptr);
1180
1181 m_errorMonitor->ExpectSuccess();
1182 vk::CmdCopyBufferToImage(cb, buffer_b.handle(), image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_buffer_back_image_1_back);
1183 m_errorMonitor->VerifyNotFound();
1184
1185 m_commandBuffer->end();
1186}
1187
1188TEST_F(VkSyncValTest, SyncBlitImageHazards) {
1189 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
1190 ASSERT_NO_FATAL_FAILURE(InitState());
1191
1192 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1193 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
1194 VkImageObj image_a(m_device), image_b(m_device);
1195 const auto image_ci = VkImageObj::ImageCreateInfo2D(32, 32, 1, 2, format, usage, VK_IMAGE_TILING_OPTIMAL);
1196 image_a.Init(image_ci);
1197 image_b.Init(image_ci);
1198
1199 VkImageSubresourceLayers layers_0{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
1200 VkImageSubresourceLayers layers_1{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1};
1201 VkOffset3D zero_offset{0, 0, 0};
1202 VkOffset3D half_0_offset{16, 16, 0};
1203 VkOffset3D half_1_offset{16, 16, 1};
1204 VkOffset3D full_offset{32, 32, 1};
1205 VkImageBlit region_0_front_1_front = {layers_0, {zero_offset, half_1_offset}, layers_1, {zero_offset, half_1_offset}};
1206 VkImageBlit region_1_front_0_front = {layers_1, {zero_offset, half_1_offset}, layers_0, {zero_offset, half_1_offset}};
1207 VkImageBlit region_1_back_0_back = {layers_1, {half_0_offset, full_offset}, layers_0, {half_0_offset, full_offset}};
1208
1209 m_commandBuffer->begin();
1210 image_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1211 image_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1212
1213 auto cb = m_commandBuffer->handle();
1214
1215 vk::CmdBlitImage(cb, image_a.image(), VK_IMAGE_LAYOUT_GENERAL, image_b.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
1216 &region_0_front_1_front, VK_FILTER_NEAREST);
1217
1218 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1219 vk::CmdBlitImage(cb, image_a.image(), VK_IMAGE_LAYOUT_GENERAL, image_b.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
1220 &region_0_front_1_front, VK_FILTER_NEAREST);
1221 m_errorMonitor->VerifyFound();
1222
1223 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1224 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1225 vk::CmdBlitImage(cb, image_b.image(), VK_IMAGE_LAYOUT_GENERAL, image_a.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
1226 &region_1_front_0_front, VK_FILTER_NEAREST);
1227 m_errorMonitor->VerifyFound();
1228
1229 m_errorMonitor->ExpectSuccess();
1230 vk::CmdBlitImage(cb, image_b.image(), VK_IMAGE_LAYOUT_GENERAL, image_a.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
1231 &region_1_back_0_back, VK_FILTER_NEAREST);
1232 m_errorMonitor->VerifyNotFound();
1233
1234 m_commandBuffer->end();
1235}
1236
1237TEST_F(VkSyncValTest, SyncRenderPassBeginTransitionHazard) {
1238 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
1239 ASSERT_NO_FATAL_FAILURE(InitState());
John Zulaufbb373682021-10-05 17:21:40 -06001240 const VkSubpassDependency external_subpass_dependency = {VK_SUBPASS_EXTERNAL,
1241 0,
1242 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
1243 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
1244 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1245 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1246 VK_DEPENDENCY_BY_REGION_BIT};
1247 m_additionalSubpassDependencies.push_back(external_subpass_dependency);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001248 ASSERT_NO_FATAL_FAILURE(InitRenderTarget(2));
1249
1250 // Render Target Information
1251 auto width = static_cast<uint32_t>(m_width);
1252 auto height = static_cast<uint32_t>(m_height);
1253 auto *rt_0 = m_renderTargets[0].get();
1254 auto *rt_1 = m_renderTargets[1].get();
1255
1256 // Other buffers with which to interact
1257 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1258 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
1259 VkImageObj image_a(m_device), image_b(m_device);
1260 const auto image_ci = VkImageObj::ImageCreateInfo2D(width, height, 1, 1, format, usage, VK_IMAGE_TILING_OPTIMAL);
1261 image_a.Init(image_ci);
1262 image_b.Init(image_ci);
1263
1264 VkOffset3D zero_offset{0, 0, 0};
1265 VkExtent3D full_extent{width, height, 1}; // <-- image type is 2D
1266 VkImageSubresourceLayers layer_color{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
1267 VkImageCopy region_to_copy = {layer_color, zero_offset, layer_color, zero_offset, full_extent};
1268
1269 auto cb = m_commandBuffer->handle();
1270
1271 m_errorMonitor->ExpectSuccess();
1272 m_commandBuffer->begin();
1273 image_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1274 image_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1275 rt_0->SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1276 rt_1->SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1277
1278 rt_0->SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1279 vk::CmdCopyImage(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, rt_0->handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_to_copy);
1280 m_errorMonitor->VerifyNotFound();
1281
1282 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1283 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); // This fails so the driver call is skip and no end is valid
1284 m_errorMonitor->VerifyFound();
1285
1286 m_errorMonitor->ExpectSuccess();
1287 // Use the barrier to clean up the WAW, and try again. (and show that validation is accounting for the barrier effect too.)
1288 VkImageSubresourceRange rt_full_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07001289 auto image_barrier = LvlInitStruct<VkImageMemoryBarrier>();
Jeremy Gebben170781d2020-11-19 16:21:21 -07001290 image_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
John Zulaufbb373682021-10-05 17:21:40 -06001291 image_barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
Jeremy Gebben170781d2020-11-19 16:21:21 -07001292 image_barrier.image = rt_0->handle();
1293 image_barrier.subresourceRange = rt_full_subresource_range;
1294 image_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
1295 image_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
John Zulaufbb373682021-10-05 17:21:40 -06001296 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0,
1297 nullptr, 1, &image_barrier);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001298 vk::CmdCopyImage(cb, rt_1->handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_to_copy);
1299 m_errorMonitor->VerifyNotFound();
1300
1301 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1302 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); // This fails so the driver call is skip and no end is valid
1303 m_errorMonitor->VerifyFound();
1304
1305 m_errorMonitor->ExpectSuccess();
1306 // A global execution barrier that the implict external dependency can chain with should work...
1307 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, 0,
1308 nullptr);
1309
1310 // With the barrier above, the layout transition has a chained execution sync operation, and the default
1311 // implict VkSubpassDependency safes the load op clear vs. the layout transition...
1312 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1313 m_commandBuffer->EndRenderPass();
1314 m_errorMonitor->VerifyNotFound();
1315}
1316
1317TEST_F(VkSyncValTest, SyncCmdDispatchDrawHazards) {
1318 // TODO: Add code to enable sync validation
1319 SetTargetApiVersion(VK_API_VERSION_1_2);
1320
1321 // Enable VK_KHR_draw_indirect_count for KHR variants
1322 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
sfricke-samsung6fc3e322022-02-15 22:41:29 -08001323 VkPhysicalDeviceVulkan12Features features12 = LvlInitStruct<VkPhysicalDeviceVulkan12Features>();
Jeremy Gebben170781d2020-11-19 16:21:21 -07001324 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME)) {
1325 m_device_extension_names.push_back(VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME);
1326 if (DeviceValidationVersion() >= VK_API_VERSION_1_2) {
1327 features12.drawIndirectCount = VK_TRUE;
1328 }
1329 }
1330 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features12, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
1331 bool has_khr_indirect = DeviceExtensionEnabled(VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME);
1332 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1333
1334 VkImageUsageFlags image_usage_combine = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
1335 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1336 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
1337 VkImageObj image_c_a(m_device), image_c_b(m_device);
1338 const auto image_c_ci = VkImageObj::ImageCreateInfo2D(16, 16, 1, 1, format, image_usage_combine, VK_IMAGE_TILING_OPTIMAL);
1339 image_c_a.Init(image_c_ci);
1340 image_c_b.Init(image_c_ci);
1341
1342 VkImageView imageview_c = image_c_a.targetView(format);
1343 VkImageUsageFlags image_usage_storage =
1344 VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1345 VkImageObj image_s_a(m_device), image_s_b(m_device);
1346 const auto image_s_ci = VkImageObj::ImageCreateInfo2D(16, 16, 1, 1, format, image_usage_storage, VK_IMAGE_TILING_OPTIMAL);
1347 image_s_a.Init(image_s_ci);
1348 image_s_b.Init(image_s_ci);
1349 image_s_a.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1350 image_s_b.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1351
1352 VkImageView imageview_s = image_s_a.targetView(format);
1353
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001354 vk_testing::Sampler sampler_s, sampler_c;
Jeremy Gebben170781d2020-11-19 16:21:21 -07001355 VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001356 sampler_s.init(*m_device, sampler_ci);
1357 sampler_c.init(*m_device, sampler_ci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001358
1359 VkBufferObj buffer_a, buffer_b;
1360 VkMemoryPropertyFlags mem_prop = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
1361 VkBufferUsageFlags buffer_usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT |
1362 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1363 buffer_a.init(*m_device, buffer_a.create_info(2048, buffer_usage, nullptr), mem_prop);
1364 buffer_b.init(*m_device, buffer_b.create_info(2048, buffer_usage, nullptr), mem_prop);
1365
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001366 vk_testing::BufferView bufferview;
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07001367 auto bvci = LvlInitStruct<VkBufferViewCreateInfo>();
Jeremy Gebben170781d2020-11-19 16:21:21 -07001368 bvci.buffer = buffer_a.handle();
1369 bvci.format = VK_FORMAT_R32_SFLOAT;
1370 bvci.offset = 0;
1371 bvci.range = VK_WHOLE_SIZE;
1372
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001373 bufferview.init(*m_device, bvci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001374
1375 OneOffDescriptorSet descriptor_set(m_device,
1376 {
1377 {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
1378 {1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr},
1379 {2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_ALL, nullptr},
1380 {3, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
1381 });
1382
sfricke-samsung36428462021-02-10 01:23:34 -08001383 descriptor_set.WriteDescriptorBufferInfo(0, buffer_a.handle(), 0, 2048);
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001384 descriptor_set.WriteDescriptorImageInfo(1, imageview_c, sampler_c.handle(), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
Jeremy Gebben170781d2020-11-19 16:21:21 -07001385 VK_IMAGE_LAYOUT_GENERAL);
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001386 descriptor_set.WriteDescriptorImageInfo(2, imageview_s, sampler_s.handle(), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_IMAGE_LAYOUT_GENERAL);
1387 descriptor_set.WriteDescriptorBufferView(3, bufferview.handle());
Jeremy Gebben170781d2020-11-19 16:21:21 -07001388 descriptor_set.UpdateDescriptorSets();
1389
1390 // Dispatch
sjfricke394227a2022-06-20 16:47:38 +09001391 const char *csSource = R"glsl(
sfricke-samsung1c0b96a2021-07-08 22:24:09 -07001392 #version 450
1393 layout(set=0, binding=0) uniform foo { float x; } ub0;
1394 layout(set=0, binding=1) uniform sampler2D cis1;
1395 layout(set=0, binding=2, rgba8) uniform readonly image2D si2;
1396 layout(set=0, binding=3, r32f) uniform readonly imageBuffer stb3;
1397 void main(){
1398 vec4 vColor4;
1399 vColor4.x = ub0.x;
1400 vColor4 = texture(cis1, vec2(0));
1401 vColor4 = imageLoad(si2, ivec2(0));
1402 vColor4 = imageLoad(stb3, 0);
1403 }
1404 )glsl";
Jeremy Gebben170781d2020-11-19 16:21:21 -07001405
John Zulaufbe8562b2020-12-15 14:21:01 -07001406 VkEventObj event;
1407 event.init(*m_device, VkEventObj::create_info(0));
1408 VkEvent event_handle = event.handle();
1409
Jeremy Gebben170781d2020-11-19 16:21:21 -07001410 CreateComputePipelineHelper pipe(*this);
1411 pipe.InitInfo();
sfricke-samsungae54c1e2022-01-21 05:35:21 -08001412 pipe.cs_.reset(new VkShaderObj(this, csSource, VK_SHADER_STAGE_COMPUTE_BIT));
Jeremy Gebben170781d2020-11-19 16:21:21 -07001413 pipe.InitState();
1414 pipe.pipeline_layout_ = VkPipelineLayoutObj(m_device, {&descriptor_set.layout_});
1415 pipe.CreateComputePipeline();
1416
1417 m_commandBuffer->begin();
1418
1419 VkBufferCopy buffer_region = {0, 0, 2048};
1420 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_b.handle(), buffer_a.handle(), 1, &buffer_region);
1421
1422 VkImageSubresourceLayers layer{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
1423 VkOffset3D zero_offset{0, 0, 0};
1424 VkExtent3D full_extent{16, 16, 1};
1425 VkImageCopy image_region = {layer, zero_offset, layer, zero_offset, full_extent};
1426 vk::CmdCopyImage(m_commandBuffer->handle(), image_c_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_c_a.handle(),
1427 VK_IMAGE_LAYOUT_GENERAL, 1, &image_region);
1428 vk::CmdCopyImage(m_commandBuffer->handle(), image_s_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_s_a.handle(),
1429 VK_IMAGE_LAYOUT_GENERAL, 1, &image_region);
1430
1431 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_);
1432 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_layout_.handle(), 0, 1,
1433 &descriptor_set.set_, 0, nullptr);
1434
1435 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1436 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1437 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1438 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1439 vk::CmdDispatch(m_commandBuffer->handle(), 1, 1, 1);
1440 m_errorMonitor->VerifyFound();
1441
1442 m_commandBuffer->end();
1443 m_commandBuffer->reset();
1444 m_commandBuffer->begin();
1445
1446 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_);
1447 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_layout_.handle(), 0, 1,
1448 &descriptor_set.set_, 0, nullptr);
1449 vk::CmdDispatch(m_commandBuffer->handle(), 1, 1, 1);
1450
1451 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1452 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_b.handle(), buffer_a.handle(), 1, &buffer_region);
1453 m_errorMonitor->VerifyFound();
1454
1455 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1456 vk::CmdCopyImage(m_commandBuffer->handle(), image_c_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_c_a.handle(),
1457 VK_IMAGE_LAYOUT_GENERAL, 1, &image_region);
1458 m_errorMonitor->VerifyFound();
1459
1460 m_commandBuffer->end();
1461 m_commandBuffer->reset();
1462
1463 // DispatchIndirect
1464 m_errorMonitor->ExpectSuccess();
1465 VkBufferObj buffer_dispatchIndirect, buffer_dispatchIndirect2;
1466 buffer_usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1467 buffer_dispatchIndirect.init(
1468 *m_device, buffer_dispatchIndirect.create_info(sizeof(VkDispatchIndirectCommand), buffer_usage, nullptr), mem_prop);
1469 buffer_dispatchIndirect2.init(
1470 *m_device, buffer_dispatchIndirect2.create_info(sizeof(VkDispatchIndirectCommand), buffer_usage, nullptr), mem_prop);
1471 m_commandBuffer->begin();
1472 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_);
1473 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_layout_.handle(), 0, 1,
1474 &descriptor_set.set_, 0, nullptr);
1475 vk::CmdDispatchIndirect(m_commandBuffer->handle(), buffer_dispatchIndirect.handle(), 0);
1476 m_commandBuffer->end();
1477 m_errorMonitor->VerifyNotFound();
1478
1479 m_commandBuffer->reset();
1480 m_commandBuffer->begin();
1481
1482 buffer_region = {0, 0, sizeof(VkDispatchIndirectCommand)};
1483 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_dispatchIndirect2.handle(), buffer_dispatchIndirect.handle(), 1,
1484 &buffer_region);
1485 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_);
1486 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_layout_.handle(), 0, 1,
1487 &descriptor_set.set_, 0, nullptr);
1488 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1489 vk::CmdDispatchIndirect(m_commandBuffer->handle(), buffer_dispatchIndirect.handle(), 0);
1490 m_errorMonitor->VerifyFound();
1491 m_commandBuffer->end();
1492
1493 // Draw
1494 m_errorMonitor->ExpectSuccess();
1495 const float vbo_data[3] = {1.f, 0.f, 1.f};
1496 VkVertexInputAttributeDescription VertexInputAttributeDescription = {0, 0, VK_FORMAT_R32G32B32_SFLOAT, sizeof(vbo_data)};
1497 VkVertexInputBindingDescription VertexInputBindingDescription = {0, sizeof(vbo_data), VK_VERTEX_INPUT_RATE_VERTEX};
1498 VkBufferObj vbo, vbo2;
1499 buffer_usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1500 vbo.init(*m_device, vbo.create_info(sizeof(vbo_data), buffer_usage, nullptr), mem_prop);
1501 vbo2.init(*m_device, vbo2.create_info(sizeof(vbo_data), buffer_usage, nullptr), mem_prop);
1502
sfricke-samsungae54c1e2022-01-21 05:35:21 -08001503 VkShaderObj vs(this, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT);
1504 VkShaderObj fs(this, csSource, VK_SHADER_STAGE_FRAGMENT_BIT);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001505
1506 CreatePipelineHelper g_pipe(*this);
1507 g_pipe.InitInfo();
1508 g_pipe.InitState();
1509 g_pipe.vi_ci_.pVertexBindingDescriptions = &VertexInputBindingDescription;
1510 g_pipe.vi_ci_.vertexBindingDescriptionCount = 1;
1511 g_pipe.vi_ci_.pVertexAttributeDescriptions = &VertexInputAttributeDescription;
1512 g_pipe.vi_ci_.vertexAttributeDescriptionCount = 1;
1513 g_pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
1514 g_pipe.pipeline_layout_ = VkPipelineLayoutObj(m_device, {&descriptor_set.layout_});
1515 ASSERT_VK_SUCCESS(g_pipe.CreateGraphicsPipeline());
1516
1517 m_commandBuffer->reset();
1518 m_commandBuffer->begin();
1519 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1520 VkDeviceSize offset = 0;
1521 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1522
1523 VkViewport viewport = {0, 0, 16, 16, 0, 1};
1524 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1525 VkRect2D scissor = {{0, 0}, {16, 16}};
1526 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1527
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 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1532 m_commandBuffer->EndRenderPass();
1533 m_commandBuffer->end();
1534 m_errorMonitor->VerifyNotFound();
1535
1536 m_commandBuffer->reset();
1537 m_commandBuffer->begin();
1538
1539 buffer_region = {0, 0, sizeof(vbo_data)};
1540 vk::CmdCopyBuffer(m_commandBuffer->handle(), vbo2.handle(), vbo.handle(), 1, &buffer_region);
1541
1542 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1543 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1544 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1545 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1546 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1547 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1548 &descriptor_set.set_, 0, nullptr);
1549
1550 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1551 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1552 m_errorMonitor->VerifyFound();
1553
1554 m_commandBuffer->EndRenderPass();
1555 m_commandBuffer->end();
1556
John Zulaufbe8562b2020-12-15 14:21:01 -07001557 // Repeat the draw test with a WaitEvent to protect it.
1558 m_errorMonitor->ExpectSuccess();
1559 m_commandBuffer->reset();
1560 m_commandBuffer->begin();
1561
1562 vk::CmdCopyBuffer(m_commandBuffer->handle(), vbo2.handle(), vbo.handle(), 1, &buffer_region);
1563
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07001564 auto vbo_barrier = LvlInitStruct<VkBufferMemoryBarrier>();
John Zulaufbe8562b2020-12-15 14:21:01 -07001565 vbo_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1566 vbo_barrier.dstAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
1567 vbo_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1568 vbo_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1569 vbo_barrier.buffer = vbo.handle();
1570 vbo_barrier.offset = buffer_region.dstOffset;
1571 vbo_barrier.size = buffer_region.size;
1572
1573 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
1574
1575 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1576 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1577 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1578 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1579 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1580 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1581 &descriptor_set.set_, 0, nullptr);
1582
1583 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0, nullptr, 1,
1584 &vbo_barrier, 0, nullptr);
1585 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1586
1587 m_commandBuffer->EndRenderPass();
1588 m_commandBuffer->end();
1589 m_errorMonitor->VerifyNotFound();
1590
Jeremy Gebben170781d2020-11-19 16:21:21 -07001591 // DrawIndexed
1592 m_errorMonitor->ExpectSuccess();
1593 const float ibo_data[3] = {0.f, 0.f, 0.f};
1594 VkBufferObj ibo, ibo2;
1595 buffer_usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1596 ibo.init(*m_device, ibo.create_info(sizeof(ibo_data), buffer_usage, nullptr), mem_prop);
1597 ibo2.init(*m_device, ibo2.create_info(sizeof(ibo_data), buffer_usage, nullptr), mem_prop);
1598
1599 m_commandBuffer->reset();
1600 m_commandBuffer->begin();
1601 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1602 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1603 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), ibo.handle(), 0, VK_INDEX_TYPE_UINT16);
1604 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1605 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1606
1607 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1608 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1609 &descriptor_set.set_, 0, nullptr);
1610 m_commandBuffer->DrawIndexed(3, 1, 0, 0, 0);
1611 m_commandBuffer->EndRenderPass();
1612 m_commandBuffer->end();
1613 m_errorMonitor->VerifyNotFound();
1614
1615 m_commandBuffer->reset();
1616 m_commandBuffer->begin();
1617
1618 buffer_region = {0, 0, sizeof(ibo_data)};
1619 vk::CmdCopyBuffer(m_commandBuffer->handle(), ibo2.handle(), ibo.handle(), 1, &buffer_region);
1620
1621 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1622 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1623 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), ibo.handle(), 0, VK_INDEX_TYPE_UINT16);
1624 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1625 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1626 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1627 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1628 &descriptor_set.set_, 0, nullptr);
1629
1630 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1631 m_commandBuffer->DrawIndexed(3, 1, 0, 0, 0);
1632 m_errorMonitor->VerifyFound();
1633
1634 m_commandBuffer->EndRenderPass();
1635 m_commandBuffer->end();
1636
1637 // DrawIndirect
1638 m_errorMonitor->ExpectSuccess();
1639 VkBufferObj buffer_drawIndirect, buffer_drawIndirect2;
1640 buffer_usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1641 buffer_drawIndirect.init(*m_device, buffer_drawIndirect.create_info(sizeof(VkDrawIndirectCommand), buffer_usage, nullptr),
1642 mem_prop);
1643 buffer_drawIndirect2.init(*m_device, buffer_drawIndirect2.create_info(sizeof(VkDrawIndirectCommand), buffer_usage, nullptr),
1644 mem_prop);
1645
1646 m_commandBuffer->reset();
1647 m_commandBuffer->begin();
1648 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1649 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1650 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1651 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1652
1653 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1654 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1655 &descriptor_set.set_, 0, nullptr);
1656 vk::CmdDrawIndirect(m_commandBuffer->handle(), buffer_drawIndirect.handle(), 0, 1, sizeof(VkDrawIndirectCommand));
1657 m_commandBuffer->EndRenderPass();
1658 m_commandBuffer->end();
1659 m_errorMonitor->VerifyNotFound();
1660
1661 m_commandBuffer->reset();
1662 m_commandBuffer->begin();
1663
1664 buffer_region = {0, 0, sizeof(VkDrawIndirectCommand)};
1665 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_drawIndirect2.handle(), buffer_drawIndirect.handle(), 1, &buffer_region);
1666
1667 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1668 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1669 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1670 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1671 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1672 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1673 &descriptor_set.set_, 0, nullptr);
1674
1675 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1676 vk::CmdDrawIndirect(m_commandBuffer->handle(), buffer_drawIndirect.handle(), 0, 1, sizeof(VkDrawIndirectCommand));
1677 m_errorMonitor->VerifyFound();
1678
1679 m_commandBuffer->EndRenderPass();
1680 m_commandBuffer->end();
1681
1682 // DrawIndexedIndirect
1683 m_errorMonitor->ExpectSuccess();
1684 VkBufferObj buffer_drawIndexedIndirect, buffer_drawIndexedIndirect2;
1685 buffer_usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1686 buffer_drawIndexedIndirect.init(
1687 *m_device, buffer_drawIndexedIndirect.create_info(sizeof(VkDrawIndexedIndirectCommand), buffer_usage, nullptr), mem_prop);
1688 buffer_drawIndexedIndirect2.init(
1689 *m_device, buffer_drawIndexedIndirect2.create_info(sizeof(VkDrawIndexedIndirectCommand), buffer_usage, nullptr), mem_prop);
1690
1691 m_commandBuffer->reset();
1692 m_commandBuffer->begin();
1693 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1694 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1695 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), ibo.handle(), 0, VK_INDEX_TYPE_UINT16);
1696 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1697 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1698
1699 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1700 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1701 &descriptor_set.set_, 0, nullptr);
1702 vk::CmdDrawIndexedIndirect(m_commandBuffer->handle(), buffer_drawIndirect.handle(), 0, 1, sizeof(VkDrawIndexedIndirectCommand));
1703 m_commandBuffer->EndRenderPass();
1704 m_commandBuffer->end();
1705 m_errorMonitor->VerifyNotFound();
1706
1707 m_commandBuffer->reset();
1708 m_commandBuffer->begin();
1709
1710 buffer_region = {0, 0, sizeof(VkDrawIndexedIndirectCommand)};
1711 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_drawIndexedIndirect2.handle(), buffer_drawIndexedIndirect.handle(), 1,
1712 &buffer_region);
1713
1714 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1715 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1716 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), ibo.handle(), 0, VK_INDEX_TYPE_UINT16);
1717 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1718 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1719 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1720 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1721 &descriptor_set.set_, 0, nullptr);
1722
1723 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1724 vk::CmdDrawIndexedIndirect(m_commandBuffer->handle(), buffer_drawIndexedIndirect.handle(), 0, 1,
1725 sizeof(VkDrawIndexedIndirectCommand));
1726 m_errorMonitor->VerifyFound();
1727
1728 m_commandBuffer->EndRenderPass();
1729 m_commandBuffer->end();
1730
1731 if (has_khr_indirect) {
1732 // DrawIndirectCount
1733 auto fpCmdDrawIndirectCountKHR =
1734 (PFN_vkCmdDrawIndirectCount)vk::GetDeviceProcAddr(m_device->device(), "vkCmdDrawIndirectCountKHR");
1735 if (!fpCmdDrawIndirectCountKHR) {
1736 printf("%s Test requires unsupported vkCmdDrawIndirectCountKHR feature. Skipped.\n", kSkipPrefix);
1737 } else {
1738 m_errorMonitor->ExpectSuccess();
1739 VkBufferObj buffer_count, buffer_count2;
1740 buffer_usage =
1741 VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1742 buffer_count.init(*m_device, buffer_count.create_info(sizeof(uint32_t), buffer_usage, nullptr), mem_prop);
1743 buffer_count2.init(*m_device, buffer_count2.create_info(sizeof(uint32_t), buffer_usage, nullptr), mem_prop);
1744
1745 m_commandBuffer->reset();
1746 m_commandBuffer->begin();
1747 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1748 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1749 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1750 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1751
1752 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1753 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(),
1754 0, 1, &descriptor_set.set_, 0, nullptr);
1755 fpCmdDrawIndirectCountKHR(m_commandBuffer->handle(), buffer_drawIndirect.handle(), 0, buffer_count.handle(), 0, 1,
1756 sizeof(VkDrawIndirectCommand));
1757 m_commandBuffer->EndRenderPass();
1758 m_commandBuffer->end();
1759 m_errorMonitor->VerifyNotFound();
1760
1761 m_commandBuffer->reset();
1762 m_commandBuffer->begin();
1763
1764 buffer_region = {0, 0, sizeof(uint32_t)};
1765 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_count2.handle(), buffer_count.handle(), 1, &buffer_region);
1766
1767 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1768 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1769 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1770 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1771 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1772 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(),
1773 0, 1, &descriptor_set.set_, 0, nullptr);
1774
1775 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1776 fpCmdDrawIndirectCountKHR(m_commandBuffer->handle(), buffer_drawIndirect.handle(), 0, buffer_count.handle(), 0, 1,
1777 sizeof(VkDrawIndirectCommand));
1778 m_errorMonitor->VerifyFound();
1779
1780 m_commandBuffer->EndRenderPass();
1781 m_commandBuffer->end();
1782 }
1783
1784 // DrawIndexedIndirectCount
1785 auto fpCmdDrawIndexIndirectCountKHR =
1786 (PFN_vkCmdDrawIndirectCount)vk::GetDeviceProcAddr(m_device->device(), "vkCmdDrawIndexedIndirectCountKHR");
1787 if (!fpCmdDrawIndexIndirectCountKHR) {
1788 printf("%s Test requires unsupported vkCmdDrawIndexedIndirectCountKHR feature. Skipped.\n", kSkipPrefix);
1789 } else {
1790 m_errorMonitor->ExpectSuccess();
1791 VkBufferObj buffer_count, buffer_count2;
1792 buffer_usage =
1793 VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1794 buffer_count.init(*m_device, buffer_count.create_info(sizeof(uint32_t), buffer_usage, nullptr), mem_prop);
1795 buffer_count2.init(*m_device, buffer_count2.create_info(sizeof(uint32_t), buffer_usage, nullptr), mem_prop);
1796
1797 m_commandBuffer->reset();
1798 m_commandBuffer->begin();
1799 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1800 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1801 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), ibo.handle(), 0, VK_INDEX_TYPE_UINT16);
1802 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1803 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1804
1805 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1806 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(),
1807 0, 1, &descriptor_set.set_, 0, nullptr);
1808 fpCmdDrawIndexIndirectCountKHR(m_commandBuffer->handle(), buffer_drawIndexedIndirect.handle(), 0, buffer_count.handle(),
1809 0, 1, sizeof(VkDrawIndexedIndirectCommand));
1810 m_commandBuffer->EndRenderPass();
1811 m_commandBuffer->end();
1812 m_errorMonitor->VerifyNotFound();
1813
1814 m_commandBuffer->reset();
1815 m_commandBuffer->begin();
1816
1817 buffer_region = {0, 0, sizeof(uint32_t)};
1818 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_count2.handle(), buffer_count.handle(), 1, &buffer_region);
1819
1820 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1821 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1822 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), ibo.handle(), 0, VK_INDEX_TYPE_UINT16);
1823 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1824 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1825 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1826 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(),
1827 0, 1, &descriptor_set.set_, 0, nullptr);
1828
1829 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1830 fpCmdDrawIndexIndirectCountKHR(m_commandBuffer->handle(), buffer_drawIndexedIndirect.handle(), 0, buffer_count.handle(),
1831 0, 1, sizeof(VkDrawIndexedIndirectCommand));
1832 m_errorMonitor->VerifyFound();
1833
1834 m_commandBuffer->EndRenderPass();
1835 m_commandBuffer->end();
1836 }
1837 } else {
1838 printf("%s Test requires unsupported vkCmdDrawIndirectCountKHR & vkDrawIndexedIndirectCountKHR feature. Skipped.\n",
1839 kSkipPrefix);
1840 }
1841}
1842
1843TEST_F(VkSyncValTest, SyncCmdClear) {
1844 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
1845 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
1846 // CmdClearColorImage
1847 m_errorMonitor->ExpectSuccess();
1848 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1849 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
1850 VkImageObj image_a(m_device), image_b(m_device);
1851 auto image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 1, format, usage, VK_IMAGE_TILING_OPTIMAL);
1852 image_a.Init(image_ci);
1853 image_b.Init(image_ci);
1854
1855 VkImageSubresourceLayers layers_all{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
1856 VkOffset3D zero_offset{0, 0, 0};
1857 VkExtent3D full_extent{128, 128, 1}; // <-- image type is 2D
1858 VkImageSubresourceRange full_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
1859
1860 VkImageCopy full_region = {layers_all, zero_offset, layers_all, zero_offset, full_extent};
1861
1862 m_commandBuffer->begin();
1863
1864 image_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1865 image_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1866
1867 auto cb = m_commandBuffer->handle();
1868 VkClearColorValue ccv = {};
1869 vk::CmdClearColorImage(m_commandBuffer->handle(), image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &full_subresource_range);
1870 m_commandBuffer->end();
1871 m_errorMonitor->VerifyNotFound();
1872
1873 m_commandBuffer->reset();
1874 m_commandBuffer->begin();
1875 vk::CmdCopyImage(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
1876
1877 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1878 vk::CmdClearColorImage(m_commandBuffer->handle(), image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &full_subresource_range);
1879 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1880 vk::CmdClearColorImage(m_commandBuffer->handle(), image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &full_subresource_range);
1881 m_errorMonitor->VerifyFound();
1882
1883 m_commandBuffer->end();
1884
1885 // CmdClearDepthStencilImage
1886 format = FindSupportedDepthStencilFormat(gpu());
1887 if (!format) {
1888 printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix);
1889 return;
1890 }
1891 m_errorMonitor->ExpectSuccess();
1892 VkImageObj image_ds_a(m_device), image_ds_b(m_device);
1893 image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 1, format, usage, VK_IMAGE_TILING_OPTIMAL);
1894 image_ds_a.Init(image_ci);
1895 image_ds_b.Init(image_ci);
1896
1897 const VkImageAspectFlags ds_aspect = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
1898 image_ds_a.SetLayout(ds_aspect, VK_IMAGE_LAYOUT_GENERAL);
1899 image_ds_b.SetLayout(ds_aspect, VK_IMAGE_LAYOUT_GENERAL);
1900
1901 m_commandBuffer->begin();
1902 const VkClearDepthStencilValue clear_value = {};
1903 VkImageSubresourceRange ds_range = {ds_aspect, 0, 1, 0, 1};
1904
1905 vk::CmdClearDepthStencilImage(cb, image_ds_a.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1, &ds_range);
1906 m_commandBuffer->end();
1907 m_errorMonitor->VerifyNotFound();
1908
1909 VkImageSubresourceLayers ds_layers_all{ds_aspect, 0, 0, 1};
1910 VkImageCopy ds_full_region = {ds_layers_all, zero_offset, ds_layers_all, zero_offset, full_extent};
1911
1912 m_commandBuffer->reset();
1913 m_commandBuffer->begin();
1914 vk::CmdCopyImage(cb, image_ds_a.handle(), VK_IMAGE_LAYOUT_GENERAL, image_ds_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1915 &ds_full_region);
1916
1917 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1918 vk::CmdClearDepthStencilImage(m_commandBuffer->handle(), image_ds_a.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1,
1919 &ds_range);
1920 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1921 vk::CmdClearDepthStencilImage(m_commandBuffer->handle(), image_ds_b.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1,
1922 &ds_range);
1923 m_errorMonitor->VerifyFound();
1924
1925 m_commandBuffer->end();
1926}
1927
1928TEST_F(VkSyncValTest, SyncCmdQuery) {
1929 // CmdCopyQueryPoolResults
1930 m_errorMonitor->ExpectSuccess();
1931 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
1932 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
1933 if (IsPlatform(kNexusPlayer)) {
1934 printf("%s This test should not run on Nexus Player\n", kSkipPrefix);
1935 return;
1936 }
1937 if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) {
1938 printf("%s Queue family needs to have multiple queues to run this test.\n", kSkipPrefix);
1939 return;
1940 }
1941 uint32_t queue_count;
1942 vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_count, NULL);
Jeremy Gebbend2573fc2021-05-12 17:17:38 -06001943 std::vector<VkQueueFamilyProperties> queue_props(queue_count);
1944 vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_count, queue_props.data());
Jeremy Gebben170781d2020-11-19 16:21:21 -07001945 if (queue_props[m_device->graphics_queue_node_index_].timestampValidBits == 0) {
1946 printf("%s Device graphic queue has timestampValidBits of 0, skipping.\n", kSkipPrefix);
1947 return;
1948 }
1949
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001950 vk_testing::QueryPool query_pool;
sfricke-samsung6fc3e322022-02-15 22:41:29 -08001951 VkQueryPoolCreateInfo query_pool_create_info = LvlInitStruct<VkQueryPoolCreateInfo>();
Jeremy Gebben170781d2020-11-19 16:21:21 -07001952 query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
1953 query_pool_create_info.queryCount = 1;
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001954 query_pool.init(*m_device, query_pool_create_info);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001955
1956 VkBufferObj buffer_a, buffer_b;
1957 VkMemoryPropertyFlags mem_prop = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
1958 buffer_a.init_as_src_and_dst(*m_device, 256, mem_prop);
1959 buffer_b.init_as_src_and_dst(*m_device, 256, mem_prop);
1960
1961 VkBufferCopy region = {0, 0, 256};
1962
1963 auto cb = m_commandBuffer->handle();
1964 m_commandBuffer->begin();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001965 vk::CmdResetQueryPool(cb, query_pool.handle(), 0, 1);
1966 vk::CmdWriteTimestamp(cb, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool.handle(), 0);
1967 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 -07001968 m_commandBuffer->end();
1969 m_errorMonitor->VerifyNotFound();
1970
1971 m_commandBuffer->reset();
1972 m_commandBuffer->begin();
1973 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &region);
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001974 vk::CmdResetQueryPool(cb, query_pool.handle(), 0, 1);
1975 vk::CmdWriteTimestamp(cb, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool.handle(), 0);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001976 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001977 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 -07001978 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001979 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 -07001980 m_commandBuffer->end();
1981 m_errorMonitor->VerifyFound();
1982
1983 // TODO:Track VkQueryPool
1984 // TODO:CmdWriteTimestamp
Jeremy Gebben170781d2020-11-19 16:21:21 -07001985}
1986
1987TEST_F(VkSyncValTest, SyncCmdDrawDepthStencil) {
1988 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
1989 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
Jeremy Gebben170781d2020-11-19 16:21:21 -07001990
1991 const auto format_ds = FindSupportedDepthStencilFormat(gpu());
1992 if (!format_ds) {
Nathaniel Cesario0d50bcf2022-06-21 10:30:04 -06001993 GTEST_SKIP() << "No Depth + Stencil format found. Skipped.";
Jeremy Gebben170781d2020-11-19 16:21:21 -07001994 }
1995 const auto format_dp = FindSupportedDepthOnlyFormat(gpu());
1996 if (!format_dp) {
Nathaniel Cesario0d50bcf2022-06-21 10:30:04 -06001997 GTEST_SKIP() << "No only Depth format found. Skipped.";
Jeremy Gebben170781d2020-11-19 16:21:21 -07001998 }
1999 const auto format_st = FindSupportedStencilOnlyFormat(gpu());
2000 if (!format_st) {
Nathaniel Cesario0d50bcf2022-06-21 10:30:04 -06002001 GTEST_SKIP() << "No only Stencil format found. Skipped.";
Jeremy Gebben170781d2020-11-19 16:21:21 -07002002 }
2003
2004 VkDepthStencilObj image_ds(m_device), image_dp(m_device), image_st(m_device);
2005 image_ds.Init(m_device, 16, 16, format_ds);
2006 image_dp.Init(m_device, 16, 16, format_dp);
2007 image_st.Init(m_device, 16, 16, format_st);
2008
2009 VkRenderpassObj rp_ds(m_device, format_ds, true), rp_dp(m_device, format_dp, true), rp_st(m_device, format_st, true);
2010
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002011 vk_testing::Framebuffer fb_ds, fb_dp, fb_st;
Jeremy Gebben170781d2020-11-19 16:21:21 -07002012 VkFramebufferCreateInfo fbci = {
2013 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 -06002014 fb_ds.init(*m_device, fbci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002015 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 -06002016 fb_dp.init(*m_device, fbci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002017 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 -06002018 fb_st.init(*m_device, fbci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002019
2020 VkStencilOpState stencil = {};
2021 stencil.failOp = VK_STENCIL_OP_KEEP;
2022 stencil.passOp = VK_STENCIL_OP_KEEP;
2023 stencil.depthFailOp = VK_STENCIL_OP_KEEP;
2024 stencil.compareOp = VK_COMPARE_OP_NEVER;
2025
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07002026 auto ds_ci = LvlInitStruct<VkPipelineDepthStencilStateCreateInfo>();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002027 ds_ci.depthTestEnable = VK_TRUE;
2028 ds_ci.depthWriteEnable = VK_TRUE;
2029 ds_ci.depthCompareOp = VK_COMPARE_OP_NEVER;
2030 ds_ci.stencilTestEnable = VK_TRUE;
2031 ds_ci.front = stencil;
2032 ds_ci.back = stencil;
2033
2034 CreatePipelineHelper g_pipe_ds(*this), g_pipe_dp(*this), g_pipe_st(*this);
2035 g_pipe_ds.InitInfo();
2036 g_pipe_ds.gp_ci_.renderPass = rp_ds.handle();
2037 g_pipe_ds.gp_ci_.pDepthStencilState = &ds_ci;
2038 g_pipe_ds.InitState();
2039 ASSERT_VK_SUCCESS(g_pipe_ds.CreateGraphicsPipeline());
2040 g_pipe_dp.InitInfo();
2041 g_pipe_dp.gp_ci_.renderPass = rp_dp.handle();
2042 ds_ci.stencilTestEnable = VK_FALSE;
2043 g_pipe_dp.gp_ci_.pDepthStencilState = &ds_ci;
2044 g_pipe_dp.InitState();
2045 ASSERT_VK_SUCCESS(g_pipe_dp.CreateGraphicsPipeline());
2046 g_pipe_st.InitInfo();
2047 g_pipe_st.gp_ci_.renderPass = rp_st.handle();
2048 ds_ci.depthTestEnable = VK_FALSE;
2049 ds_ci.stencilTestEnable = VK_TRUE;
2050 g_pipe_st.gp_ci_.pDepthStencilState = &ds_ci;
2051 g_pipe_st.InitState();
2052 ASSERT_VK_SUCCESS(g_pipe_st.CreateGraphicsPipeline());
2053
2054 m_commandBuffer->begin();
2055 m_renderPassBeginInfo.renderArea = {{0, 0}, {16, 16}};
2056 m_renderPassBeginInfo.pClearValues = nullptr;
2057 m_renderPassBeginInfo.clearValueCount = 0;
2058
2059 m_renderPassBeginInfo.renderPass = rp_ds.handle();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002060 m_renderPassBeginInfo.framebuffer = fb_ds.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002061 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2062 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_ds.pipeline_);
2063 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
2064 m_commandBuffer->EndRenderPass();
2065
2066 m_renderPassBeginInfo.renderPass = rp_dp.handle();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002067 m_renderPassBeginInfo.framebuffer = fb_dp.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002068 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2069 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_dp.pipeline_);
2070 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
2071 m_commandBuffer->EndRenderPass();
2072
2073 m_renderPassBeginInfo.renderPass = rp_st.handle();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002074 m_renderPassBeginInfo.framebuffer = fb_st.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002075 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2076 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_st.pipeline_);
2077 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
2078 m_commandBuffer->EndRenderPass();
2079
2080 m_commandBuffer->end();
2081 m_errorMonitor->VerifyNotFound();
2082
2083 m_commandBuffer->reset();
2084 m_commandBuffer->begin();
2085
2086 VkImageCopy copyRegion;
2087 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
2088 copyRegion.srcSubresource.mipLevel = 0;
2089 copyRegion.srcSubresource.baseArrayLayer = 0;
2090 copyRegion.srcSubresource.layerCount = 1;
2091 copyRegion.srcOffset = {0, 0, 0};
2092 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
2093 copyRegion.dstSubresource.mipLevel = 0;
2094 copyRegion.dstSubresource.baseArrayLayer = 0;
2095 copyRegion.dstSubresource.layerCount = 1;
2096 copyRegion.dstOffset = {0, 0, 0};
2097 copyRegion.extent = {16, 16, 1};
2098
2099 m_commandBuffer->CopyImage(image_ds.handle(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, image_dp.handle(),
2100 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 1, &copyRegion);
2101
2102 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
2103 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
2104 m_commandBuffer->CopyImage(image_ds.handle(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, image_st.handle(),
2105 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 1, &copyRegion);
2106 m_renderPassBeginInfo.renderPass = rp_ds.handle();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002107 m_renderPassBeginInfo.framebuffer = fb_ds.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002108 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
2109 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2110 m_errorMonitor->VerifyFound();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002111
2112 m_renderPassBeginInfo.renderPass = rp_dp.handle();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002113 m_renderPassBeginInfo.framebuffer = fb_dp.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002114 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
2115 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2116 m_errorMonitor->VerifyFound();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002117
2118 m_renderPassBeginInfo.renderPass = rp_st.handle();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002119 m_renderPassBeginInfo.framebuffer = fb_st.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002120 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
2121 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2122 m_errorMonitor->VerifyFound();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002123}
2124
John Zulaufd57a36b2021-08-16 10:34:44 -06002125
Jeremy Gebben170781d2020-11-19 16:21:21 -07002126TEST_F(VkSyncValTest, RenderPassLoadHazardVsInitialLayout) {
2127 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
John Zulaufd57a36b2021-08-16 10:34:44 -06002128 bool do_none_load_op_test = false;
2129 if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_LOAD_STORE_OP_NONE_EXTENSION_NAME)) {
2130 m_device_extension_names.push_back(VK_EXT_LOAD_STORE_OP_NONE_EXTENSION_NAME);
2131 do_none_load_op_test = true;
2132 }
2133
Jeremy Gebben170781d2020-11-19 16:21:21 -07002134 ASSERT_NO_FATAL_FAILURE(InitState());
2135 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2136
2137 VkImageUsageFlags usage_color = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
2138 VkImageUsageFlags usage_input = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
2139 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
2140 VkImageObj image_color(m_device), image_input(m_device);
2141 auto image_ci = VkImageObj::ImageCreateInfo2D(32, 32, 1, 1, format, usage_color, VK_IMAGE_TILING_OPTIMAL);
2142 image_color.Init(image_ci);
2143 image_ci.usage = usage_input;
2144 image_input.Init(image_ci);
2145 VkImageView attachments[] = {image_color.targetView(format), image_input.targetView(format)};
2146
John Zulaufd57a36b2021-08-16 10:34:44 -06002147 VkAttachmentDescription attachmentDescriptions[] = {
Jeremy Gebben170781d2020-11-19 16:21:21 -07002148 // Result attachment
2149 {(VkAttachmentDescriptionFlags)0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR,
2150 VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
2151 VK_IMAGE_LAYOUT_UNDEFINED, // Here causes DesiredError that SYNC-HAZARD-NONE in BeginRenderPass.
2152 // It should be VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
2153 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
2154 // Input attachment
2155 {(VkAttachmentDescriptionFlags)0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD,
2156 VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
2157 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL}};
2158
2159 const VkAttachmentReference resultAttachmentRef = {0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
2160 const VkAttachmentReference inputAttachmentRef = {1u, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};
2161
2162 const VkSubpassDescription subpassDescription = {(VkSubpassDescriptionFlags)0,
2163 VK_PIPELINE_BIND_POINT_GRAPHICS,
2164 1u,
2165 &inputAttachmentRef,
2166 1u,
2167 &resultAttachmentRef,
2168 0,
2169 0,
2170 0u,
2171 0};
2172
2173 const VkSubpassDependency subpassDependency = {VK_SUBPASS_EXTERNAL,
2174 0,
2175 VK_PIPELINE_STAGE_TRANSFER_BIT,
2176 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
2177 VK_ACCESS_TRANSFER_WRITE_BIT,
2178 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | VK_ACCESS_SHADER_READ_BIT,
2179 VK_DEPENDENCY_BY_REGION_BIT};
2180
2181 const VkRenderPassCreateInfo renderPassInfo = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
2182 0,
2183 (VkRenderPassCreateFlags)0,
2184 2u,
2185 attachmentDescriptions,
2186 1u,
2187 &subpassDescription,
2188 1u,
2189 &subpassDependency};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002190 vk_testing::RenderPass rp;
2191 rp.init(*m_device, renderPassInfo);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002192
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002193 vk_testing::Framebuffer fb;
2194 VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp.handle(), 2, attachments, 32, 32, 1};
2195 fb.init(*m_device, fbci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002196
2197 image_input.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
2198
2199 m_commandBuffer->begin();
2200
2201 m_renderPassBeginInfo.renderArea = {{0, 0}, {32, 32}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002202 m_renderPassBeginInfo.renderPass = rp.handle();
2203 m_renderPassBeginInfo.framebuffer = fb.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002204
2205 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
2206 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
2207 // Even though we have no accesses prior, the layout transition *is* an access, so load can be validated vs. layout transition
2208 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2209 m_errorMonitor->VerifyFound();
John Zulaufd57a36b2021-08-16 10:34:44 -06002210
2211 vk_testing::RenderPass rp_no_load_store;
2212 if (do_none_load_op_test) {
2213 m_errorMonitor->ExpectSuccess();
2214 attachmentDescriptions[0].loadOp = VK_ATTACHMENT_LOAD_OP_NONE_EXT;
2215 attachmentDescriptions[0].storeOp = VK_ATTACHMENT_STORE_OP_NONE_EXT;
2216 attachmentDescriptions[1].loadOp = VK_ATTACHMENT_LOAD_OP_NONE_EXT;
2217 attachmentDescriptions[1].storeOp = VK_ATTACHMENT_STORE_OP_NONE_EXT;
2218 rp_no_load_store.init(*m_device, renderPassInfo);
2219 m_renderPassBeginInfo.renderPass = rp_no_load_store.handle();
2220 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2221 m_commandBuffer->EndRenderPass();
2222 m_errorMonitor->VerifyNotFound();
2223 } else {
2224 printf("%s VK_EXT_load_store_op_none not supported, skipping sub-test\n", kSkipPrefix);
2225 }
Jeremy Gebben170781d2020-11-19 16:21:21 -07002226}
2227
2228TEST_F(VkSyncValTest, SyncRenderPassWithWrongDepthStencilInitialLayout) {
2229 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
2230 ASSERT_NO_FATAL_FAILURE(InitState());
2231 if (IsPlatform(kNexusPlayer)) {
2232 printf("%s This test should not run on Nexus Player\n", kSkipPrefix);
2233 return;
2234 }
2235
2236 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2237
2238 VkFormat color_format = VK_FORMAT_R8G8B8A8_UNORM;
2239 VkFormat ds_format = FindSupportedDepthStencilFormat(gpu());
2240 if (!ds_format) {
2241 printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix);
2242 return;
2243 }
2244 VkImageUsageFlags usage_color = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
2245 VkImageUsageFlags usage_ds = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
2246 VkImageObj image_color(m_device), image_color2(m_device);
2247 auto image_ci = VkImageObj::ImageCreateInfo2D(32, 32, 1, 1, color_format, usage_color, VK_IMAGE_TILING_OPTIMAL);
2248 image_color.Init(image_ci);
2249 image_color2.Init(image_ci);
2250 VkDepthStencilObj image_ds(m_device);
2251 image_ds.Init(m_device, 32, 32, ds_format, usage_ds);
2252
2253 const VkAttachmentDescription colorAttachmentDescription = {(VkAttachmentDescriptionFlags)0,
2254 color_format,
2255 VK_SAMPLE_COUNT_1_BIT,
2256 VK_ATTACHMENT_LOAD_OP_CLEAR,
2257 VK_ATTACHMENT_STORE_OP_STORE,
2258 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2259 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2260 VK_IMAGE_LAYOUT_UNDEFINED,
2261 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
2262
2263 const VkAttachmentDescription depthStencilAttachmentDescription = {
2264 (VkAttachmentDescriptionFlags)0, ds_format, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR,
2265 VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE,
2266 VK_IMAGE_LAYOUT_UNDEFINED, // Here causes DesiredError that SYNC-HAZARD-WRITE_AFTER_WRITE in BeginRenderPass.
2267 // It should be VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
2268 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
2269
2270 std::vector<VkAttachmentDescription> attachmentDescriptions;
2271 attachmentDescriptions.push_back(colorAttachmentDescription);
2272 attachmentDescriptions.push_back(depthStencilAttachmentDescription);
2273
2274 const VkAttachmentReference colorAttachmentRef = {0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
2275
2276 const VkAttachmentReference depthStencilAttachmentRef = {1u, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
2277
2278 const VkSubpassDescription subpassDescription = {(VkSubpassDescriptionFlags)0,
2279 VK_PIPELINE_BIND_POINT_GRAPHICS,
2280 0u,
2281 0,
2282 1u,
2283 &colorAttachmentRef,
2284 0,
2285 &depthStencilAttachmentRef,
2286 0u,
2287 0};
2288
2289 const VkRenderPassCreateInfo renderPassInfo = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
2290 0,
2291 (VkRenderPassCreateFlags)0,
2292 (uint32_t)attachmentDescriptions.size(),
2293 &attachmentDescriptions[0],
2294 1u,
2295 &subpassDescription,
2296 0u,
2297 0};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002298 vk_testing::RenderPass rp;
2299 rp.init(*m_device, renderPassInfo);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002300
2301 VkImageView fb_attachments[] = {image_color.targetView(color_format),
2302 image_ds.targetView(ds_format, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)};
2303 const VkFramebufferCreateInfo fbci = {
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002304 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, 0, 0u, rp.handle(), 2u, fb_attachments, 32, 32, 1u,
Jeremy Gebben170781d2020-11-19 16:21:21 -07002305 };
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002306 vk_testing::Framebuffer fb;
2307 fb.init(*m_device, fbci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002308 fb_attachments[0] = image_color2.targetView(color_format);
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002309 vk_testing::Framebuffer fb1;
2310 fb1.init(*m_device, fbci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002311
2312 CreatePipelineHelper g_pipe(*this);
2313 g_pipe.InitInfo();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002314 g_pipe.gp_ci_.renderPass = rp.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002315
2316 VkStencilOpState stencil = {};
2317 stencil.failOp = VK_STENCIL_OP_KEEP;
2318 stencil.passOp = VK_STENCIL_OP_KEEP;
2319 stencil.depthFailOp = VK_STENCIL_OP_KEEP;
2320 stencil.compareOp = VK_COMPARE_OP_NEVER;
2321
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07002322 auto ds_ci = LvlInitStruct<VkPipelineDepthStencilStateCreateInfo>();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002323 ds_ci.depthTestEnable = VK_TRUE;
2324 ds_ci.depthWriteEnable = VK_TRUE;
2325 ds_ci.depthCompareOp = VK_COMPARE_OP_NEVER;
2326 ds_ci.stencilTestEnable = VK_TRUE;
2327 ds_ci.front = stencil;
2328 ds_ci.back = stencil;
2329
2330 g_pipe.gp_ci_.pDepthStencilState = &ds_ci;
2331 g_pipe.InitState();
2332 ASSERT_VK_SUCCESS(g_pipe.CreateGraphicsPipeline());
2333
2334 m_commandBuffer->begin();
Tony-LunarG73f37032021-06-07 11:47:03 -06002335 VkClearValue clear = {};
2336 std::array<VkClearValue, 2> clear_values = { {clear, clear} };
2337 m_renderPassBeginInfo.pClearValues = clear_values.data();
2338 m_renderPassBeginInfo.clearValueCount = clear_values.size();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002339 m_renderPassBeginInfo.renderArea = {{0, 0}, {32, 32}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002340 m_renderPassBeginInfo.renderPass = rp.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002341
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002342 m_renderPassBeginInfo.framebuffer = fb.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002343 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2344 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
2345 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
2346 m_commandBuffer->EndRenderPass();
2347
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002348 m_renderPassBeginInfo.framebuffer = fb1.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002349
2350 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
2351 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2352 m_errorMonitor->VerifyFound();
2353}
2354
John Zulauf01a49ee2022-07-13 11:37:08 -06002355struct CreateRenderPassHelper {
2356 struct SubpassDescriptionStore {
2357 const std::vector<VkAttachmentReference>& input_store;
2358 const std::vector<VkAttachmentReference>& color_store;
2359 VkSubpassDescription desc;
2360 SubpassDescriptionStore(const std::vector<VkAttachmentReference>& input, const std::vector<VkAttachmentReference>& color)
2361 : input_store(input), color_store(color) {
2362 desc = {
2363 0u,
2364 VK_PIPELINE_BIND_POINT_GRAPHICS,
2365 static_cast<uint32_t>(input_store.size()),
2366 input_store.data(),
2367 static_cast<uint32_t>(color_store.size()),
2368 color_store.data(),
2369 nullptr,
2370 nullptr,
2371 0u,
2372 nullptr,
2373 };
2374 if (desc.inputAttachmentCount == 0) {
2375 desc.pInputAttachments = nullptr;
2376 }
2377 if (desc.colorAttachmentCount == 0) {
2378 desc.pColorAttachments = nullptr;
2379 }
2380 }
2381 };
2382
2383 VkImageUsageFlags usage_color = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
2384 VkImageUsageFlags usage_input =
2385 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
2386 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
2387 VkClearColorValue ccv = {};
2388
2389 VkDeviceObj* dev;
2390 const static uint32_t kDefaultImageSize = 64;
2391 uint32_t width = kDefaultImageSize;
2392 uint32_t height = kDefaultImageSize;
2393 std::shared_ptr<VkImageObj> image_color;
2394 std::shared_ptr<VkImageObj> image_input;
2395 VkImageView view_input = VK_NULL_HANDLE;
2396 VkImageView view_color = VK_NULL_HANDLE;
2397
2398 VkAttachmentReference color_ref;
2399 VkAttachmentReference input_ref;
2400 std::vector<VkImageView> attachments;
2401 VkAttachmentDescription fb_attach_desc;
2402 VkAttachmentDescription input_attach_desc;
2403 std::vector<VkAttachmentDescription> attachment_descs;
2404 std::vector<VkAttachmentReference> input_attachments;
2405 std::vector<VkAttachmentReference> color_attachments;
2406 std::vector<VkSubpassDependency> subpass_dep;
2407 std::vector<VkSubpassDescription> subpasses;
2408 std::vector<SubpassDescriptionStore> subpass_description_store;
2409 VkRenderPassCreateInfo render_pass_create_info;
2410 VkRenderPassCreateInfo render_pass_ci;
2411 vk_testing::RenderPass render_pass;
2412 std::shared_ptr<vk_testing::Framebuffer> framebuffer;
2413 VkRenderPassBeginInfo render_pass_begin;
2414 std::vector<VkClearValue> clear_colors;
2415
2416 CreateRenderPassHelper(VkDeviceObj* dev_)
2417 : dev(dev_),
2418 image_color(std::make_shared<VkImageObj>(dev)),
2419 image_input(std::make_shared<VkImageObj>(dev)),
2420 color_ref(DefaultColorRef()),
2421 input_ref(DefaultInputRef()),
2422 fb_attach_desc(DefaultFbAttachDesc()),
2423 input_attach_desc(DefaultInputAttachDesc()) {}
2424
2425 CreateRenderPassHelper(const CreateRenderPassHelper& other) = default;
2426
2427 void InitImageAndView() {
2428 auto image_ci = VkImageObj::ImageCreateInfo2D(width, height, 1, 1, format, usage_input, VK_IMAGE_TILING_OPTIMAL);
2429 image_input->InitNoLayout(image_ci);
2430 image_ci.usage = usage_color;
2431 image_color->InitNoLayout(image_ci);
2432
2433 view_input = image_input->targetView(format);
2434 view_color = image_color->targetView(format);
2435 attachments = {view_color, view_input};
2436 }
2437
2438 VkAttachmentReference DefaultColorRef() const {
2439 return {
2440 0u,
2441 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
2442 };
2443 }
2444
2445 VkAttachmentReference DefaultInputRef() const {
2446 return {
2447 1u,
2448 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
2449 };
2450 };
2451
2452 VkAttachmentDescription DefaultFbAttachDesc() {
2453 return VkAttachmentDescription{
2454 0u,
2455 format,
2456 VK_SAMPLE_COUNT_1_BIT,
2457 VK_ATTACHMENT_LOAD_OP_CLEAR,
2458 VK_ATTACHMENT_STORE_OP_STORE,
2459 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2460 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2461 VK_IMAGE_LAYOUT_UNDEFINED,
2462 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
2463 };
2464 }
2465 VkAttachmentDescription DefaultInputAttachDesc() const {
2466 return VkAttachmentDescription{
2467 0u,
2468 format,
2469 VK_SAMPLE_COUNT_1_BIT,
2470 VK_ATTACHMENT_LOAD_OP_LOAD,
2471 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2472 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2473 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2474 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
2475 VK_IMAGE_LAYOUT_GENERAL,
2476 };
2477 }
2478
2479 void InitAttachmentArrays() {
2480 // Add attachments
2481 if (attachment_descs.empty()) {
2482 attachment_descs = {fb_attach_desc, input_attach_desc};
2483 }
2484 if (color_attachments.empty()) {
2485 color_attachments = {color_ref};
2486 }
2487 if (input_attachments.empty()) {
2488 input_attachments = {input_ref};
2489 }
2490 }
2491
2492 // This is the default for a single subpass renderpass, don't call if you want to change that
2493 void InitSubpassDescription() {
2494 if (subpass_description_store.empty()) {
2495 subpass_description_store.emplace_back(input_attachments, color_attachments);
2496 }
2497 }
2498
2499 void InitSubpasses() {
2500 if (subpasses.empty()) {
2501 subpasses.reserve(subpass_description_store.size());
2502 for (const auto& desc_store : subpass_description_store) {
2503 subpasses.emplace_back(desc_store.desc);
2504 }
2505 }
2506 }
2507
2508 void InitRenderPassInfo() {
2509 render_pass_create_info = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
2510 nullptr,
2511 0u,
2512 static_cast<uint32_t>(attachment_descs.size()),
2513 attachment_descs.data(),
2514 static_cast<uint32_t>(subpasses.size()),
2515 subpasses.data(),
2516 static_cast<uint32_t>(subpass_dep.size()),
2517 subpass_dep.data()};
2518 }
2519
2520 void InitRenderPass() {
2521 InitAttachmentArrays();
2522 InitSubpassDescription();
2523 InitSubpasses();
2524 InitRenderPassInfo();
2525 render_pass.init(*dev, render_pass_create_info);
2526 }
2527
2528 void InitFramebuffer() {
2529 framebuffer = std::make_shared<vk_testing::Framebuffer>();
2530 VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
2531 0,
2532 0u,
2533 render_pass.handle(),
2534 static_cast<uint32_t>(attachments.size()),
2535 attachments.data(),
2536 width,
2537 height,
2538 1u};
2539 framebuffer->init(*dev, fbci);
2540 }
2541
2542 void InitState() {
2543 InitImageAndView();
2544 }
2545
2546 void InitBeginInfo() {
2547 render_pass_begin = lvl_init_struct<VkRenderPassBeginInfo>();
2548 render_pass_begin.renderArea = {{0, 0}, {width, height}};
2549 render_pass_begin.renderPass = render_pass.handle();
2550 render_pass_begin.framebuffer = framebuffer->handle();
2551
2552 // Simplistic ensure enough clear colors, if not provided
2553 // TODO: Should eventually be smart enough to fill in color/depth as appropos
2554 VkClearValue fill_in;
2555 fill_in.color = ccv;
2556 for (size_t i = clear_colors.size(); i < attachments.size(); ++i) {
2557 clear_colors.push_back(fill_in);
2558 }
2559 render_pass_begin.clearValueCount = static_cast<uint32_t>(clear_colors.size());
2560 render_pass_begin.pClearValues = clear_colors.data();
2561 }
2562
2563 void Init() {
2564 InitState();
2565 InitRenderPass();
2566 InitFramebuffer();
2567 InitBeginInfo();
2568 }
2569};
2570
2571struct SyncTestPipeline {
2572 VkLayerTest& test;
2573 VkRenderPass rp;
2574 CreatePipelineHelper g_pipe;
2575 VkShaderObj vs;
2576 VkShaderObj fs;
2577 VkSamplerCreateInfo sampler_info;
2578 vk_testing::Sampler sampler;
2579 VkImageView view_input = VK_NULL_HANDLE;
2580 SyncTestPipeline(VkLayerTest& test_, VkRenderPass rp_)
2581 : test(test_),
2582 rp(rp_),
2583 g_pipe(test),
2584 vs(&test, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT),
2585 fs(&test, bindStateFragSubpassLoadInputText, VK_SHADER_STAGE_FRAGMENT_BIT),
2586 sampler_info(SafeSaneSamplerCreateInfo()),
2587 sampler() {}
2588 void InitState() {
2589 VkSamplerCreateInfo sampler_info = SafeSaneSamplerCreateInfo();
2590 sampler.init(*test.DeviceObj(), sampler_info);
2591 g_pipe.InitInfo();
2592 g_pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
2593 g_pipe.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
2594 g_pipe.gp_ci_.renderPass = rp;
2595 g_pipe.InitState();
2596 }
2597 void Init() {
2598 ASSERT_VK_SUCCESS(g_pipe.CreateGraphicsPipeline());
2599 g_pipe.descriptor_set_->WriteDescriptorImageInfo(0, view_input, sampler.handle(), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
2600 g_pipe.descriptor_set_->UpdateDescriptorSets();
2601 }
2602};
2603
Jeremy Gebben170781d2020-11-19 16:21:21 -07002604TEST_F(VkSyncValTest, SyncLayoutTransition) {
2605 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
2606 ASSERT_NO_FATAL_FAILURE(InitState());
2607 if (IsPlatform(kNexusPlayer)) {
Nathaniel Cesario0d50bcf2022-06-21 10:30:04 -06002608 GTEST_SKIP() << "This test should not run on Nexus Player";
Jeremy Gebben170781d2020-11-19 16:21:21 -07002609 }
2610
John Zulauf01a49ee2022-07-13 11:37:08 -06002611 // ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
Jeremy Gebben170781d2020-11-19 16:21:21 -07002612
John Zulauf01a49ee2022-07-13 11:37:08 -06002613 CreateRenderPassHelper rp_helper(m_device);
2614 rp_helper.Init();
2615 const VkImage image_input_handle = rp_helper.image_input->handle();
2616 const VkRenderPass rp = rp_helper.render_pass.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002617
John Zulauf01a49ee2022-07-13 11:37:08 -06002618 SyncTestPipeline st_pipe(*this, rp);
2619 st_pipe.InitState();
2620 st_pipe.view_input = rp_helper.view_input;
2621 st_pipe.Init();
2622 const auto& g_pipe = st_pipe.g_pipe;
Jeremy Gebben170781d2020-11-19 16:21:21 -07002623
John Zulauffa44ab22022-07-14 15:12:28 -06002624 m_errorMonitor->ExpectSuccess();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002625 m_commandBuffer->begin();
2626 auto cb = m_commandBuffer->handle();
2627 VkClearColorValue ccv = {};
2628 VkImageSubresourceRange full_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
2629
2630 const VkImageMemoryBarrier preClearBarrier = {
2631 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, 0, 0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
John Zulauf01a49ee2022-07-13 11:37:08 -06002632 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, 0, image_input_handle, full_subresource_range,
Jeremy Gebben170781d2020-11-19 16:21:21 -07002633 };
2634 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u,
2635 &preClearBarrier);
2636
John Zulauf01a49ee2022-07-13 11:37:08 -06002637 vk::CmdClearColorImage(m_commandBuffer->handle(), image_input_handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &ccv, 1,
Jeremy Gebben170781d2020-11-19 16:21:21 -07002638 &full_subresource_range);
2639
2640 const VkImageMemoryBarrier postClearBarrier = {
2641 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
2642 0,
2643 VK_ACCESS_TRANSFER_WRITE_BIT,
John Zulauffa44ab22022-07-14 15:12:28 -06002644 VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
Jeremy Gebben170781d2020-11-19 16:21:21 -07002645 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
2646 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
2647 0,
2648 0,
John Zulauf01a49ee2022-07-13 11:37:08 -06002649 image_input_handle,
Jeremy Gebben170781d2020-11-19 16:21:21 -07002650 full_subresource_range,
2651 };
John Zulauffa44ab22022-07-14 15:12:28 -06002652 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT,
2653 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0u, nullptr,
2654 0u, nullptr, 1u, &postClearBarrier);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002655
John Zulauf01a49ee2022-07-13 11:37:08 -06002656 m_commandBuffer->BeginRenderPass(rp_helper.render_pass_begin);
John Zulauffa44ab22022-07-14 15:12:28 -06002657 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
2658 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
2659 &g_pipe.descriptor_set_->set_, 0, nullptr);
2660
2661 // Positive test for ordering rules between load and input attachment usage
2662 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
2663
2664 // Positive test for store ordering vs. input attachment and dependency *to* external for layout transition
2665 m_commandBuffer->EndRenderPass();
2666 m_errorMonitor->VerifyNotFound();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002667
2668 // Catch a conflict with the input attachment final layout transition
2669 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
John Zulauf01a49ee2022-07-13 11:37:08 -06002670 vk::CmdClearColorImage(m_commandBuffer->handle(), image_input_handle, VK_IMAGE_LAYOUT_GENERAL, &ccv, 1,
Jeremy Gebben170781d2020-11-19 16:21:21 -07002671 &full_subresource_range);
2672 m_errorMonitor->VerifyFound();
John Zulaufe972b752021-05-04 15:47:17 -06002673
2674 // There should be no hazard for ILT after ILT
2675 m_errorMonitor->ExpectSuccess();
2676 m_commandBuffer->end();
2677 m_commandBuffer->reset();
2678 m_commandBuffer->begin();
2679 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u,
2680 &preClearBarrier);
2681 const VkImageMemoryBarrier wawBarrier = {
2682 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
2683 0,
2684 VK_ACCESS_SHADER_READ_BIT,
2685 VK_ACCESS_SHADER_READ_BIT,
2686 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
2687 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
2688 0,
2689 0,
John Zulauf01a49ee2022-07-13 11:37:08 -06002690 image_input_handle,
John Zulaufe972b752021-05-04 15:47:17 -06002691 full_subresource_range,
2692 };
John Zulaufe972b752021-05-04 15:47:17 -06002693 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u, nullptr, 0u,
2694 nullptr, 1u, &wawBarrier);
2695 m_errorMonitor->VerifyNotFound();
2696 m_commandBuffer->end();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002697}
2698
2699TEST_F(VkSyncValTest, SyncSubpassMultiDep) {
2700 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
2701 ASSERT_NO_FATAL_FAILURE(InitState());
2702 if (IsPlatform(kNexusPlayer)) {
2703 printf("%s This test should not run on Nexus Player\n", kSkipPrefix);
2704 return;
2705 }
2706
John Zulauf01a49ee2022-07-13 11:37:08 -06002707 CreateRenderPassHelper rp_helper_positive(m_device);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002708
Jeremy Gebben170781d2020-11-19 16:21:21 -07002709 VkImageSubresourceRange full_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
2710 VkImageSubresourceLayers mip_0_layer_0{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
2711 VkOffset3D image_zero{0, 0, 0};
John Zulauf01a49ee2022-07-13 11:37:08 -06002712 VkExtent3D image_size{rp_helper_positive.width, rp_helper_positive.height, 1};
2713
Jeremy Gebben170781d2020-11-19 16:21:21 -07002714 VkImageCopy full_region{mip_0_layer_0, image_zero, mip_0_layer_0, image_zero, image_size};
2715
John Zulauf01a49ee2022-07-13 11:37:08 -06002716 rp_helper_positive.InitState();
2717 rp_helper_positive.fb_attach_desc.initialLayout = VK_IMAGE_LAYOUT_GENERAL;
2718 rp_helper_positive.fb_attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL;
2719 rp_helper_positive.color_ref.layout = VK_IMAGE_LAYOUT_GENERAL;
2720 rp_helper_positive.input_attach_desc.initialLayout = VK_IMAGE_LAYOUT_GENERAL;
2721 rp_helper_positive.input_attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL;
2722 rp_helper_positive.input_ref.layout = VK_IMAGE_LAYOUT_GENERAL;
Jeremy Gebben170781d2020-11-19 16:21:21 -07002723
John Zulauf01a49ee2022-07-13 11:37:08 -06002724 // Copy the comon state to the other renderpass helper
2725 CreateRenderPassHelper rp_helper_negative(m_device);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002726
John Zulauf01a49ee2022-07-13 11:37:08 -06002727 auto& subpass_dep_positive = rp_helper_positive.subpass_dep;
Jeremy Gebben170781d2020-11-19 16:21:21 -07002728
John Zulauf01a49ee2022-07-13 11:37:08 -06002729 subpass_dep_positive.push_back({VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_TRANSFER_BIT,
2730 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2731 VK_DEPENDENCY_VIEW_LOCAL_BIT});
2732 subpass_dep_positive.push_back({VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_TRANSFER_BIT,
2733 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_TRANSFER_WRITE_BIT,
2734 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, VK_DEPENDENCY_VIEW_LOCAL_BIT});
2735 subpass_dep_positive.push_back({0, VK_SUBPASS_EXTERNAL, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2736 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2737 VK_ACCESS_TRANSFER_READ_BIT, VK_DEPENDENCY_VIEW_LOCAL_BIT});
2738 subpass_dep_positive.push_back({0, VK_SUBPASS_EXTERNAL, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2739 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2740 VK_ACCESS_TRANSFER_WRITE_BIT, VK_DEPENDENCY_VIEW_LOCAL_BIT});
Jeremy Gebben170781d2020-11-19 16:21:21 -07002741
John Zulauf01a49ee2022-07-13 11:37:08 -06002742 rp_helper_positive.InitRenderPass();
2743 rp_helper_positive.InitFramebuffer();
2744 rp_helper_positive.InitBeginInfo();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002745
John Zulauf01a49ee2022-07-13 11:37:08 -06002746 auto& subpass_dep_negative = rp_helper_negative.subpass_dep;
Jeremy Gebben170781d2020-11-19 16:21:21 -07002747 subpass_dep_negative.push_back({VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_TRANSFER_BIT,
2748 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2749 VK_DEPENDENCY_VIEW_LOCAL_BIT});
2750 // Show that the two barriers do *not* chain by breaking the positive barrier into two bits.
2751 subpass_dep_negative.push_back({VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_TRANSFER_BIT,
2752 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, 0,
2753 VK_DEPENDENCY_VIEW_LOCAL_BIT});
2754 subpass_dep_negative.push_back({VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2755 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
2756 VK_DEPENDENCY_VIEW_LOCAL_BIT});
John Zulauf01a49ee2022-07-13 11:37:08 -06002757 rp_helper_negative.InitRenderPass();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002758
John Zulauf01a49ee2022-07-13 11:37:08 -06002759 // Negative and postive RP's are compatible.
2760 rp_helper_negative.framebuffer = rp_helper_positive.framebuffer;
2761 rp_helper_negative.InitBeginInfo();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002762
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002763 vk_testing::Sampler sampler;
Jeremy Gebben170781d2020-11-19 16:21:21 -07002764 VkSamplerCreateInfo sampler_info = SafeSaneSamplerCreateInfo();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002765 sampler.init(*m_device, sampler_info);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002766
Jeremy Gebben170781d2020-11-19 16:21:21 -07002767
2768 CreatePipelineHelper g_pipe(*this);
2769 g_pipe.InitInfo();
John Zulauf01a49ee2022-07-13 11:37:08 -06002770 g_pipe.ResetShaderInfo(bindStateVertShaderText, bindStateFragSubpassLoadInputText);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002771 g_pipe.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
John Zulauf01a49ee2022-07-13 11:37:08 -06002772 g_pipe.gp_ci_.renderPass = rp_helper_positive.render_pass.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002773 g_pipe.InitState();
2774 ASSERT_VK_SUCCESS(g_pipe.CreateGraphicsPipeline());
2775
John Zulauf01a49ee2022-07-13 11:37:08 -06002776 g_pipe.descriptor_set_->WriteDescriptorImageInfo(0, rp_helper_positive.view_input, sampler.handle(),
2777 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002778 g_pipe.descriptor_set_->UpdateDescriptorSets();
2779
2780 m_commandBuffer->begin();
2781 auto cb = m_commandBuffer->handle();
2782 VkClearColorValue ccv = {};
2783
2784 const VkImageMemoryBarrier xferDestBarrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
2785 nullptr,
2786 VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT,
2787 VK_ACCESS_TRANSFER_WRITE_BIT,
2788 VK_IMAGE_LAYOUT_GENERAL,
2789 VK_IMAGE_LAYOUT_GENERAL,
2790 VK_QUEUE_FAMILY_IGNORED,
2791 VK_QUEUE_FAMILY_IGNORED,
2792 VK_NULL_HANDLE,
2793 full_subresource_range};
2794 const VkImageMemoryBarrier xferDestToSrcBarrier = {
2795 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
2796 nullptr,
2797 VK_ACCESS_TRANSFER_WRITE_BIT,
2798 VK_ACCESS_TRANSFER_READ_BIT,
2799 VK_IMAGE_LAYOUT_GENERAL,
2800 VK_IMAGE_LAYOUT_GENERAL,
2801 VK_QUEUE_FAMILY_IGNORED,
2802 VK_QUEUE_FAMILY_IGNORED,
2803 VK_NULL_HANDLE,
2804 full_subresource_range,
2805 };
2806
John Zulauf01a49ee2022-07-13 11:37:08 -06002807 const VkImage image_color = rp_helper_positive.image_color->handle();
2808 const VkImage image_input = rp_helper_positive.image_input->handle();
2809
Jeremy Gebben170781d2020-11-19 16:21:21 -07002810 VkImageMemoryBarrier preClearBarrier = xferDestBarrier;
John Zulauf01a49ee2022-07-13 11:37:08 -06002811 preClearBarrier.image = image_color;
Jeremy Gebben170781d2020-11-19 16:21:21 -07002812
2813 VkImageMemoryBarrier preCopyBarriers[2] = {xferDestToSrcBarrier, xferDestBarrier};
John Zulauf01a49ee2022-07-13 11:37:08 -06002814 preCopyBarriers[0].image = image_color;
2815 preCopyBarriers[1].image = image_input;
Jeremy Gebben170781d2020-11-19 16:21:21 -07002816 // Positive test for ordering rules between load and input attachment usage
2817 m_errorMonitor->ExpectSuccess();
2818
2819 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u,
2820 &preClearBarrier);
2821
John Zulauf01a49ee2022-07-13 11:37:08 -06002822 vk::CmdClearColorImage(m_commandBuffer->handle(), image_color, VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &full_subresource_range);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002823
2824 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 2u,
2825 preCopyBarriers);
2826
John Zulauf01a49ee2022-07-13 11:37:08 -06002827 vk::CmdCopyImage(m_commandBuffer->handle(), image_color, VK_IMAGE_LAYOUT_GENERAL, image_input, VK_IMAGE_LAYOUT_GENERAL, 1u,
2828 &full_region);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002829
2830 // No post copy image barrier, we are testing the subpass dependencies
2831
Jeremy Gebben170781d2020-11-19 16:21:21 -07002832 // Postive renderpass multidependency test
John Zulauf01a49ee2022-07-13 11:37:08 -06002833 m_commandBuffer->BeginRenderPass(rp_helper_positive.render_pass_begin);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002834 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
2835 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
2836 &g_pipe.descriptor_set_->set_, 0, nullptr);
2837
2838 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
2839
2840 // Positive test for store ordering vs. input attachment and dependency *to* external for layout transition
2841 m_commandBuffer->EndRenderPass();
2842 // m_errorMonitor->VerifyNotFound();
2843
John Zulauf01a49ee2022-07-13 11:37:08 -06002844 vk::CmdCopyImage(m_commandBuffer->handle(), image_color, VK_IMAGE_LAYOUT_GENERAL, image_input,
Jeremy Gebben170781d2020-11-19 16:21:21 -07002845 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &full_region);
2846 m_errorMonitor->VerifyNotFound();
2847
Jeremy Gebben170781d2020-11-19 16:21:21 -07002848 // Postive renderpass multidependency test, will fail IFF the dependencies are acting indepently.
2849 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "SYNC-HAZARD-READ_AFTER_WRITE");
John Zulauf01a49ee2022-07-13 11:37:08 -06002850 m_commandBuffer->BeginRenderPass(rp_helper_negative.render_pass_begin);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002851 m_errorMonitor->VerifyFound();
2852}
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002853
2854TEST_F(VkSyncValTest, RenderPassAsyncHazard) {
2855 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
2856 ASSERT_NO_FATAL_FAILURE(InitState());
2857
Nathaniel Cesariof9cd1a82021-07-24 08:48:55 -06002858 if (IsPlatform(kPixel3) || IsPlatform(kPixel3aXL)) {
Nathaniel Cesario0d50bcf2022-06-21 10:30:04 -06002859 GTEST_SKIP() << "Temporarily disabling on Pixel 3 and Pixel 3a XL due to driver crash";
Nathaniel Cesariof9cd1a82021-07-24 08:48:55 -06002860 }
2861
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002862 // overall set up:
2863 // subpass 0:
2864 // write image 0
2865 // subpass 1:
2866 // read image 0
2867 // write image 1
2868 // subpass 2:
2869 // read image 0
2870 // write image 2
2871 // subpass 3:
2872 // read image 0
2873 // write image 3
2874 //
2875 // subpasses 1 & 2 can run in parallel but both should depend on 0
2876 // subpass 3 must run after 1 & 2 because otherwise the store operation will
2877 // race with the reads in the other subpasses.
2878
2879 constexpr VkFormat kFormat = VK_FORMAT_R8G8B8A8_UNORM;
2880 constexpr uint32_t kWidth = 32, kHeight = 32;
2881 constexpr uint32_t kNumImages = 4;
2882
sfricke-samsung6fc3e322022-02-15 22:41:29 -08002883 VkImageCreateInfo src_img_info = LvlInitStruct<VkImageCreateInfo>();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002884 src_img_info.flags = 0;
2885 src_img_info.imageType = VK_IMAGE_TYPE_2D;
2886 src_img_info.format = kFormat;
2887 src_img_info.extent = {kWidth, kHeight, 1};
2888 src_img_info.mipLevels = 1;
2889 src_img_info.arrayLayers = 1;
2890 src_img_info.samples = VK_SAMPLE_COUNT_2_BIT;
2891 src_img_info.tiling = VK_IMAGE_TILING_OPTIMAL;
2892 src_img_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
2893 src_img_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2894 src_img_info.queueFamilyIndexCount = 0;
2895 src_img_info.pQueueFamilyIndices = nullptr;
2896 src_img_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2897
sfricke-samsung6fc3e322022-02-15 22:41:29 -08002898 VkImageCreateInfo dst_img_info = LvlInitStruct<VkImageCreateInfo>();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002899 dst_img_info.flags = 0;
2900 dst_img_info.imageType = VK_IMAGE_TYPE_2D;
2901 dst_img_info.format = kFormat;
2902 dst_img_info.extent = {kWidth, kHeight, 1};
2903 dst_img_info.mipLevels = 1;
2904 dst_img_info.arrayLayers = 1;
2905 dst_img_info.samples = VK_SAMPLE_COUNT_1_BIT;
2906 dst_img_info.tiling = VK_IMAGE_TILING_OPTIMAL;
2907 dst_img_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
2908 dst_img_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2909 dst_img_info.queueFamilyIndexCount = 0;
2910 dst_img_info.pQueueFamilyIndices = nullptr;
2911 dst_img_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2912
2913 std::vector<std::unique_ptr<VkImageObj>> images;
2914 for (uint32_t i = 0; i < kNumImages; i++) {
2915 images.emplace_back(new VkImageObj(m_device));
2916 }
2917 images[0]->Init(src_img_info);
2918 for (uint32_t i = 1; i < images.size(); i++) {
2919 images[i]->Init(dst_img_info);
2920 }
2921
2922 std::array<VkImageView, kNumImages> attachments{};
2923 std::array<VkAttachmentDescription, kNumImages> attachment_descriptions{};
2924 std::array<VkAttachmentReference, kNumImages> color_refs{};
2925 std::array<VkImageMemoryBarrier, kNumImages> img_barriers{};
2926
2927 for (uint32_t i = 0; i < attachments.size(); i++) {
2928 attachments[i] = images[i]->targetView(kFormat);
2929 attachment_descriptions[i] = {};
2930 attachment_descriptions[i].flags = 0;
2931 attachment_descriptions[i].format = kFormat;
2932 attachment_descriptions[i].samples = VK_SAMPLE_COUNT_1_BIT;
2933 attachment_descriptions[i].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
2934 attachment_descriptions[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
2935 attachment_descriptions[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
2936 attachment_descriptions[i].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
2937 attachment_descriptions[i].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
2938 attachment_descriptions[i].finalLayout =
2939 (i == 0) ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
2940
2941 color_refs[i] = {i, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
2942
sfricke-samsung6fc3e322022-02-15 22:41:29 -08002943 img_barriers[i] = LvlInitStruct<VkImageMemoryBarrier>();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002944 img_barriers[i].srcAccessMask = 0;
2945 img_barriers[i].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
2946 img_barriers[i].oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2947 img_barriers[i].newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
2948 img_barriers[i].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
2949 img_barriers[i].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
2950 img_barriers[i].image = images[i]->handle();
2951 img_barriers[i].subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS};
2952 }
2953
2954 const VkAttachmentReference input_ref{0u, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};
2955
2956 std::array<std::array<uint32_t, 2>, kNumImages - 1> preserve_subpass{{{2, 3}, {1, 3}, {1, 2}}};
2957
2958 std::array<VkSubpassDescription, kNumImages> subpasses{};
2959
2960 subpasses[0].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
2961 subpasses[0].inputAttachmentCount = 0;
2962 subpasses[0].pInputAttachments = nullptr;
2963 subpasses[0].colorAttachmentCount = 1;
2964 subpasses[0].pColorAttachments = &color_refs[0];
2965
2966 for (uint32_t i = 1; i < subpasses.size(); i++) {
2967 subpasses[i].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
2968 subpasses[i].inputAttachmentCount = 1;
2969 subpasses[i].pInputAttachments = &input_ref;
2970 subpasses[i].colorAttachmentCount = 1;
2971 subpasses[i].pColorAttachments = &color_refs[1];
2972 subpasses[i].preserveAttachmentCount = preserve_subpass[i - 1].size();
2973 subpasses[i].pPreserveAttachments = preserve_subpass[i - 1].data();
2974 }
2975
sfricke-samsung6fc3e322022-02-15 22:41:29 -08002976 VkRenderPassCreateInfo renderpass_info = LvlInitStruct<VkRenderPassCreateInfo>();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002977 renderpass_info.flags = 0;
2978 renderpass_info.attachmentCount = attachment_descriptions.size();
2979 renderpass_info.pAttachments = attachment_descriptions.data();
2980 renderpass_info.subpassCount = subpasses.size();
2981 renderpass_info.pSubpasses = subpasses.data();
2982 renderpass_info.dependencyCount = 0;
2983 renderpass_info.pDependencies = nullptr;
2984
sfricke-samsung6fc3e322022-02-15 22:41:29 -08002985 VkFramebufferCreateInfo fbci = LvlInitStruct<VkFramebufferCreateInfo>();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002986 fbci.flags = 0;
2987 fbci.attachmentCount = attachments.size();
2988 fbci.pAttachments = attachments.data();
2989 fbci.width = kWidth;
2990 fbci.height = kHeight;
2991 fbci.layers = 1;
2992
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002993 vk_testing::Sampler sampler;
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002994 VkSamplerCreateInfo sampler_info = SafeSaneSamplerCreateInfo();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002995 sampler.init(*m_device, sampler_info);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002996
sfricke-samsungae54c1e2022-01-21 05:35:21 -08002997 VkShaderObj vs(this, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT);
John Zulauf01a49ee2022-07-13 11:37:08 -06002998 VkShaderObj fs(this, bindStateFragSubpassLoadInputText, VK_SHADER_STAGE_FRAGMENT_BIT);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002999
3000 VkClearValue clear = {};
3001 clear.color = m_clear_color;
Tony-LunarG73f37032021-06-07 11:47:03 -06003002 std::array<VkClearValue, 4> clear_values = {{clear, clear, clear, clear}};
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003003
3004 // run the renderpass with no dependencies
3005 {
Jeremy Gebben18ac1052021-08-12 11:07:32 -06003006 vk_testing::RenderPass rp;
3007 vk_testing::Framebuffer fb;
3008 rp.init(*m_device, renderpass_info);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003009
Jeremy Gebben18ac1052021-08-12 11:07:32 -06003010 fbci.renderPass = rp.handle();
3011 fb.init(*m_device, fbci);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003012
3013 CreatePipelineHelper g_pipe_0(*this);
3014 g_pipe_0.InitInfo();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06003015 g_pipe_0.gp_ci_.renderPass = rp.handle();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003016 g_pipe_0.InitState();
3017 ASSERT_VK_SUCCESS(g_pipe_0.CreateGraphicsPipeline());
3018
3019 CreatePipelineHelper g_pipe_12(*this);
3020 g_pipe_12.InitInfo();
3021 g_pipe_12.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
3022 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 -06003023 g_pipe_12.gp_ci_.renderPass = rp.handle();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003024 g_pipe_12.InitState();
3025 ASSERT_VK_SUCCESS(g_pipe_12.CreateGraphicsPipeline());
3026
Jeremy Gebben18ac1052021-08-12 11:07:32 -06003027 g_pipe_12.descriptor_set_->WriteDescriptorImageInfo(0, attachments[0], sampler.handle(), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003028 g_pipe_12.descriptor_set_->UpdateDescriptorSets();
3029
3030 m_commandBuffer->begin();
3031
3032 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
3033 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0, nullptr, img_barriers.size(),
3034 img_barriers.data());
3035
3036 m_renderPassBeginInfo.renderArea = {{0, 0}, {16, 16}};
3037 m_renderPassBeginInfo.pClearValues = clear_values.data();
3038 m_renderPassBeginInfo.clearValueCount = clear_values.size();
3039
3040 m_renderPassBeginInfo.renderArea = {{0, 0}, {kWidth, kHeight}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06003041 m_renderPassBeginInfo.renderPass = rp.handle();
3042 m_renderPassBeginInfo.framebuffer = fb.handle();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003043
3044 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
3045 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_);
3046 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_layout_.handle(), 0,
3047 1, &g_pipe_0.descriptor_set_->set_, 0, NULL);
3048
3049 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
3050
3051 for (uint32_t i = 1; i < subpasses.size(); i++) {
3052 vk::CmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
3053 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_12.pipeline_);
3054 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS,
3055 g_pipe_12.pipeline_layout_.handle(), 0, 1, &g_pipe_12.descriptor_set_->set_, 0, NULL);
3056
3057 // we're racing the writes from subpass 0 with our shader reads
3058 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ-RACING-WRITE");
3059 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
3060 m_errorMonitor->VerifyFound();
3061 }
3062
3063 // we should get an error from async checking in both subpasses 2 & 3
3064 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE-RACING-WRITE");
3065 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE-RACING-WRITE");
3066 vk::CmdEndRenderPass(m_commandBuffer->handle());
3067 m_errorMonitor->VerifyFound();
3068
3069 m_commandBuffer->end();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003070 }
3071
3072 // add dependencies from subpass 0 to the others, which are necessary but not sufficient
3073 std::vector<VkSubpassDependency> subpass_dependencies;
3074 for (uint32_t i = 1; i < subpasses.size(); i++) {
3075 VkSubpassDependency dep{0,
3076 i,
3077 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
3078 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
3079 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
3080 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
3081 0};
3082 subpass_dependencies.push_back(dep);
3083 }
3084 renderpass_info.dependencyCount = subpass_dependencies.size();
3085 renderpass_info.pDependencies = subpass_dependencies.data();
3086
3087 {
Jeremy Gebben18ac1052021-08-12 11:07:32 -06003088 vk_testing::RenderPass rp;
3089 vk_testing::Framebuffer fb;
3090 rp.init(*m_device, renderpass_info);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003091
Jeremy Gebben18ac1052021-08-12 11:07:32 -06003092 fbci.renderPass = rp.handle();
3093 fb.init(*m_device, fbci);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003094
3095 CreatePipelineHelper g_pipe_0(*this);
3096 g_pipe_0.InitInfo();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06003097 g_pipe_0.gp_ci_.renderPass = rp.handle();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003098 g_pipe_0.InitState();
3099 ASSERT_VK_SUCCESS(g_pipe_0.CreateGraphicsPipeline());
3100
3101 CreatePipelineHelper g_pipe_12(*this);
3102 g_pipe_12.InitInfo();
3103 g_pipe_12.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
3104 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 -06003105 g_pipe_12.gp_ci_.renderPass = rp.handle();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003106 g_pipe_12.InitState();
3107 ASSERT_VK_SUCCESS(g_pipe_12.CreateGraphicsPipeline());
3108
Jeremy Gebben18ac1052021-08-12 11:07:32 -06003109 g_pipe_12.descriptor_set_->WriteDescriptorImageInfo(0, attachments[0], sampler.handle(), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003110 g_pipe_12.descriptor_set_->UpdateDescriptorSets();
3111
3112 m_commandBuffer->begin();
3113
3114 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
3115 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0, nullptr, img_barriers.size(),
3116 img_barriers.data());
3117
3118 m_renderPassBeginInfo.renderArea = {{0, 0}, {16, 16}};
3119 m_renderPassBeginInfo.pClearValues = clear_values.data();
3120 m_renderPassBeginInfo.clearValueCount = clear_values.size();
3121
3122 m_renderPassBeginInfo.renderArea = {{0, 0}, {kWidth, kHeight}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06003123 m_renderPassBeginInfo.renderPass = rp.handle();
3124 m_renderPassBeginInfo.framebuffer = fb.handle();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003125
3126 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
3127 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_);
3128 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_layout_.handle(), 0,
3129 1, &g_pipe_0.descriptor_set_->set_, 0, NULL);
3130
3131 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
3132
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003133 for (uint32_t i = 1; i < subpasses.size(); i++) {
3134 vk::CmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
3135 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_12.pipeline_);
3136 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS,
3137 g_pipe_12.pipeline_layout_.handle(), 0, 1, &g_pipe_12.descriptor_set_->set_, 0, NULL);
3138 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
3139 }
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003140 // expect this error because 2 subpasses could try to do the store operation
3141 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE-RACING-WRITE");
3142 // ... and this one because the store could happen during a shader read from another subpass
3143 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE-RACING-READ");
3144 vk::CmdEndRenderPass(m_commandBuffer->handle());
3145 m_errorMonitor->VerifyFound();
3146
3147 m_commandBuffer->end();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003148 }
3149
3150 // try again with correct dependencies to make subpass 3 depend on 1 & 2
3151 for (uint32_t i = 1; i < (subpasses.size() - 1); i++) {
3152 VkSubpassDependency dep{i,
3153 static_cast<uint32_t>(subpasses.size() - 1),
3154 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
3155 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
3156 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
3157 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
3158 0};
3159 subpass_dependencies.push_back(dep);
3160 }
3161 renderpass_info.dependencyCount = subpass_dependencies.size();
3162 renderpass_info.pDependencies = subpass_dependencies.data();
3163 {
Jeremy Gebben18ac1052021-08-12 11:07:32 -06003164 vk_testing::RenderPass rp;
3165 vk_testing::Framebuffer fb;
3166 rp.init(*m_device, renderpass_info);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003167
Jeremy Gebben18ac1052021-08-12 11:07:32 -06003168 fbci.renderPass = rp.handle();
3169 fb.init(*m_device, fbci);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003170
3171 CreatePipelineHelper g_pipe_0(*this);
3172 g_pipe_0.InitInfo();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06003173 g_pipe_0.gp_ci_.renderPass = rp.handle();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003174 g_pipe_0.InitState();
3175 ASSERT_VK_SUCCESS(g_pipe_0.CreateGraphicsPipeline());
3176
3177 CreatePipelineHelper g_pipe_12(*this);
3178 g_pipe_12.InitInfo();
3179 g_pipe_12.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
3180 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 -06003181 g_pipe_12.gp_ci_.renderPass = rp.handle();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003182 g_pipe_12.InitState();
3183 ASSERT_VK_SUCCESS(g_pipe_12.CreateGraphicsPipeline());
3184
Jeremy Gebben18ac1052021-08-12 11:07:32 -06003185 g_pipe_12.descriptor_set_->WriteDescriptorImageInfo(0, attachments[0], sampler.handle(), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003186 g_pipe_12.descriptor_set_->UpdateDescriptorSets();
3187
3188 m_errorMonitor->ExpectSuccess();
3189 m_commandBuffer->begin();
3190 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
3191 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0, nullptr, img_barriers.size(),
3192 img_barriers.data());
3193
3194 m_renderPassBeginInfo.renderArea = {{0, 0}, {16, 16}};
3195 m_renderPassBeginInfo.pClearValues = clear_values.data();
3196 m_renderPassBeginInfo.clearValueCount = clear_values.size();
3197
3198 m_renderPassBeginInfo.renderArea = {{0, 0}, {kWidth, kHeight}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06003199 m_renderPassBeginInfo.renderPass = rp.handle();
3200 m_renderPassBeginInfo.framebuffer = fb.handle();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003201
3202 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
3203 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_);
3204 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_layout_.handle(), 0,
3205 1, &g_pipe_0.descriptor_set_->set_, 0, NULL);
3206
3207 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
3208
3209 for (uint32_t i = 1; i < subpasses.size(); i++) {
3210 vk::CmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
3211 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_12.pipeline_);
3212 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS,
3213 g_pipe_12.pipeline_layout_.handle(), 0, 1, &g_pipe_12.descriptor_set_->set_, 0, NULL);
3214 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
3215 }
3216
3217 vk::CmdEndRenderPass(m_commandBuffer->handle());
3218
3219 m_commandBuffer->end();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003220 }
3221}
John Zulauf025ee442020-12-15 11:44:19 -07003222
3223TEST_F(VkSyncValTest, SyncEventsBufferCopy) {
3224 TEST_DESCRIPTION("Check Set/Wait protection for a variety of use cases using buffer copies");
3225 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
3226 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
3227
3228 VkBufferObj buffer_a;
3229 VkBufferObj buffer_b;
3230 VkBufferObj buffer_c;
3231 VkMemoryPropertyFlags mem_prop = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
3232 buffer_a.init_as_src_and_dst(*m_device, 256, mem_prop);
3233 buffer_b.init_as_src_and_dst(*m_device, 256, mem_prop);
3234 buffer_c.init_as_src_and_dst(*m_device, 256, mem_prop);
3235
3236 VkBufferCopy region = {0, 0, 256};
3237 VkBufferCopy front2front = {0, 0, 128};
3238 VkBufferCopy front2back = {0, 128, 128};
3239 VkBufferCopy back2back = {128, 128, 128};
3240
3241 VkEventObj event;
3242 event.init(*m_device, VkEventObj::create_info(0));
3243 VkEvent event_handle = event.handle();
3244
3245 auto cb = m_commandBuffer->handle();
3246 m_commandBuffer->begin();
3247
3248 // Copy after set for WAR (note we are writing to the back half of c but only reading from the front
3249 m_errorMonitor->ExpectSuccess();
3250 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &region);
3251 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3252 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_c.handle(), 1, &back2back);
3253 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3254 nullptr, 0, nullptr);
3255 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &front2front);
3256 m_errorMonitor->VerifyNotFound();
3257 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
3258 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &front2back);
3259 m_errorMonitor->VerifyFound();
3260 m_commandBuffer->end();
3261
3262 // WAR prevented
3263 m_commandBuffer->reset();
3264 m_commandBuffer->begin();
3265 m_errorMonitor->ExpectSuccess();
3266 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &region);
3267 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3268 // Just protect against WAR, only need a sync barrier.
3269 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3270 nullptr, 0, nullptr);
3271 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &region);
3272 m_errorMonitor->VerifyNotFound();
3273
3274 // Wait shouldn't prevent this WAW though, as it's only a synchronization barrier
3275 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
3276 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_b.handle(), 1, &region);
3277 m_errorMonitor->VerifyFound();
3278 m_commandBuffer->end();
3279
3280 // Prevent WAR and WAW
3281 m_commandBuffer->reset();
3282 m_commandBuffer->begin();
3283 m_errorMonitor->ExpectSuccess();
3284 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &region);
3285 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07003286 auto mem_barrier_waw = LvlInitStruct<VkMemoryBarrier>();
John Zulauf025ee442020-12-15 11:44:19 -07003287 mem_barrier_waw.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3288 mem_barrier_waw.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3289 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 1,
3290 &mem_barrier_waw, 0, nullptr, 0, nullptr);
3291 // The WAW should be safe (on a memory barrier)
3292 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_b.handle(), 1, &region);
3293 // The WAR should also be safe (on a sync barrier)
3294 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &region);
3295 m_errorMonitor->VerifyNotFound();
3296 m_commandBuffer->end();
3297
3298 // Barrier range check for WAW
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07003299 auto buffer_barrier_front_waw = LvlInitStruct<VkBufferMemoryBarrier>();
John Zulauf025ee442020-12-15 11:44:19 -07003300 buffer_barrier_front_waw.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3301 buffer_barrier_front_waw.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3302 buffer_barrier_front_waw.buffer = buffer_b.handle();
3303 buffer_barrier_front_waw.offset = front2front.dstOffset;
3304 buffer_barrier_front_waw.size = front2front.size;
3305
3306 // Front safe, back WAW
3307 m_commandBuffer->reset();
3308 m_commandBuffer->begin();
3309 m_errorMonitor->ExpectSuccess();
3310 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &region);
3311 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3312 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 1,
3313 &buffer_barrier_front_waw, 0, nullptr);
3314 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &front2front);
3315 m_errorMonitor->VerifyNotFound();
3316 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
3317 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &back2back);
3318 m_errorMonitor->VerifyFound();
3319 m_commandBuffer->end();
3320}
3321
3322TEST_F(VkSyncValTest, SyncEventsCopyImageHazards) {
3323 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
3324 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
3325
3326 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3327 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
3328 VkImageObj image_a(m_device);
3329 auto image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 2, format, usage, VK_IMAGE_TILING_OPTIMAL);
3330 image_a.Init(image_ci);
3331 ASSERT_TRUE(image_a.initialized());
3332
3333 VkImageObj image_b(m_device);
3334 image_b.Init(image_ci);
3335 ASSERT_TRUE(image_b.initialized());
3336
3337 VkImageObj image_c(m_device);
3338 image_c.Init(image_ci);
3339 ASSERT_TRUE(image_c.initialized());
3340
3341 VkEventObj event;
3342 event.init(*m_device, VkEventObj::create_info(0));
3343 VkEvent event_handle = event.handle();
3344
3345 VkImageSubresourceLayers layers_all{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 2};
3346 VkImageSubresourceLayers layers_0{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
3347 VkImageSubresourceLayers layers_1{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1};
3348 VkImageSubresourceRange layers_0_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
3349 VkOffset3D zero_offset{0, 0, 0};
3350 VkOffset3D half_offset{64, 64, 0};
3351 VkExtent3D full_extent{128, 128, 1}; // <-- image type is 2D
3352 VkExtent3D half_extent{64, 64, 1}; // <-- image type is 2D
3353
3354 VkImageCopy full_region = {layers_all, zero_offset, layers_all, zero_offset, full_extent};
3355 VkImageCopy region_0_to_0 = {layers_0, zero_offset, layers_0, zero_offset, full_extent};
3356 VkImageCopy region_1_to_1 = {layers_1, zero_offset, layers_1, zero_offset, full_extent};
3357 VkImageCopy region_0_q0toq0 = {layers_0, zero_offset, layers_0, zero_offset, half_extent};
3358 VkImageCopy region_0_q0toq3 = {layers_0, zero_offset, layers_0, half_offset, half_extent};
3359 VkImageCopy region_0_q3toq3 = {layers_0, half_offset, layers_0, half_offset, half_extent};
3360
3361 auto cb = m_commandBuffer->handle();
3362 auto copy_general = [cb](const VkImageObj &from, const VkImageObj &to, const VkImageCopy &region) {
3363 vk::CmdCopyImage(cb, from.handle(), VK_IMAGE_LAYOUT_GENERAL, to.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
3364 };
3365
3366 auto set_layouts = [this, &image_a, &image_b, &image_c]() {
3367 image_c.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
3368 image_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
3369 image_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
3370 };
3371
John Zulaufdd462092020-12-18 12:00:35 -07003372 // Scope check. One access in, one access not
John Zulauf025ee442020-12-15 11:44:19 -07003373 m_commandBuffer->begin();
3374 set_layouts();
3375 m_errorMonitor->ExpectSuccess();
3376 copy_general(image_a, image_b, full_region);
3377 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3378 copy_general(image_a, image_c, region_0_q3toq3);
3379 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3380 nullptr, 0, nullptr);
3381 copy_general(image_c, image_a, region_0_q0toq0);
3382 m_errorMonitor->VerifyNotFound();
3383 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
3384 copy_general(image_c, image_a, region_0_q0toq3);
3385 m_errorMonitor->VerifyFound();
3386 m_commandBuffer->end();
3387
3388 // WAR prevented
3389 m_commandBuffer->reset();
3390 m_commandBuffer->begin();
3391 set_layouts();
3392 m_errorMonitor->ExpectSuccess();
3393 copy_general(image_a, image_b, full_region);
3394 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3395 // Just protect against WAR, only need a sync barrier.
3396 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3397 nullptr, 0, nullptr);
3398 copy_general(image_c, image_a, full_region);
3399 m_errorMonitor->VerifyNotFound();
3400
3401 // Wait shouldn't prevent this WAW though, as it's only a synchronization barrier
3402 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
3403 copy_general(image_c, image_b, full_region);
3404 m_errorMonitor->VerifyFound();
3405 m_commandBuffer->end();
3406
3407 // Prevent WAR and WAW
3408 m_commandBuffer->reset();
3409 m_commandBuffer->begin();
3410 m_errorMonitor->ExpectSuccess();
3411 set_layouts();
3412 copy_general(image_a, image_b, full_region);
3413 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07003414 auto mem_barrier_waw = LvlInitStruct<VkMemoryBarrier>();
John Zulauf025ee442020-12-15 11:44:19 -07003415 mem_barrier_waw.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3416 mem_barrier_waw.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3417 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 1,
3418 &mem_barrier_waw, 0, nullptr, 0, nullptr);
3419 // The WAW should be safe (on a memory barrier)
3420 copy_general(image_c, image_b, full_region);
3421 // The WAR should also be safe (on a sync barrier)
3422 copy_general(image_c, image_a, full_region);
3423 m_errorMonitor->VerifyNotFound();
3424 m_commandBuffer->end();
3425
3426 // Barrier range check for WAW
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07003427 auto image_barrier_region0_waw = LvlInitStruct<VkImageMemoryBarrier>();
John Zulauf025ee442020-12-15 11:44:19 -07003428 image_barrier_region0_waw.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3429 image_barrier_region0_waw.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3430 image_barrier_region0_waw.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
3431 image_barrier_region0_waw.newLayout = VK_IMAGE_LAYOUT_GENERAL;
3432 image_barrier_region0_waw.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
3433 image_barrier_region0_waw.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
3434 image_barrier_region0_waw.image = image_b.handle();
3435 image_barrier_region0_waw.subresourceRange = layers_0_subresource_range;
3436
3437 // Region 0 safe, back WAW
3438 m_commandBuffer->reset();
3439 m_commandBuffer->begin();
3440 set_layouts();
3441 m_errorMonitor->ExpectSuccess();
3442 copy_general(image_a, image_b, full_region);
3443 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3444 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3445 nullptr, 1, &image_barrier_region0_waw);
3446 copy_general(image_a, image_b, region_0_to_0);
3447 m_errorMonitor->VerifyNotFound();
3448 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
3449 copy_general(image_a, image_b, region_1_to_1);
3450 m_errorMonitor->VerifyFound();
3451 m_commandBuffer->end();
3452}
John Zulauf4b5e4632020-12-15 11:48:59 -07003453
3454TEST_F(VkSyncValTest, SyncEventsCommandHazards) {
3455 TEST_DESCRIPTION("Check Set/Reset/Wait command hazard checking");
3456 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
3457 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
3458
3459 VkEventObj event;
3460 event.init(*m_device, VkEventObj::create_info(0));
3461
3462 const VkEvent event_handle = event.handle();
3463
3464 m_commandBuffer->begin();
3465 m_errorMonitor->ExpectSuccess();
3466 m_commandBuffer->ResetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3467 m_errorMonitor->VerifyNotFound();
3468
John Zulauf4edde622021-02-15 08:54:50 -07003469 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdResetEvent-event-03834");
John Zulauf4b5e4632020-12-15 11:48:59 -07003470 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3471 nullptr, 0, nullptr);
3472 m_errorMonitor->VerifyFound();
3473 m_errorMonitor->ExpectSuccess();
3474 m_commandBuffer->end();
3475
3476 m_commandBuffer->begin();
3477 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3478 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, nullptr,
3479 0, nullptr, 0, nullptr);
3480 m_errorMonitor->VerifyNotFound();
3481 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-vkCmdResetEvent-missingbarrier-wait");
3482 m_commandBuffer->ResetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3483 m_errorMonitor->VerifyFound();
3484 m_errorMonitor->ExpectSuccess();
3485 m_commandBuffer->end();
3486
3487 m_commandBuffer->begin();
3488 m_commandBuffer->ResetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3489 m_errorMonitor->VerifyNotFound();
3490 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-vkCmdSetEvent-missingbarrier-reset");
3491 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3492 m_errorMonitor->VerifyFound();
3493
3494 m_errorMonitor->ExpectSuccess();
3495 m_commandBuffer->PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0U, 0, nullptr, 0,
3496 nullptr, 0, nullptr);
3497 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3498 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3499 nullptr, 0, nullptr);
3500 m_commandBuffer->ResetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3501 m_commandBuffer->PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0U, 0, nullptr, 0,
3502 nullptr, 0, nullptr);
3503 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3504 m_errorMonitor->VerifyNotFound();
3505
3506 // Need a barrier between set and a reset
3507 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-vkCmdResetEvent-missingbarrier-set");
3508 m_commandBuffer->ResetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3509 m_errorMonitor->VerifyFound();
3510 m_errorMonitor->ExpectSuccess();
3511 m_commandBuffer->end();
3512
3513 m_commandBuffer->begin();
3514 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3515 m_errorMonitor->VerifyNotFound();
3516 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-vkCmdSetEvent-missingbarrier-set");
3517 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3518 m_errorMonitor->VerifyFound();
3519
3520 m_commandBuffer->end();
John Zulaufb0b6e9b2021-08-20 09:22:45 -06003521
3522 // Secondary command buffer events tests
3523 const auto cb = m_commandBuffer->handle();
3524 VkBufferObj buffer_a;
3525 VkBufferObj buffer_b;
3526 VkMemoryPropertyFlags mem_prop = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
3527 buffer_a.init_as_src_and_dst(*m_device, 256, mem_prop);
3528 buffer_b.init_as_src_and_dst(*m_device, 256, mem_prop);
3529
3530 VkBufferCopy front2front = {0, 0, 128};
3531
3532 // Barrier range check for WAW
3533 auto buffer_barrier_front_waw = LvlInitStruct<VkBufferMemoryBarrier>();
3534 buffer_barrier_front_waw.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3535 buffer_barrier_front_waw.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3536 buffer_barrier_front_waw.buffer = buffer_b.handle();
3537 buffer_barrier_front_waw.offset = front2front.dstOffset;
3538 buffer_barrier_front_waw.size = front2front.size;
3539
3540 m_errorMonitor->ExpectSuccess();
3541 VkCommandBufferObj secondary_cb1(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
3542 VkCommandBuffer scb1 = secondary_cb1.handle();
3543 secondary_cb1.begin();
3544 secondary_cb1.WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 1,
3545 &buffer_barrier_front_waw, 0, nullptr);
3546 vk::CmdCopyBuffer(scb1, buffer_a.handle(), buffer_b.handle(), 1, &front2front);
3547 secondary_cb1.end();
3548 m_errorMonitor->VerifyNotFound();
3549
3550 // One secondary cb hazarding with primary
3551 m_errorMonitor->ExpectSuccess();
3552 m_commandBuffer->reset();
3553 m_commandBuffer->begin();
3554 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &front2front);
3555 m_errorMonitor->VerifyNotFound();
3556 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
3557 vk::CmdExecuteCommands(cb, 1, &scb1);
3558 m_errorMonitor->VerifyFound();
3559 m_commandBuffer->end();
3560
3561 // One secondary cb sharing event with primary
3562 m_errorMonitor->ExpectSuccess();
3563 m_commandBuffer->reset();
3564 m_commandBuffer->begin();
3565 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &front2front);
3566 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3567 vk::CmdExecuteCommands(cb, 1, &scb1);
3568 m_commandBuffer->end();
3569 m_errorMonitor->VerifyNotFound();
John Zulauf4b5e4632020-12-15 11:48:59 -07003570}
ziga-lunarg3a16ff12021-07-30 12:09:55 +02003571
3572TEST_F(VkLayerTest, CmdWaitEvents2KHRUsedButSynchronizaion2Disabled) {
3573 TEST_DESCRIPTION("Using CmdWaitEvents2KHR when synchronization2 is not enabled");
Tony-LunarG53b72e52021-11-19 10:04:40 -07003574 SetTargetApiVersion(VK_API_VERSION_1_3);
sfricke-samsung6fc3e322022-02-15 22:41:29 -08003575
Tony-LunarGdf960d42022-01-27 16:13:34 -07003576 AddRequiredExtensions(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME);
ziga-lunarg3a16ff12021-07-30 12:09:55 +02003577 ASSERT_NO_FATAL_FAILURE(InitFramework());
sjfricked700bc02022-05-30 16:35:06 +09003578 if (!AreRequiredExtensionsEnabled()) {
3579 GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported";
ziga-lunarg3a16ff12021-07-30 12:09:55 +02003580 }
sjfricked8e01c52022-07-06 14:09:04 +09003581 ASSERT_NO_FATAL_FAILURE(InitState());
ziga-lunarg3a16ff12021-07-30 12:09:55 +02003582
Tony-LunarG53b72e52021-11-19 10:04:40 -07003583 bool vulkan_13 = (DeviceValidationVersion() >= VK_API_VERSION_1_3);
ziga-lunarg3a16ff12021-07-30 12:09:55 +02003584 auto fpCmdWaitEvents2KHR = (PFN_vkCmdWaitEvents2KHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdWaitEvents2KHR");
3585
3586 VkEventObj event;
3587 event.init(*m_device, VkEventObj::create_info(0));
3588 VkEvent event_handle = event.handle();
3589
3590 VkDependencyInfoKHR dependency_info = LvlInitStruct<VkDependencyInfoKHR>();
3591
3592 m_commandBuffer->begin();
Tony-LunarG279601c2021-11-16 10:50:51 -07003593 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdWaitEvents2-synchronization2-03836");
ziga-lunarg3a16ff12021-07-30 12:09:55 +02003594 fpCmdWaitEvents2KHR(m_commandBuffer->handle(), 1, &event_handle, &dependency_info);
3595 m_errorMonitor->VerifyFound();
Tony-LunarG53b72e52021-11-19 10:04:40 -07003596 if (vulkan_13) {
3597 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdWaitEvents2-synchronization2-03836");
3598 vk::CmdWaitEvents2(m_commandBuffer->handle(), 1, &event_handle, &dependency_info);
3599 m_errorMonitor->VerifyFound();
3600 }
ziga-lunarg3a16ff12021-07-30 12:09:55 +02003601 m_commandBuffer->end();
3602}
ziga-lunarg15f450d2021-08-26 23:10:05 +02003603
3604TEST_F(VkLayerTest, Sync2FeatureDisabled) {
3605 TEST_DESCRIPTION("Call sync2 functions when the feature is disabled");
3606
Tony-LunarG53b72e52021-11-19 10:04:40 -07003607 SetTargetApiVersion(VK_API_VERSION_1_3);
Tony-LunarGdf960d42022-01-27 16:13:34 -07003608 AddRequiredExtensions(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME);
ziga-lunarg15f450d2021-08-26 23:10:05 +02003609 ASSERT_NO_FATAL_FAILURE(InitFramework());
sjfricked700bc02022-05-30 16:35:06 +09003610 if (!AreRequiredExtensionsEnabled()) {
3611 GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported";
ziga-lunarg15f450d2021-08-26 23:10:05 +02003612 }
3613
3614 ASSERT_NO_FATAL_FAILURE(InitState());
3615
Tony-LunarG53b72e52021-11-19 10:04:40 -07003616 bool vulkan_13 = (DeviceValidationVersion() >= VK_API_VERSION_1_3);
ziga-lunarg15f450d2021-08-26 23:10:05 +02003617 VkPhysicalDeviceSynchronization2FeaturesKHR synchronization2 = LvlInitStruct<VkPhysicalDeviceSynchronization2FeaturesKHR>();
3618 synchronization2.synchronization2 = VK_FALSE; // Invalid
3619 auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&synchronization2);
3620 vk::GetPhysicalDeviceFeatures2(gpu(), &features2);
3621
3622 auto vkCmdPipelineBarrier2KHR =
3623 (PFN_vkCmdPipelineBarrier2KHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdPipelineBarrier2KHR");
3624 auto vkCmdResetEvent2KHR = (PFN_vkCmdResetEvent2KHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdResetEvent2KHR");
3625 auto vkCmdSetEvent2KHR = (PFN_vkCmdSetEvent2KHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetEvent2KHR");
3626 auto vkCmdWriteTimestamp2KHR =
3627 (PFN_vkCmdWriteTimestamp2KHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdWriteTimestamp2KHR");
3628
3629 bool timestamp = false;
3630
3631 uint32_t queue_count;
3632 vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_count, NULL);
3633 std::vector<VkQueueFamilyProperties> queue_props(queue_count);
3634 vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_count, queue_props.data());
3635 if (queue_props[m_device->graphics_queue_node_index_].timestampValidBits > 0) {
3636 timestamp = true;
3637 }
3638
3639 m_commandBuffer->begin();
3640
3641 VkDependencyInfoKHR dependency_info = LvlInitStruct<VkDependencyInfoKHR>();
3642
Tony-LunarG279601c2021-11-16 10:50:51 -07003643 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPipelineBarrier2-synchronization2-03848");
ziga-lunarg15f450d2021-08-26 23:10:05 +02003644 vkCmdPipelineBarrier2KHR(m_commandBuffer->handle(), &dependency_info);
3645 m_errorMonitor->VerifyFound();
3646
3647 VkEventCreateInfo eci = LvlInitStruct<VkEventCreateInfo>();
3648 vk_testing::Event event;
3649 event.init(*m_device, eci);
3650
3651 VkPipelineStageFlagBits2KHR stage = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR;
3652
Tony-LunarG279601c2021-11-16 10:50:51 -07003653 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResetEvent2-synchronization2-03829");
ziga-lunarg15f450d2021-08-26 23:10:05 +02003654 vkCmdResetEvent2KHR(m_commandBuffer->handle(), event.handle(), stage);
3655 m_errorMonitor->VerifyFound();
3656
Tony-LunarG279601c2021-11-16 10:50:51 -07003657 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetEvent2-synchronization2-03824");
ziga-lunarg15f450d2021-08-26 23:10:05 +02003658 vkCmdSetEvent2KHR(m_commandBuffer->handle(), event.handle(), &dependency_info);
3659 m_errorMonitor->VerifyFound();
3660
3661 if (timestamp) {
3662 VkQueryPoolCreateInfo qpci = LvlInitStruct<VkQueryPoolCreateInfo>();
3663 qpci.queryType = VK_QUERY_TYPE_TIMESTAMP;
3664 qpci.queryCount = 1;
3665
3666 vk_testing::QueryPool query_pool;
3667 query_pool.init(*m_device, qpci);
3668
Tony-LunarG279601c2021-11-16 10:50:51 -07003669 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdWriteTimestamp2-synchronization2-03858");
ziga-lunarg15f450d2021-08-26 23:10:05 +02003670 vkCmdWriteTimestamp2KHR(m_commandBuffer->handle(), stage, query_pool.handle(), 0);
3671 m_errorMonitor->VerifyFound();
Tony-LunarG53b72e52021-11-19 10:04:40 -07003672 if (vulkan_13) {
3673 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdWriteTimestamp2-synchronization2-03858");
3674 vk::CmdWriteTimestamp2(m_commandBuffer->handle(), stage, query_pool.handle(), 0);
3675 m_errorMonitor->VerifyFound();
3676 }
3677 }
3678 if (vulkan_13) {
3679 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPipelineBarrier2-synchronization2-03848");
3680 vk::CmdPipelineBarrier2(m_commandBuffer->handle(), &dependency_info);
3681 m_errorMonitor->VerifyFound();
3682
3683 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResetEvent2-synchronization2-03829");
3684 vk::CmdResetEvent2(m_commandBuffer->handle(), event.handle(), stage);
3685 m_errorMonitor->VerifyFound();
3686
3687 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetEvent2-synchronization2-03824");
3688 vk::CmdSetEvent2(m_commandBuffer->handle(), event.handle(), &dependency_info);
3689 m_errorMonitor->VerifyFound();
ziga-lunarg15f450d2021-08-26 23:10:05 +02003690 }
3691
3692 m_commandBuffer->end();
3693}
Jeremy Gebben9b6f0532022-02-02 11:10:31 -07003694
3695TEST_F(VkSyncValTest, DestroyedUnusedDescriptors) {
3696 TEST_DESCRIPTION("Verify unused descriptors are ignored and don't crash syncval if they've been destroyed.");
3697 SetTargetApiVersion(VK_API_VERSION_1_1);
Jeremy Gebben9b6f0532022-02-02 11:10:31 -07003698 AddRequiredExtensions(VK_KHR_MAINTENANCE_3_EXTENSION_NAME);
3699 AddRequiredExtensions(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
3700
3701 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
3702
sjfricked700bc02022-05-30 16:35:06 +09003703 if (!AreRequiredExtensionsEnabled()) {
3704 GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported";
Jeremy Gebben9b6f0532022-02-02 11:10:31 -07003705 }
3706
3707 auto indexing_features = LvlInitStruct<VkPhysicalDeviceDescriptorIndexingFeaturesEXT>();
3708 auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>();
3709 features2.pNext = &indexing_features;
3710
3711 auto vkGetPhysicalDeviceFeatures2KHR = reinterpret_cast<PFN_vkGetPhysicalDeviceFeatures2KHR>(
3712 vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR"));
3713 ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
3714
3715 vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
3716 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
3717 if (!indexing_features.descriptorBindingPartiallyBound) {
3718 printf("%s Partially bound bindings not supported, skipping test\n", kSkipPrefix);
3719 return;
3720 }
3721 if (!indexing_features.descriptorBindingUpdateUnusedWhilePending) {
3722 printf("%s Updating unused while pending is not supported, skipping test\n", kSkipPrefix);
3723 return;
3724 }
3725
3726 ASSERT_NO_FATAL_FAILURE(InitViewport());
3727 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3728 m_errorMonitor->ExpectSuccess();
3729
sfricke-samsung6fc3e322022-02-15 22:41:29 -08003730 VkDescriptorSetLayoutBindingFlagsCreateInfoEXT layout_createinfo_binding_flags =
3731 LvlInitStruct<VkDescriptorSetLayoutBindingFlagsCreateInfoEXT>();
Jeremy Gebben9b6f0532022-02-02 11:10:31 -07003732 constexpr size_t kNumDescriptors = 6;
3733
3734 std::array<VkDescriptorBindingFlagsEXT, kNumDescriptors> ds_binding_flags;
3735 for (auto &elem : ds_binding_flags) {
3736 elem = VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT | VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT;
3737 }
3738
Jeremy Gebben9b6f0532022-02-02 11:10:31 -07003739 layout_createinfo_binding_flags.bindingCount = ds_binding_flags.size();
3740 layout_createinfo_binding_flags.pBindingFlags = ds_binding_flags.data();
3741
3742 // Prepare descriptors
3743 OneOffDescriptorSet descriptor_set(m_device,
3744 {
3745 {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
3746 {1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
3747 {2, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
3748 {3, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr},
3749 {4, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_ALL, nullptr},
3750 {5, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr},
3751 },
3752 0, &layout_createinfo_binding_flags, 0);
3753 const VkPipelineLayoutObj pipeline_layout(m_device, {&descriptor_set.layout_});
3754 uint32_t qfi = 0;
3755 auto buffer_create_info = LvlInitStruct<VkBufferCreateInfo>();
3756 buffer_create_info.size = 32;
3757 buffer_create_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
3758 buffer_create_info.queueFamilyIndexCount = 1;
3759 buffer_create_info.pQueueFamilyIndices = &qfi;
3760
3761 VkBufferObj doit_buffer;
3762 doit_buffer.init(*m_device, buffer_create_info);
3763
3764 auto buffer = layer_data::make_unique<VkBufferObj>();
3765 buffer->init(*m_device, buffer_create_info);
3766
3767 VkDescriptorBufferInfo buffer_info[2] = {};
3768 buffer_info[0].buffer = doit_buffer.handle();
3769 buffer_info[0].offset = 0;
3770 buffer_info[0].range = sizeof(uint32_t);
3771 buffer_info[1].buffer = buffer->handle();
3772 buffer_info[1].offset = 0;
3773 buffer_info[1].range = sizeof(uint32_t);
3774
3775 VkBufferObj texel_buffer;
3776 buffer_create_info.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
3777 texel_buffer.init(*m_device, buffer_create_info);
3778
3779 auto bvci = LvlInitStruct<VkBufferViewCreateInfo>();
3780 bvci.buffer = texel_buffer.handle();
3781 bvci.format = VK_FORMAT_R32_SFLOAT;
3782 bvci.offset = 0;
3783 bvci.range = VK_WHOLE_SIZE;
3784
3785 auto texel_bufferview = layer_data::make_unique<vk_testing::BufferView>();
3786 texel_bufferview->init(*m_device, bvci);
3787
3788 auto index_buffer_create_info = LvlInitStruct<VkBufferCreateInfo>();
3789 index_buffer_create_info.size = sizeof(uint32_t);
3790 index_buffer_create_info.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
3791 VkBufferObj index_buffer;
3792 index_buffer.init(*m_device, index_buffer_create_info);
3793
3794 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
3795 VkImageObj sampled_image(m_device);
3796 auto image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 1, format, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL);
3797 sampled_image.Init(image_ci);
3798 auto sampled_view = layer_data::make_unique<vk_testing::ImageView>();
3799 auto imageview_ci = SafeSaneImageViewCreateInfo(sampled_image, format, VK_IMAGE_ASPECT_COLOR_BIT);
3800 sampled_view->init(*m_device, imageview_ci);
3801
3802 VkImageObj combined_image(m_device);
3803 image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 1, format, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL);
3804 combined_image.Init(image_ci);
3805 imageview_ci = SafeSaneImageViewCreateInfo(combined_image, format, VK_IMAGE_ASPECT_COLOR_BIT);
3806 auto combined_view = layer_data::make_unique<vk_testing::ImageView>();
3807 combined_view->init(*m_device, imageview_ci);
3808
3809 vk_testing::Sampler sampler;
3810 VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
3811 sampler.init(*m_device, sampler_ci);
3812
3813 VkDescriptorImageInfo image_info[3] = {};
3814 image_info[0].sampler = sampler.handle();
3815 image_info[0].imageView = VK_NULL_HANDLE;
3816 image_info[0].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
3817 image_info[1].sampler = VK_NULL_HANDLE;
3818 image_info[1].imageView = sampled_view->handle();
3819 image_info[1].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
3820 image_info[2].sampler = sampler.handle();
3821 image_info[2].imageView = combined_view->handle();
3822 image_info[2].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
3823
3824 // Update all descriptors
3825 std::array<VkWriteDescriptorSet, kNumDescriptors> descriptor_writes;
3826 descriptor_writes[0] = LvlInitStruct<VkWriteDescriptorSet>();
3827 descriptor_writes[0].dstSet = descriptor_set.set_;
3828 descriptor_writes[0].dstBinding = 0;
3829 descriptor_writes[0].descriptorCount = 1;
3830 descriptor_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
3831 descriptor_writes[0].pBufferInfo = &buffer_info[0];
3832
3833 descriptor_writes[1] = LvlInitStruct<VkWriteDescriptorSet>();
3834 descriptor_writes[1].dstSet = descriptor_set.set_;
3835 descriptor_writes[1].dstBinding = 1;
3836 descriptor_writes[1].descriptorCount = 1;
3837 descriptor_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
3838 descriptor_writes[1].pBufferInfo = &buffer_info[1];
3839
3840 descriptor_writes[2] = LvlInitStruct<VkWriteDescriptorSet>();
3841 descriptor_writes[2].dstSet = descriptor_set.set_;
3842 descriptor_writes[2].dstBinding = 2;
3843 descriptor_writes[2].descriptorCount = 1;
3844 descriptor_writes[2].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
3845 descriptor_writes[2].pTexelBufferView = &texel_bufferview->handle();
3846
3847 descriptor_writes[3] = LvlInitStruct<VkWriteDescriptorSet>();
3848 descriptor_writes[3].dstSet = descriptor_set.set_;
3849 descriptor_writes[3].dstBinding = 3;
3850 descriptor_writes[3].descriptorCount = 1;
3851 descriptor_writes[3].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
3852 descriptor_writes[3].pImageInfo = &image_info[0];
3853
3854 descriptor_writes[4] = LvlInitStruct<VkWriteDescriptorSet>();
3855 descriptor_writes[4].dstSet = descriptor_set.set_;
3856 descriptor_writes[4].dstBinding = 4;
3857 descriptor_writes[4].descriptorCount = 1;
3858 descriptor_writes[4].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
3859 descriptor_writes[4].pImageInfo = &image_info[1];
3860
3861 descriptor_writes[5] = LvlInitStruct<VkWriteDescriptorSet>();
3862 descriptor_writes[5].dstSet = descriptor_set.set_;
3863 descriptor_writes[5].dstBinding = 5;
3864 descriptor_writes[5].descriptorCount = 1;
3865 descriptor_writes[5].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
3866 descriptor_writes[5].pImageInfo = &image_info[2];
3867
3868 vk::UpdateDescriptorSets(m_device->device(), descriptor_writes.size(), descriptor_writes.data(), 0, NULL);
3869
3870 // only descriptor 0 is used, the rest are going to get destroyed
3871 char const *shader_source = R"glsl(
3872 #version 450
3873 layout(set = 0, binding = 0) uniform foo_0 { int val; } doit;
3874 layout(set = 0, binding = 1) uniform foo_1 { int val; } readit;
3875 layout(set = 0, binding = 2) uniform samplerBuffer texels;
3876 layout(set = 0, binding = 3) uniform sampler samp;
3877 layout(set = 0, binding = 4) uniform texture2D img;
3878 layout(set = 0, binding = 5) uniform sampler2D sampled_image;
3879
3880 void main() {
3881 vec4 x;
3882 vec4 y;
3883 vec4 z;
3884 if (doit.val == 0) {
3885 gl_Position = vec4(0.0);
3886 x = vec4(0.0);
3887 y = vec4(0.0);
3888 z = vec4(0.0);
3889 } else {
3890 gl_Position = vec4(readit.val);
3891 x = texelFetch(texels, 5);
3892 y = texture(sampler2D(img, samp), vec2(0));
3893 z = texture(sampled_image, vec2(0));
3894 }
3895 }
3896 )glsl";
3897
3898 VkShaderObj vs(this, shader_source, VK_SHADER_STAGE_VERTEX_BIT);
3899 VkPipelineObj pipe(m_device);
3900 pipe.AddShader(&vs);
3901 pipe.AddDefaultColorAttachment();
3902 pipe.CreateVKPipeline(pipeline_layout.handle(), m_renderPass);
sfricke-samsung6fc3e322022-02-15 22:41:29 -08003903 VkCommandBufferBeginInfo begin_info = LvlInitStruct<VkCommandBufferBeginInfo>();
Jeremy Gebben9b6f0532022-02-02 11:10:31 -07003904 m_commandBuffer->begin(&begin_info);
3905 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
3906 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
3907 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
3908 &descriptor_set.set_, 0, nullptr);
3909
3910 // destroy resources for the unused descriptors
3911 buffer.reset();
3912 texel_bufferview.reset();
3913 sampled_view.reset();
3914 combined_view.reset();
3915
3916 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), index_buffer.handle(), 0, VK_INDEX_TYPE_UINT32);
3917 VkViewport viewport = {0, 0, 16, 16, 0, 1};
3918 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
3919 VkRect2D scissor = {{0, 0}, {16, 16}};
3920 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
3921 vk::CmdDrawIndexed(m_commandBuffer->handle(), 1, 1, 0, 0, 0);
3922 vk::CmdEndRenderPass(m_commandBuffer->handle());
3923 m_commandBuffer->end();
3924 m_commandBuffer->QueueCommandBuffer();
3925 vk::QueueWaitIdle(m_device->m_queue);
3926 m_errorMonitor->VerifyNotFound();
3927}
ziga-lunargc71f1a92022-03-23 23:08:35 +01003928
ziga-lunarg26ba4b92022-03-24 16:43:03 +01003929TEST_F(VkSyncValTest, TestInvalidExternalSubpassDependency) {
3930 TEST_DESCRIPTION("Test write after write hazard with invalid external subpass dependency");
3931
3932 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
3933 ASSERT_NO_FATAL_FAILURE(InitState());
3934
3935 VkSubpassDependency subpass_dependency = {};
3936 subpass_dependency.srcSubpass = 0;
3937 subpass_dependency.dstSubpass = VK_SUBPASS_EXTERNAL;
3938 subpass_dependency.srcStageMask = 0;
3939 subpass_dependency.dstStageMask = 0;
3940 subpass_dependency.srcAccessMask = 0;
3941 subpass_dependency.dstAccessMask = 0;
3942 subpass_dependency.dependencyFlags = 0;
3943
3944 VkAttachmentReference attach_ref1 = {};
3945 attach_ref1.attachment = 0;
3946 attach_ref1.layout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL;
3947 VkAttachmentReference attach_ref2 = {};
3948 attach_ref2.attachment = 0;
3949 attach_ref2.layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
3950
3951 VkSubpassDescription subpass_descriptions[2] = {};
3952 subpass_descriptions[0].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
3953 subpass_descriptions[0].pDepthStencilAttachment = &attach_ref1;
3954 subpass_descriptions[1].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
3955 subpass_descriptions[1].pDepthStencilAttachment = &attach_ref2;
3956
3957 VkAttachmentDescription attachment_description = {};
3958 attachment_description.format = VK_FORMAT_D32_SFLOAT;
3959 attachment_description.samples = VK_SAMPLE_COUNT_1_BIT;
3960 attachment_description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
3961 attachment_description.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
3962 attachment_description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
3963 attachment_description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
3964 attachment_description.initialLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL;
3965 attachment_description.finalLayout = VK_IMAGE_LAYOUT_GENERAL;
3966
3967 auto rp_ci = LvlInitStruct<VkRenderPassCreateInfo>();
3968 rp_ci.subpassCount = 1;
3969 rp_ci.pSubpasses = subpass_descriptions;
3970 rp_ci.attachmentCount = 1;
3971 rp_ci.pAttachments = &attachment_description;
3972 rp_ci.dependencyCount = 1;
3973 rp_ci.pDependencies = &subpass_dependency;
3974
3975 vk_testing::RenderPass render_pass;
3976 render_pass.init(*m_device, rp_ci);
3977
3978 VkClearValue clear_value = {};
3979 clear_value.color = {{0, 0, 0, 0}};
3980
3981 VkImageCreateInfo image_ci = LvlInitStruct<VkImageCreateInfo>();
3982 image_ci.imageType = VK_IMAGE_TYPE_2D;
3983 image_ci.format = VK_FORMAT_D32_SFLOAT;
3984 image_ci.extent.width = 32;
3985 image_ci.extent.height = 32;
3986 image_ci.extent.depth = 1;
3987 image_ci.mipLevels = 1;
3988 image_ci.arrayLayers = 1;
3989 image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
3990 image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
3991 image_ci.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
3992
3993 VkImageObj image1(m_device);
3994 image1.init(&image_ci);
3995 ASSERT_TRUE(image1.initialized());
3996
3997 vk_testing::ImageView image_view1;
3998 VkImageViewCreateInfo iv_ci = LvlInitStruct<VkImageViewCreateInfo>();
3999 iv_ci.image = image1.handle();
4000 iv_ci.viewType = VK_IMAGE_VIEW_TYPE_2D;
4001 iv_ci.format = VK_FORMAT_D32_SFLOAT;
4002 iv_ci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
4003 iv_ci.subresourceRange.baseMipLevel = 0;
4004 iv_ci.subresourceRange.levelCount = 1;
4005 iv_ci.subresourceRange.baseArrayLayer = 0;
4006 iv_ci.subresourceRange.layerCount = 1;
4007 image_view1.init(*m_device, iv_ci);
4008
4009 VkImageView framebuffer_attachments[1] = {image_view1.handle()};
4010
4011 auto fb_ci = LvlInitStruct<VkFramebufferCreateInfo>();
4012 fb_ci.renderPass = render_pass.handle();
4013 fb_ci.attachmentCount = 1;
4014 fb_ci.pAttachments = framebuffer_attachments;
4015 fb_ci.width = 32;
4016 fb_ci.height = 32;
4017 fb_ci.layers = 1;
4018
4019 vk_testing::Framebuffer framebuffer;
4020 framebuffer.init(*m_device, fb_ci);
4021
4022 auto rp_bi = LvlInitStruct<VkRenderPassBeginInfo>();
4023 rp_bi.renderPass = render_pass.handle();
4024 rp_bi.framebuffer = framebuffer.handle();
4025 rp_bi.renderArea.extent.width = 32;
4026 rp_bi.renderArea.extent.height = 32;
4027 rp_bi.clearValueCount = 1;
4028 rp_bi.pClearValues = &clear_value;
4029
4030 auto ds_ci = LvlInitStruct<VkPipelineDepthStencilStateCreateInfo>();
4031 ds_ci.depthTestEnable = VK_FALSE;
4032 ds_ci.depthWriteEnable = VK_FALSE;
4033 ds_ci.depthCompareOp = VK_COMPARE_OP_NEVER;
4034
4035 CreatePipelineHelper pipe(*this);
4036 pipe.InitInfo();
4037 pipe.gp_ci_.renderPass = render_pass.handle();
4038 pipe.gp_ci_.pDepthStencilState = &ds_ci;
4039 pipe.InitState();
4040 ASSERT_VK_SUCCESS(pipe.CreateGraphicsPipeline());
4041
4042 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
4043
4044 m_commandBuffer->begin();
4045 m_commandBuffer->BeginRenderPass(rp_bi);
4046 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
4047 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
4048 m_commandBuffer->EndRenderPass();
4049 m_commandBuffer->end();
4050
4051 m_errorMonitor->VerifyFound();
4052}
4053
ziga-lunargc71f1a92022-03-23 23:08:35 +01004054TEST_F(VkSyncValTest, TestCopyingToCompressedImage) {
4055 TEST_DESCRIPTION("Copy from uncompressed to compressed image with and without overlap.");
4056
4057 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
4058 bool copy_commands_2 = false;
4059 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_COPY_COMMANDS_2_EXTENSION_NAME)) {
4060 m_device_extension_names.push_back(VK_KHR_COPY_COMMANDS_2_EXTENSION_NAME);
4061 copy_commands_2 = true;
4062 }
4063 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
4064
4065 VkFormatProperties format_properties;
4066 VkFormat mp_format = VK_FORMAT_BC1_RGBA_UNORM_BLOCK;
4067 vk::GetPhysicalDeviceFormatProperties(gpu(), mp_format, &format_properties);
4068 if ((format_properties.linearTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0) {
4069 printf(
4070 "%s Device does not support VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT for VK_FORMAT_BC1_RGBA_UNORM_BLOCK, skipping test.\n",
4071 kSkipPrefix);
4072 return;
4073 }
4074
4075 VkImageObj src_image(m_device);
4076 src_image.Init(1, 1, 1, VK_FORMAT_R32G32_UINT, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_LINEAR);
4077 VkImageObj dst_image(m_device);
4078 dst_image.Init(12, 4, 1, VK_FORMAT_BC1_RGBA_UNORM_BLOCK, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_LINEAR);
4079
4080 VkImageCopy copy_regions[2] = {};
4081 copy_regions[0].srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4082 copy_regions[0].srcSubresource.mipLevel = 0;
4083 copy_regions[0].srcSubresource.baseArrayLayer = 0;
4084 copy_regions[0].srcSubresource.layerCount = 1;
4085 copy_regions[0].srcOffset = {0, 0, 0};
4086 copy_regions[0].dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4087 copy_regions[0].dstSubresource.mipLevel = 0;
4088 copy_regions[0].dstSubresource.baseArrayLayer = 0;
4089 copy_regions[0].dstSubresource.layerCount = 1;
4090 copy_regions[0].dstOffset = {0, 0, 0};
4091 copy_regions[0].extent = {1, 1, 1};
4092 copy_regions[1].srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4093 copy_regions[1].srcSubresource.mipLevel = 0;
4094 copy_regions[1].srcSubresource.baseArrayLayer = 0;
4095 copy_regions[1].srcSubresource.layerCount = 1;
4096 copy_regions[1].srcOffset = {0, 0, 0};
4097 copy_regions[1].dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4098 copy_regions[1].dstSubresource.mipLevel = 0;
4099 copy_regions[1].dstSubresource.baseArrayLayer = 0;
4100 copy_regions[1].dstSubresource.layerCount = 1;
4101 copy_regions[1].dstOffset = {4, 0, 0};
4102 copy_regions[1].extent = {1, 1, 1};
4103
4104 m_commandBuffer->begin();
4105
4106 m_errorMonitor->ExpectSuccess();
4107 vk::CmdCopyImage(m_commandBuffer->handle(), src_image.handle(), VK_IMAGE_LAYOUT_GENERAL, dst_image.handle(),
4108 VK_IMAGE_LAYOUT_GENERAL, 1, &copy_regions[0]);
4109 vk::CmdCopyImage(m_commandBuffer->handle(), src_image.handle(), VK_IMAGE_LAYOUT_GENERAL, dst_image.handle(),
4110 VK_IMAGE_LAYOUT_GENERAL, 1, &copy_regions[1]);
4111 m_errorMonitor->VerifyNotFound();
4112 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "SYNC-HAZARD-WRITE_AFTER_WRITE");
4113 copy_regions[1].dstOffset = {7, 0, 0};
4114 vk::CmdCopyImage(m_commandBuffer->handle(), src_image.handle(), VK_IMAGE_LAYOUT_GENERAL, dst_image.handle(),
4115 VK_IMAGE_LAYOUT_GENERAL, 1, &copy_regions[1]);
4116 m_errorMonitor->VerifyFound();
4117
4118 m_commandBuffer->end();
4119
4120 if (copy_commands_2) {
4121 auto vkCmdCopyImage2KHR =
4122 reinterpret_cast<PFN_vkCmdCopyImage2KHR>(vk::GetInstanceProcAddr(instance(), "vkCmdCopyImage2KHR"));
4123 assert(vkCmdCopyImage2KHR != nullptr);
4124
4125 m_commandBuffer->reset();
4126
4127 VkImageCopy2KHR copy_regions2[2];
4128 copy_regions2[0] = LvlInitStruct<VkImageCopy2KHR>();
4129 copy_regions2[0].srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4130 copy_regions2[0].srcSubresource.mipLevel = 0;
4131 copy_regions2[0].srcSubresource.baseArrayLayer = 0;
4132 copy_regions2[0].srcSubresource.layerCount = 1;
4133 copy_regions2[0].srcOffset = {0, 0, 0};
4134 copy_regions2[0].dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4135 copy_regions2[0].dstSubresource.mipLevel = 0;
4136 copy_regions2[0].dstSubresource.baseArrayLayer = 0;
4137 copy_regions2[0].dstSubresource.layerCount = 1;
4138 copy_regions2[0].dstOffset = {0, 0, 0};
4139 copy_regions2[0].extent = {1, 1, 1};
4140 copy_regions2[1] = LvlInitStruct<VkImageCopy2KHR>();
4141 copy_regions2[1].srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4142 copy_regions2[1].srcSubresource.mipLevel = 0;
4143 copy_regions2[1].srcSubresource.baseArrayLayer = 0;
4144 copy_regions2[1].srcSubresource.layerCount = 1;
4145 copy_regions2[1].srcOffset = {0, 0, 0};
4146 copy_regions2[1].dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4147 copy_regions2[1].dstSubresource.mipLevel = 0;
4148 copy_regions2[1].dstSubresource.baseArrayLayer = 0;
4149 copy_regions2[1].dstSubresource.layerCount = 1;
4150 copy_regions2[1].dstOffset = {4, 0, 0};
4151 copy_regions2[1].extent = {1, 1, 1};
4152
4153 auto copy_image_info = LvlInitStruct<VkCopyImageInfo2KHR>();
4154 copy_image_info.srcImage = src_image.handle();
4155 copy_image_info.srcImageLayout = VK_IMAGE_LAYOUT_GENERAL;
4156 copy_image_info.dstImage = dst_image.handle();
4157 copy_image_info.dstImageLayout = VK_IMAGE_LAYOUT_GENERAL;
4158 copy_image_info.regionCount = 2;
4159 copy_image_info.pRegions = copy_regions2;
4160
4161 m_commandBuffer->begin();
4162
4163 m_errorMonitor->ExpectSuccess();
4164 vkCmdCopyImage2KHR(m_commandBuffer->handle(), &copy_image_info);
4165 m_errorMonitor->VerifyNotFound();
4166 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "SYNC-HAZARD-WRITE_AFTER_WRITE");
4167 copy_image_info.regionCount = 1;
4168 copy_image_info.pRegions = &copy_regions2[1];
4169 copy_regions[1].dstOffset = {7, 0, 0};
4170 vkCmdCopyImage2KHR(m_commandBuffer->handle(), &copy_image_info);
4171 m_errorMonitor->VerifyFound();
4172
4173 m_commandBuffer->end();
4174 }
4175}
John Zulaufd79e34f2022-04-20 16:39:59 -06004176
Jeremy Gebbena0e0e772022-06-08 14:41:43 -06004177TEST_F(VkSyncValTest, StageAccessExpansion) {
4178 SetTargetApiVersion(VK_API_VERSION_1_2);
4179
4180 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
4181 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
4182 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4183
4184 VkImageUsageFlags image_usage_combine = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
4185 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
4186 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
4187 VkImageObj image_c_a(m_device), image_c_b(m_device);
4188 const auto image_c_ci = VkImageObj::ImageCreateInfo2D(16, 16, 1, 1, format, image_usage_combine, VK_IMAGE_TILING_OPTIMAL);
4189 image_c_a.Init(image_c_ci);
4190 image_c_b.Init(image_c_ci);
4191
4192 VkImageView imageview_c = image_c_a.targetView(format);
4193 VkImageUsageFlags image_usage_storage =
4194 VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
4195 VkImageObj image_s_a(m_device), image_s_b(m_device);
4196 const auto image_s_ci = VkImageObj::ImageCreateInfo2D(16, 16, 1, 1, format, image_usage_storage, VK_IMAGE_TILING_OPTIMAL);
4197 image_s_a.Init(image_s_ci);
4198 image_s_b.Init(image_s_ci);
4199 image_s_a.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
4200 image_s_b.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
4201
4202 VkImageView imageview_s = image_s_a.targetView(format);
4203
4204 vk_testing::Sampler sampler_s, sampler_c;
4205 VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
4206 sampler_s.init(*m_device, sampler_ci);
4207 sampler_c.init(*m_device, sampler_ci);
4208
4209 VkBufferObj buffer_a, buffer_b;
4210 VkMemoryPropertyFlags mem_prop = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
4211 VkBufferUsageFlags buffer_usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT |
4212 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
4213 buffer_a.init(*m_device, buffer_a.create_info(2048, buffer_usage, nullptr), mem_prop);
4214 buffer_b.init(*m_device, buffer_b.create_info(2048, buffer_usage, nullptr), mem_prop);
4215
4216 vk_testing::BufferView bufferview;
4217 auto bvci = LvlInitStruct<VkBufferViewCreateInfo>();
4218 bvci.buffer = buffer_a.handle();
4219 bvci.format = VK_FORMAT_R32_SFLOAT;
4220 bvci.offset = 0;
4221 bvci.range = VK_WHOLE_SIZE;
4222
4223 bufferview.init(*m_device, bvci);
4224
4225 OneOffDescriptorSet descriptor_set(m_device,
4226 {
4227 {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
4228 {1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr},
4229 {2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_ALL, nullptr},
4230 {3, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
4231 });
4232
4233 descriptor_set.WriteDescriptorBufferInfo(0, buffer_a.handle(), 0, 2048);
4234 descriptor_set.WriteDescriptorImageInfo(1, imageview_c, sampler_c.handle(), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
4235 VK_IMAGE_LAYOUT_GENERAL);
4236 descriptor_set.WriteDescriptorImageInfo(2, imageview_s, sampler_s.handle(), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
4237 VK_IMAGE_LAYOUT_GENERAL);
4238 descriptor_set.WriteDescriptorBufferView(3, bufferview.handle());
4239 descriptor_set.UpdateDescriptorSets();
4240
4241 // Dispatch
4242 std::string csSource = R"glsl(
4243 #version 450
4244 layout(set=0, binding=0) uniform foo { float x; } ub0;
4245 layout(set=0, binding=1) uniform sampler2D cis1;
4246 layout(set=0, binding=2, rgba8) uniform readonly image2D si2;
4247 layout(set=0, binding=3, r32f) uniform readonly imageBuffer stb3;
4248 void main(){
4249 vec4 vColor4;
4250 vColor4.x = ub0.x;
4251 vColor4 = texture(cis1, vec2(0));
4252 vColor4 = imageLoad(si2, ivec2(0));
4253 vColor4 = imageLoad(stb3, 0);
4254 }
4255 )glsl";
4256
4257 // Draw
4258 m_errorMonitor->ExpectSuccess();
4259 const float vbo_data[3] = {1.f, 0.f, 1.f};
4260 VkVertexInputAttributeDescription VertexInputAttributeDescription = {0, 0, VK_FORMAT_R32G32B32_SFLOAT, sizeof(vbo_data)};
4261 VkVertexInputBindingDescription VertexInputBindingDescription = {0, sizeof(vbo_data), VK_VERTEX_INPUT_RATE_VERTEX};
4262 VkBufferObj vbo, vbo2;
4263 buffer_usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
4264 vbo.init(*m_device, vbo.create_info(sizeof(vbo_data), buffer_usage, nullptr), mem_prop);
4265 vbo2.init(*m_device, vbo2.create_info(sizeof(vbo_data), buffer_usage, nullptr), mem_prop);
4266
4267 VkShaderObj vs(this, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT);
Nathaniel Cesario2c8e1942022-06-21 09:15:19 -06004268 VkShaderObj fs(this, csSource.c_str(), VK_SHADER_STAGE_FRAGMENT_BIT);
Jeremy Gebbena0e0e772022-06-08 14:41:43 -06004269
4270 CreatePipelineHelper g_pipe(*this);
4271 g_pipe.InitInfo();
4272 g_pipe.InitState();
4273 g_pipe.vi_ci_.pVertexBindingDescriptions = &VertexInputBindingDescription;
4274 g_pipe.vi_ci_.vertexBindingDescriptionCount = 1;
4275 g_pipe.vi_ci_.pVertexAttributeDescriptions = &VertexInputAttributeDescription;
4276 g_pipe.vi_ci_.vertexAttributeDescriptionCount = 1;
4277 g_pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
4278 g_pipe.pipeline_layout_ = VkPipelineLayoutObj(m_device, {&descriptor_set.layout_});
4279 ASSERT_VK_SUCCESS(g_pipe.CreateGraphicsPipeline());
4280
4281 m_commandBuffer->reset();
4282 m_commandBuffer->begin();
4283 VkImageSubresourceLayers layer{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
4284 VkOffset3D zero_offset{0, 0, 0};
4285 VkExtent3D full_extent{16, 16, 1};
4286 VkImageCopy image_region = {layer, zero_offset, layer, zero_offset, full_extent};
4287 vk::CmdCopyImage(m_commandBuffer->handle(), image_c_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_c_a.handle(),
4288 VK_IMAGE_LAYOUT_GENERAL, 1, &image_region);
4289 vk::CmdCopyImage(m_commandBuffer->handle(), image_s_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_s_a.handle(),
4290 VK_IMAGE_LAYOUT_GENERAL, 1, &image_region);
4291
4292 auto barrier = LvlInitStruct<VkMemoryBarrier>();
4293 barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
4294 barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
4295
4296 // wrong: dst stage should be VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4297 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 1,
4298 &barrier, 0, nullptr, 0, nullptr);
4299 m_errorMonitor->VerifyNotFound();
4300
4301 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
4302 VkDeviceSize offset = 0;
4303 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
4304
4305 VkViewport viewport = {0, 0, 16, 16, 0, 1};
4306 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
4307 VkRect2D scissor = {{0, 0}, {16, 16}};
4308 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
4309
4310 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
4311 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
4312 &descriptor_set.set_, 0, nullptr);
4313
4314 // one error for each image copied above
4315 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
4316 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
4317 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
4318 m_errorMonitor->VerifyFound();
4319
4320 m_errorMonitor->ExpectSuccess();
4321 m_commandBuffer->EndRenderPass();
4322 m_commandBuffer->end();
4323 m_errorMonitor->VerifyNotFound();
4324
4325 // Try again with the correct dst stage on the barrier
4326 m_errorMonitor->ExpectSuccess();
4327 m_commandBuffer->reset();
4328 m_commandBuffer->begin();
4329 vk::CmdCopyImage(m_commandBuffer->handle(), image_c_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_c_a.handle(),
4330 VK_IMAGE_LAYOUT_GENERAL, 1, &image_region);
4331 vk::CmdCopyImage(m_commandBuffer->handle(), image_s_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_s_a.handle(),
4332 VK_IMAGE_LAYOUT_GENERAL, 1, &image_region);
4333
4334 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 1,
4335 &barrier, 0, nullptr, 0, nullptr);
4336
4337 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
4338 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
4339
4340 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
4341 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
4342
4343 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
4344 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
4345 &descriptor_set.set_, 0, nullptr);
4346 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
4347 m_commandBuffer->EndRenderPass();
4348 m_commandBuffer->end();
4349 m_errorMonitor->VerifyNotFound();
4350}
4351
John Zulaufb66ee052022-06-10 16:52:28 -06004352struct QSTestContext {
John Zulaufc55f4702022-07-15 12:16:34 -06004353 VkDeviceObj* dev;
John Zulaufb66ee052022-06-10 16:52:28 -06004354 uint32_t q_fam = ~0U;
John Zulauf6df2d5c2022-05-28 13:02:21 -06004355 VkQueue q0 = VK_NULL_HANDLE;
4356 VkQueue q1 = VK_NULL_HANDLE;
John Zulaufb66ee052022-06-10 16:52:28 -06004357
4358 VkBufferObj buffer_a;
4359 VkBufferObj buffer_b;
4360 VkBufferObj buffer_c;
4361
4362 VkBufferCopy region;
4363 VkCommandPoolObj pool;
4364
4365 VkCommandBufferObj cba;
4366 VkCommandBufferObj cbb;
4367 VkCommandBufferObj cbc;
4368
4369 VkCommandBuffer h_cba = VK_NULL_HANDLE;
4370 VkCommandBuffer h_cbb = VK_NULL_HANDLE;
4371 VkCommandBuffer h_cbc = VK_NULL_HANDLE;
4372
4373 vk_testing::Semaphore semaphore;
4374 vk_testing::Event event;
4375
4376 VkCommandBufferObj* current_cb = nullptr;
4377
John Zulaufc55f4702022-07-15 12:16:34 -06004378 QSTestContext(VkDeviceObj* device, VkQueueObj* force_q0 = nullptr, VkQueueObj* force_q1 = nullptr);
John Zulaufb66ee052022-06-10 16:52:28 -06004379 bool Valid() const { return q1 != VK_NULL_HANDLE; }
4380
4381 void Begin(VkCommandBufferObj& cb);
4382 void BeginA() { Begin(cba); }
4383 void BeginB() { Begin(cbb); }
4384 void BeginC() { Begin(cbc); }
4385
4386 void End();
4387
4388 void CopyAToB() { vk::CmdCopyBuffer(current_cb->handle(), buffer_a.handle(), buffer_b.handle(), 1, &region); }
4389 void CopyAToC() { vk::CmdCopyBuffer(current_cb->handle(), buffer_a.handle(), buffer_c.handle(), 1, &region); }
4390
4391 void CopyBToA() { vk::CmdCopyBuffer(current_cb->handle(), buffer_b.handle(), buffer_a.handle(), 1, &region); }
4392 void CopyBToC() { vk::CmdCopyBuffer(current_cb->handle(), buffer_b.handle(), buffer_c.handle(), 1, &region); }
4393
4394 void CopyCToA() { vk::CmdCopyBuffer(current_cb->handle(), buffer_c.handle(), buffer_a.handle(), 1, &region); }
4395 void CopyCToB() { vk::CmdCopyBuffer(current_cb->handle(), buffer_c.handle(), buffer_b.handle(), 1, &region); }
4396
John Zulauf46f5d6b2022-06-30 12:38:34 -06004397 void CopyGeneral(const VkImageObj& from, const VkImageObj& to, const VkImageCopy& region) {
4398 vk::CmdCopyImage(current_cb->handle(), from.handle(), VK_IMAGE_LAYOUT_GENERAL, to.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
4399 &region);
4400 };
4401
John Zulaufb66ee052022-06-10 16:52:28 -06004402 VkBufferMemoryBarrier InitBufferBarrier(const VkBufferObj& buffer);
4403 void TransferBarrier(const VkBufferObj& buffer);
4404 void TransferBarrier(const VkBufferMemoryBarrier& buffer_barrier);
4405
John Zulaufc55f4702022-07-15 12:16:34 -06004406 void Submit(VkQueue q, VkCommandBufferObj& cb, VkSemaphore wait = VK_NULL_HANDLE,
4407 VkPipelineStageFlags wait_mask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VkSemaphore signal = VK_NULL_HANDLE);
John Zulaufb66ee052022-06-10 16:52:28 -06004408
John Zulaufc55f4702022-07-15 12:16:34 -06004409 void Submit0(VkCommandBufferObj& cb, VkSemaphore wait = VK_NULL_HANDLE,
4410 VkPipelineStageFlags wait_mask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VkSemaphore signal = VK_NULL_HANDLE) {
John Zulaufb66ee052022-06-10 16:52:28 -06004411 Submit(q0, cb, wait, wait_mask, signal);
4412 }
4413 void Submit0Wait(VkCommandBufferObj& cb, VkPipelineStageFlags wait_mask) { Submit0(cb, semaphore.handle(), wait_mask); }
4414 void Submit0Signal(VkCommandBufferObj& cb) { Submit0(cb, VK_NULL_HANDLE, 0U, semaphore.handle()); }
4415
John Zulaufc55f4702022-07-15 12:16:34 -06004416 void Submit1(VkCommandBufferObj& cb, VkSemaphore wait = VK_NULL_HANDLE,
4417 VkPipelineStageFlags wait_mask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VkSemaphore signal = VK_NULL_HANDLE) {
John Zulaufb66ee052022-06-10 16:52:28 -06004418 Submit(q1, cb, wait, wait_mask, signal);
4419 }
4420 void Submit1Wait(VkCommandBufferObj& cb, VkPipelineStageFlags wait_mask) { Submit1(cb, semaphore.handle(), wait_mask); }
4421 void Submit1Signal(VkCommandBufferObj& cb, VkPipelineStageFlags signal_mask) {
4422 Submit1(cb, VK_NULL_HANDLE, 0U, semaphore.handle());
4423 }
4424 void SetEvent(VkPipelineStageFlags src_mask) { event.cmd_set(*current_cb, src_mask); }
4425 void WaitEventBufferTransfer(VkBufferObj& buffer, VkPipelineStageFlags src_mask, VkPipelineStageFlags dst_mask) {
4426 std::vector<VkBufferMemoryBarrier> buffer_barriers(1, InitBufferBarrier(buffer));
4427 event.cmd_wait(*current_cb, src_mask, dst_mask, std::vector<VkMemoryBarrier>(), buffer_barriers,
4428 std::vector<VkImageMemoryBarrier>());
4429 }
John Zulaufc55f4702022-07-15 12:16:34 -06004430 void QueueWait(VkQueue q) { vk::QueueWaitIdle(q); }
4431 void QueueWait0() { QueueWait(q0); }
4432 void QueueWait1() { QueueWait(q1); }
4433 void DeviceWait() { vk::DeviceWaitIdle(dev->handle()); }
John Zulaufb66ee052022-06-10 16:52:28 -06004434};
4435
John Zulaufc55f4702022-07-15 12:16:34 -06004436QSTestContext::QSTestContext(VkDeviceObj* device, VkQueueObj* force_q0, VkQueueObj* force_q1)
4437 : dev(device), q0(VK_NULL_HANDLE), q1(VK_NULL_HANDLE) {
4438 if (force_q0) {
4439 q0 = force_q0->handle();
4440 q_fam = force_q0->get_family_index();
4441 if (force_q1) {
4442 // The object has some assumptions that the queues are from the the same family, so enforce this here
4443 if (force_q1->get_family_index() == q_fam) {
4444 q1 = force_q1->handle();
4445 }
4446 } else {
4447 q1 = q0; // Allow the two queues to be the same and valid if forced
4448 }
4449 } else {
4450 const auto& queues = device->dma_queues();
John Zulauf6df2d5c2022-05-28 13:02:21 -06004451
John Zulaufc55f4702022-07-15 12:16:34 -06004452 const uint32_t q_count = static_cast<uint32_t>(queues.size());
4453 for (uint32_t q0_index = 0; q0_index < q_count; ++q0_index) {
4454 const auto* q0_entry = queues[q0_index];
4455 q0 = q0_entry->handle();
4456 q_fam = q0_entry->get_family_index();
4457 for (uint32_t q1_index = (q0_index + 1); q1_index < q_count; ++q1_index) {
4458 const auto* q1_entry = queues[q1_index];
4459 if (q_fam == q1_entry->get_family_index()) {
4460 q1 = q1_entry->handle();
4461 break;
4462 }
4463 }
4464 if (Valid()) {
John Zulauf6df2d5c2022-05-28 13:02:21 -06004465 break;
4466 }
4467 }
John Zulauf6df2d5c2022-05-28 13:02:21 -06004468 }
John Zulaufc55f4702022-07-15 12:16:34 -06004469
John Zulaufb66ee052022-06-10 16:52:28 -06004470 if (!Valid()) return;
4471
4472 VkMemoryPropertyFlags mem_prop = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
4473 buffer_a.init_as_src_and_dst(*device, 256, mem_prop);
4474 buffer_b.init_as_src_and_dst(*device, 256, mem_prop);
4475 buffer_c.init_as_src_and_dst(*device, 256, mem_prop);
4476
4477 region = {0, 0, 256};
4478
4479 pool.Init(device, q_fam, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
4480 cba.Init(device, &pool);
4481 cbb.Init(device, &pool);
4482 cbc.Init(device, &pool);
4483
4484 h_cba = cba.handle();
4485 h_cbb = cbb.handle();
4486 h_cbc = cbc.handle();
4487
4488 auto semaphore_ci = LvlInitStruct<VkSemaphoreCreateInfo>();
4489 semaphore.init(*device, semaphore_ci);
4490
4491 VkEventCreateInfo eci = LvlInitStruct<VkEventCreateInfo>();
4492 event.init(*device, eci);
4493}
4494
4495void QSTestContext::Begin(VkCommandBufferObj& cb) {
John Zulaufc55f4702022-07-15 12:16:34 -06004496 VkCommandBufferBeginInfo info = LvlInitStruct<VkCommandBufferBeginInfo>();
4497 info.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
4498 info.pInheritanceInfo = nullptr;
4499
John Zulaufb66ee052022-06-10 16:52:28 -06004500 cb.reset();
John Zulaufc55f4702022-07-15 12:16:34 -06004501 cb.begin(&info);
John Zulaufb66ee052022-06-10 16:52:28 -06004502 current_cb = &cb;
4503}
4504
4505void QSTestContext::End() {
4506 current_cb->end();
4507 current_cb = nullptr;
4508}
4509
4510VkBufferMemoryBarrier QSTestContext::InitBufferBarrier(const VkBufferObj& buffer) {
4511 auto buffer_barrier = LvlInitStruct<VkBufferMemoryBarrier>();
4512 buffer_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
4513 buffer_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
4514 buffer_barrier.buffer = buffer.handle();
4515 buffer_barrier.offset = 0;
4516 buffer_barrier.size = 256;
4517 return buffer_barrier;
4518}
4519
4520void QSTestContext::TransferBarrier(const VkBufferMemoryBarrier& buffer_barrier) {
4521 vk::CmdPipelineBarrier(current_cb->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1,
4522 &buffer_barrier, 0, nullptr);
4523}
4524
4525void QSTestContext::TransferBarrier(const VkBufferObj& buffer) { TransferBarrier(InitBufferBarrier(buffer)); }
4526
4527void QSTestContext::Submit(VkQueue q, VkCommandBufferObj& cb, VkSemaphore wait, VkPipelineStageFlags wait_mask,
4528 VkSemaphore signal) {
4529 auto submit1 = lvl_init_struct<VkSubmitInfo>();
4530 submit1.commandBufferCount = 1;
4531 VkCommandBuffer h_cb = cb.handle();
4532 submit1.pCommandBuffers = &h_cb;
4533 if (wait != VK_NULL_HANDLE) {
4534 submit1.waitSemaphoreCount = 1;
4535 submit1.pWaitSemaphores = &wait;
4536 submit1.pWaitDstStageMask = &wait_mask;
4537 }
4538 if (signal != VK_NULL_HANDLE) {
4539 submit1.signalSemaphoreCount = 1;
4540 submit1.pSignalSemaphores = &signal;
4541 }
4542 vk::QueueSubmit(q, 1, &submit1, VK_NULL_HANDLE);
4543}
4544
John Zulaufb9fad9f2022-07-15 11:10:37 -06004545TEST_F(VkSyncValTest, SyncQSBufferCopyHazards) {
4546 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework(true)); // Enable QueueSubmit validation
4547 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
4548
4549 VkBufferObj buffer_a;
4550 VkBufferObj buffer_b;
4551 VkBufferObj buffer_c;
4552 VkMemoryPropertyFlags mem_prop = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
4553 buffer_a.init_as_src_and_dst(*m_device, 256, mem_prop);
4554 buffer_b.init_as_src_and_dst(*m_device, 256, mem_prop);
4555 buffer_c.init_as_src_and_dst(*m_device, 256, mem_prop);
4556
4557 VkBufferCopy region = {0, 0, 256};
4558
4559 VkCommandBufferObj cba(m_device, m_commandPool);
4560 VkCommandBufferObj cbb(m_device, m_commandPool);
4561
4562 cba.begin();
4563 const VkCommandBuffer h_cba = cba.handle();
4564 vk::CmdCopyBuffer(h_cba, buffer_a.handle(), buffer_b.handle(), 1, &region);
4565 cba.end();
4566
4567 const VkCommandBuffer h_cbb = cbb.handle();
4568 cbb.begin();
4569 vk::CmdCopyBuffer(h_cbb, buffer_c.handle(), buffer_a.handle(), 1, &region);
4570 cbb.end();
4571
4572 auto submit1 = lvl_init_struct<VkSubmitInfo>();
4573 submit1.commandBufferCount = 2;
4574 VkCommandBuffer two_cbs[2] = {h_cba, h_cbb};
4575 submit1.pCommandBuffers = two_cbs;
4576
4577 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
4578 vk::QueueSubmit(m_device->m_queue, 1, &submit1, VK_NULL_HANDLE);
4579 m_errorMonitor->VerifyFound();
4580
4581 vk::DeviceWaitIdle(m_device->device());
4582
4583 VkSubmitInfo submit2[2] = {lvl_init_struct<VkSubmitInfo>(), lvl_init_struct<VkSubmitInfo>()};
4584 submit2[0].commandBufferCount = 1;
4585 submit2[0].pCommandBuffers = &h_cba;
4586 submit2[1].commandBufferCount = 1;
4587 submit2[1].pCommandBuffers = &h_cbb;
4588 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
4589 vk::QueueSubmit(m_device->m_queue, 2, submit2, VK_NULL_HANDLE);
4590 m_errorMonitor->VerifyFound();
4591
4592 // With the skip settings, the above QueueSubmit's didn't record, so we can treat the global queue contexts as empty
4593 submit1.commandBufferCount = 1;
4594 submit1.pCommandBuffers = &h_cba;
4595 // Submit A
4596 m_errorMonitor->ExpectSuccess();
4597 vk::QueueSubmit(m_device->m_queue, 1, &submit1, VK_NULL_HANDLE);
4598 m_errorMonitor->VerifyNotFound();
4599
4600 submit1.pCommandBuffers = &h_cbb;
4601 // Submit B -- which should conflict via the queue's "last batch"
4602 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
4603 vk::QueueSubmit(m_device->m_queue, 1, &submit1, VK_NULL_HANDLE);
4604 m_errorMonitor->VerifyFound();
4605}
4606
4607TEST_F(VkSyncValTest, SyncQSBufferCopyVsIdle) {
4608 // TODO (jzulauf)
John Zulaufc55f4702022-07-15 12:16:34 -06004609 // GTEST_SKIP() << "this test is causing a sporadic crash on nvidia 32b release. Skip until further investigation";
John Zulaufb9fad9f2022-07-15 11:10:37 -06004610
4611 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework(true)); // Enable QueueSubmit validation
4612 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
4613
John Zulaufb9fad9f2022-07-15 11:10:37 -06004614 m_errorMonitor->ExpectSuccess();
John Zulaufc55f4702022-07-15 12:16:34 -06004615 QSTestContext test(m_device, m_device->m_queue_obj);
4616 if (!test.Valid()) {
4617 GTEST_SKIP() << "Test requires a valid queue object.";
4618 }
John Zulaufb9fad9f2022-07-15 11:10:37 -06004619
John Zulaufc55f4702022-07-15 12:16:34 -06004620 test.BeginA();
4621 test.CopyAToB();
4622 test.End();
John Zulaufb9fad9f2022-07-15 11:10:37 -06004623
John Zulaufc55f4702022-07-15 12:16:34 -06004624 test.BeginB();
4625 test.CopyCToA();
4626 test.End();
John Zulaufb9fad9f2022-07-15 11:10:37 -06004627
4628 // Submit A
John Zulaufc55f4702022-07-15 12:16:34 -06004629 test.Submit0(test.cba);
John Zulaufb9fad9f2022-07-15 11:10:37 -06004630 m_errorMonitor->VerifyNotFound();
4631
4632 // Submit B which hazards vs. A
John Zulaufb9fad9f2022-07-15 11:10:37 -06004633 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
John Zulaufc55f4702022-07-15 12:16:34 -06004634 test.Submit0(test.cbb);
John Zulaufb9fad9f2022-07-15 11:10:37 -06004635 m_errorMonitor->VerifyFound();
4636
4637 // With the skip settings, the above QueueSubmit's didn't record, so we can treat the previous submit as not
4638 // having happened. So we'll try again with a device wait idle
4639 // Submit B again, but after idling, which should remove the hazard
4640 m_errorMonitor->ExpectSuccess();
John Zulaufc55f4702022-07-15 12:16:34 -06004641 test.DeviceWait();
4642 test.Submit0(test.cbb);
John Zulaufb9fad9f2022-07-15 11:10:37 -06004643 m_errorMonitor->VerifyNotFound();
4644
John Zulaufc55f4702022-07-15 12:16:34 -06004645 // Submit the same command again for another hazard
John Zulaufb9fad9f2022-07-15 11:10:37 -06004646 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
John Zulaufc55f4702022-07-15 12:16:34 -06004647 test.Submit0(test.cbb);
John Zulaufb9fad9f2022-07-15 11:10:37 -06004648 m_errorMonitor->VerifyFound();
4649
4650 // With the skip settings, the above QueueSubmit's didn't record, so we can treat the previous submit as not
4651 // having happened. So we'll try again with a queue wait idle
4652 // Submit B again, but after idling, which should remove the hazard
4653 m_errorMonitor->ExpectSuccess();
John Zulaufc55f4702022-07-15 12:16:34 -06004654 test.QueueWait0();
4655 test.Submit0(test.cbb);
John Zulaufb9fad9f2022-07-15 11:10:37 -06004656 m_errorMonitor->VerifyNotFound();
4657}
4658
John Zulaufb66ee052022-06-10 16:52:28 -06004659TEST_F(VkSyncValTest, SyncQSBufferCopyQSORules) {
4660 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework(true)); // Enable QueueSubmit validation
4661 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
4662
4663 QSTestContext test(m_device);
4664 if (!test.Valid()) {
John Zulauf6df2d5c2022-05-28 13:02:21 -06004665 printf("%s Test requires at least 2 TRANSFER capable queues in the same queue_family. Skipped.\n", kSkipPrefix);
4666 return;
4667 }
4668
John Zulauf6df2d5c2022-05-28 13:02:21 -06004669 m_errorMonitor->ExpectSuccess();
John Zulauf6df2d5c2022-05-28 13:02:21 -06004670
4671 // Command Buffer A reads froms buffer A and writes to buffer B
John Zulaufb66ee052022-06-10 16:52:28 -06004672 test.BeginA();
4673 test.CopyAToB();
4674 test.End();
John Zulauf6df2d5c2022-05-28 13:02:21 -06004675
4676 // Command Buffer B reads froms buffer C and writes to buffer A, but has a barrier to protect the write to A when
4677 // executed on the same queue, given that commands in "queue submission order" are within the first scope of the barrier.
John Zulaufb66ee052022-06-10 16:52:28 -06004678 test.BeginB();
John Zulauf6df2d5c2022-05-28 13:02:21 -06004679
4680 // Use the barrier to clean up the WAR, which will work for command buffers ealier in queue submission order, or with
4681 // correct semaphore operations between queues.
John Zulaufb66ee052022-06-10 16:52:28 -06004682 test.TransferBarrier(test.buffer_a);
4683 test.CopyCToA();
4684 test.End();
John Zulauf6df2d5c2022-05-28 13:02:21 -06004685
John Zulaufd060c3f2022-06-08 16:00:46 -06004686 // Command Buffer C does the same copy as B but without the barrier.
John Zulaufb66ee052022-06-10 16:52:28 -06004687 test.BeginC();
4688 test.CopyCToA();
4689 test.End();
John Zulaufd060c3f2022-06-08 16:00:46 -06004690
John Zulauf6df2d5c2022-05-28 13:02:21 -06004691 // Submit A and B on the same queue, to assure us the barrier *would* be sufficient given QSO
4692 // This is included in a "Sucess" section, just to verify CBA and CBB are set up correctly.
John Zulaufb66ee052022-06-10 16:52:28 -06004693 test.Submit0(test.cba);
4694 test.Submit0(test.cbb);
John Zulauf6df2d5c2022-05-28 13:02:21 -06004695 m_device->wait(); // DeviceWaitIdle, clearing the field for the next subcase
4696 m_errorMonitor->VerifyNotFound();
4697
4698 // Submit A and B on the different queues. Since no semaphore is used between the queues, CB B hazards asynchronously with,
4699 // CB A with A being read and written on independent queues.
4700 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE-RACING-READ");
John Zulaufb66ee052022-06-10 16:52:28 -06004701 test.Submit0(test.cba);
4702 test.Submit1(test.cbb);
John Zulauf6df2d5c2022-05-28 13:02:21 -06004703 m_errorMonitor->VerifyFound();
4704
4705 // Set up the semaphore for the next two cases
4706 m_errorMonitor->ExpectSuccess();
John Zulauf6df2d5c2022-05-28 13:02:21 -06004707
4708 m_device->wait();
4709 m_errorMonitor->VerifyNotFound();
4710
4711 // Submit A and B on the different queues, with an ineffectual semaphore. The wait mask is empty, thus nothing in CB B is in
4712 // the second excution scope of the waited signal.
4713 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
John Zulaufb66ee052022-06-10 16:52:28 -06004714 test.Submit0Signal(test.cba);
John Zulaufc55f4702022-07-15 12:16:34 -06004715 test.Submit1Wait(test.cbb, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT); // wait mask is BOTTOM, s.t. this is a wait-for-nothing.
John Zulauf6df2d5c2022-05-28 13:02:21 -06004716 m_errorMonitor->VerifyFound();
4717
4718 // The since second submit failed, it was skipped. So we can try again, without having to WaitDeviceIdle
4719 m_errorMonitor->ExpectSuccess();
John Zulaufb66ee052022-06-10 16:52:28 -06004720 // Include transfers in the second execution scope of the waited signal, s.t. the PipelineBarrier in CB B can chain with it.
4721 test.Submit1Wait(test.cbb, VK_PIPELINE_STAGE_TRANSFER_BIT); //
John Zulaufd060c3f2022-06-08 16:00:46 -06004722
4723 m_device->wait();
4724
4725 // Draw A and then C to verify the second access scope of the signal
John Zulaufb66ee052022-06-10 16:52:28 -06004726 test.Submit0Signal(test.cba);
4727 test.Submit1Wait(test.cbc, VK_PIPELINE_STAGE_TRANSFER_BIT);
John Zulaufd060c3f2022-06-08 16:00:46 -06004728
4729 m_device->wait();
4730
4731 // ... and again on the same queue
John Zulaufb66ee052022-06-10 16:52:28 -06004732 test.Submit0Signal(test.cba);
4733 test.Submit0Wait(test.cbc, VK_PIPELINE_STAGE_TRANSFER_BIT);
John Zulauf6df2d5c2022-05-28 13:02:21 -06004734 m_errorMonitor->VerifyNotFound();
4735}
John Zulaufb66ee052022-06-10 16:52:28 -06004736
4737TEST_F(VkSyncValTest, SyncQSBufferEvents) {
4738 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework(true)); // Enable QueueSubmit validation
4739 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
4740
4741 QSTestContext test(m_device);
4742 if (!test.Valid()) {
4743 printf("%s Test requires at least 2 TRANSFER capable queues in the same queue_family. Skipped.\n", kSkipPrefix);
4744 return;
4745 }
4746
4747 m_errorMonitor->ExpectSuccess();
4748 // Command Buffer A reads froms buffer A and writes to buffer B
4749 test.BeginA();
4750 test.CopyAToB();
4751 test.SetEvent(VK_PIPELINE_STAGE_TRANSFER_BIT);
4752 test.End();
4753
4754 // Command Buffer B reads froms buffer C and writes to buffer A, but has a wait to protect the write to A when
4755 // executed on the same queue, given that commands in "queue submission order" are within the first scope of the barrier.
4756 test.BeginB();
4757
4758 // Use the barrier to clean up the WAR, which will work for command buffers ealier in queue submission order, or with
4759 // correct semaphore operations between queues.
4760 test.WaitEventBufferTransfer(test.buffer_a, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
4761 test.CopyCToA();
4762 test.End();
4763
4764 // Command Buffer C merges the operations from A and B, to ensure the set/wait is correct.
4765 // reads froms buffer A and writes to buffer B
4766 // reads froms buffer C and writes to buffer A, but has a barrier to protect the write to A when
4767 test.BeginC();
4768 test.CopyAToB();
4769 test.SetEvent(VK_PIPELINE_STAGE_TRANSFER_BIT);
4770 test.WaitEventBufferTransfer(test.buffer_a, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
4771 test.CopyCToA();
4772 test.End();
4773
4774 test.Submit0(test.cba);
4775 test.Submit0(test.cbb);
4776
4777 // Ensure that the wait doesn't apply to async queues
4778 m_device->wait();
4779 test.Submit0(test.cba);
4780 m_errorMonitor->VerifyNotFound();
4781 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE-RACING-READ");
4782 test.Submit1(test.cbb);
4783 m_errorMonitor->VerifyFound();
4784
4785 // Ensure that the wait doesn't apply to access on other synchronized queues
4786 m_errorMonitor->ExpectSuccess();
4787 m_device->wait();
4788
4789 test.Submit0Signal(test.cba);
4790 m_errorMonitor->VerifyNotFound();
4791 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
John Zulaufc55f4702022-07-15 12:16:34 -06004792 test.Submit1Wait(test.cbb, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
John Zulaufb66ee052022-06-10 16:52:28 -06004793 m_errorMonitor->VerifyFound();
4794
4795 // Need to have a successful signal wait to get the semaphore in a usuable state.
4796 m_errorMonitor->ExpectSuccess();
4797 test.BeginC();
4798 test.End();
John Zulaufc55f4702022-07-15 12:16:34 -06004799 test.Submit1Wait(test.cbc, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
John Zulaufb66ee052022-06-10 16:52:28 -06004800 m_device->wait();
4801
4802 // Next ensure that accesses from other queues aren't included in the first scope
4803 test.BeginA();
4804 test.CopyAToB();
4805 test.End();
4806
4807 test.BeginB();
4808 test.SetEvent(VK_PIPELINE_STAGE_TRANSFER_BIT);
4809 test.WaitEventBufferTransfer(test.buffer_a, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
4810 test.CopyCToA();
4811 test.End();
4812
4813 test.Submit0Signal(test.cba);
4814 m_errorMonitor->VerifyNotFound();
4815 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
John Zulaufc55f4702022-07-15 12:16:34 -06004816 test.Submit1Wait(test.cbb, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
John Zulaufb66ee052022-06-10 16:52:28 -06004817 m_errorMonitor->VerifyFound();
4818}
John Zulauf46f5d6b2022-06-30 12:38:34 -06004819
4820TEST_F(VkSyncValTest, SyncQSOBarrierHazard) {
4821 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework(true)); // Enable QueueSubmit validation
4822 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
4823
4824 QSTestContext test(m_device);
4825 if (!test.Valid()) {
4826 GTEST_SKIP() << "Test requires at least 2 TRANSFER capable queues in the same queue_family.";
4827 }
4828
4829 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
4830 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
4831 auto image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 1, format, usage, VK_IMAGE_TILING_OPTIMAL);
4832
4833 VkImageObj image_a(m_device);
4834 image_a.Init(image_ci);
4835 ASSERT_TRUE(image_a.initialized());
4836 image_a.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
4837
4838 VkImageObj image_b(m_device);
4839 image_b.Init(image_ci);
4840 ASSERT_TRUE(image_b.initialized());
4841 image_b.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
4842
4843 VkImageSubresourceLayers all_layers{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
4844 VkOffset3D zero_offset{0, 0, 0};
4845 VkExtent3D full_extent{128, 128, 1}; // <-- image type is 2D
4846 VkImageCopy full_region = {all_layers, zero_offset, all_layers, zero_offset, full_extent};
4847
4848 test.BeginA();
4849 test.CopyGeneral(image_a, image_b, full_region);
4850 test.End();
4851
4852 test.BeginB();
4853 image_a.ImageMemoryBarrier(test.current_cb, VK_IMAGE_ASPECT_COLOR_BIT, VK_ACCESS_NONE, VK_ACCESS_NONE,
John Zulaufc55f4702022-07-15 12:16:34 -06004854 VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT,
4855 VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
John Zulauf46f5d6b2022-06-30 12:38:34 -06004856 test.End();
4857
4858 // We're going to do the copy first, then use the skip on fail, to test three different ways...
4859 test.Submit0Signal(test.cba);
4860
4861 // First asynchronously fail -- the pipeline barrier in B shouldn't work on queue 1
4862 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE-RACING-READ ");
4863 test.Submit1(test.cbb);
4864 m_errorMonitor->VerifyFound();
4865
4866 // Next synchronously fail -- the pipeline barrier in B shouldn't work on queue 1
4867 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
John Zulaufc55f4702022-07-15 12:16:34 -06004868 test.Submit1Wait(test.cbb, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
John Zulauf46f5d6b2022-06-30 12:38:34 -06004869 m_errorMonitor->VerifyFound();
4870
4871 // Then prove qso works (note that with the failure, the semaphore hasn't been waited, nor the layout changed)
4872 m_errorMonitor->ExpectSuccess();
John Zulaufc55f4702022-07-15 12:16:34 -06004873 test.Submit0Wait(test.cbb, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
John Zulauf46f5d6b2022-06-30 12:38:34 -06004874 m_errorMonitor->VerifyNotFound();
4875}