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