blob: 1629014e32d1ce7325b3b443fb40ee1b5a89698e [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
141 // CmdWriteBufferMarkerAMD
142 if (has_amd_buffer_maker) {
143 auto fpCmdWriteBufferMarkerAMD =
144 (PFN_vkCmdWriteBufferMarkerAMD)vk::GetDeviceProcAddr(m_device->device(), "vkCmdWriteBufferMarkerAMD");
145 if (!fpCmdWriteBufferMarkerAMD) {
146 printf("%s Test requires unsupported vkCmdWriteBufferMarkerAMD feature. Skipped.\n", kSkipPrefix);
147 } else {
148 m_errorMonitor->ExpectSuccess();
149 m_commandBuffer->reset();
150 m_commandBuffer->begin();
151 fpCmdWriteBufferMarkerAMD(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, buffer_a.handle(), 0, 1);
152 m_commandBuffer->end();
153 m_errorMonitor->VerifyNotFound();
154
155 m_commandBuffer->reset();
156 m_commandBuffer->begin();
157 vk::CmdCopyBuffer(cb, buffer_b.handle(), buffer_a.handle(), 1, &region);
158 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
159 fpCmdWriteBufferMarkerAMD(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, buffer_a.handle(), 0, 1);
160 m_errorMonitor->VerifyFound();
161 m_commandBuffer->end();
162 }
163 } else {
164 printf("%s Test requires unsupported vkCmdWriteBufferMarkerAMD feature. Skipped.\n", kSkipPrefix);
165 }
166}
167
Jeremy Gebben5c1bb2d2021-02-15 08:58:04 -0700168TEST_F(VkSyncValTest, Sync2BufferCopyHazards) {
169 SetTargetApiVersion(VK_API_VERSION_1_2);
170 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
171 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME)) {
172 m_device_extension_names.push_back(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME);
173 } else {
174 printf("%s Synchronization2 not supported, skipping test\n", kSkipPrefix);
175 return;
176 }
177
178 if (!CheckSynchronization2SupportAndInitState(this)) {
179 printf("%s Synchronization2 not supported, skipping test\n", kSkipPrefix);
180 return;
181 }
182 auto fpCmdPipelineBarrier2KHR = (PFN_vkCmdPipelineBarrier2KHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdPipelineBarrier2KHR");
183
184 VkBufferObj buffer_a;
185 VkBufferObj buffer_b;
186 VkBufferObj buffer_c;
187 VkMemoryPropertyFlags mem_prop = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
188 buffer_a.init_as_src_and_dst(*m_device, 256, mem_prop);
189 buffer_b.init_as_src_and_dst(*m_device, 256, mem_prop);
190 buffer_c.init_as_src_and_dst(*m_device, 256, mem_prop);
191
192 VkBufferCopy region = {0, 0, 256};
193 VkBufferCopy front2front = {0, 0, 128};
194 VkBufferCopy front2back = {0, 128, 128};
195 VkBufferCopy back2back = {128, 128, 128};
196
197 auto cb = m_commandBuffer->handle();
198 m_commandBuffer->begin();
199
200 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &region);
201
202 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
203 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &region);
204 m_errorMonitor->VerifyFound();
205
206 // Use the barrier to clean up the WAW, and try again. (and show that validation is accounting for the barrier effect too.)
207 {
208 auto buffer_barrier = lvl_init_struct<VkBufferMemoryBarrier2KHR>();
209 buffer_barrier.srcStageMask = VK_PIPELINE_STAGE_2_COPY_BIT_KHR;
210 buffer_barrier.dstStageMask = VK_PIPELINE_STAGE_2_COPY_BIT_KHR;
211 buffer_barrier.srcAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT_KHR;
212 buffer_barrier.dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR;
213 buffer_barrier.buffer = buffer_a.handle();
214 buffer_barrier.offset = 0;
215 buffer_barrier.size = 256;
216 auto dep_info = lvl_init_struct<VkDependencyInfoKHR>();
217 dep_info.bufferMemoryBarrierCount = 1;
218 dep_info.pBufferMemoryBarriers = &buffer_barrier;
219 fpCmdPipelineBarrier2KHR(cb, &dep_info);
220 }
221
222 m_errorMonitor->ExpectSuccess();
223 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &front2front);
224 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &back2back);
225 m_errorMonitor->VerifyNotFound();
226
227 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
228 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &front2back);
229 m_errorMonitor->VerifyFound();
230
231 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
232 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_b.handle(), 1, &region);
233 m_errorMonitor->VerifyFound();
234
235 // NOTE: Since the previous command skips in validation, the state update is never done, and the validation layer thus doesn't
236 // record the write operation to b. So we'll need to repeat it successfully to set up for the *next* test.
237
238 // Use the barrier to clean up the WAW, and try again. (and show that validation is accounting for the barrier effect too.)
239 {
240 auto mem_barrier = lvl_init_struct<VkMemoryBarrier2KHR>();
241 mem_barrier.srcStageMask = VK_PIPELINE_STAGE_2_COPY_BIT_KHR;
242 mem_barrier.dstStageMask = VK_PIPELINE_STAGE_2_COPY_BIT_KHR;
243 mem_barrier.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR;
244 mem_barrier.dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR;
245 auto dep_info = lvl_init_struct<VkDependencyInfoKHR>();
246 dep_info.memoryBarrierCount = 1;
247 dep_info.pMemoryBarriers = &mem_barrier;
248 fpCmdPipelineBarrier2KHR(cb, &dep_info);
249 m_errorMonitor->ExpectSuccess();
250
251 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_c.handle(), buffer_b.handle(), 1, &region);
252 m_errorMonitor->VerifyNotFound();
253
254 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
255 mem_barrier.srcAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT_KHR; // Protect C but not B
256 mem_barrier.dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR;
257 fpCmdPipelineBarrier2KHR(cb, &dep_info);
258 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_b.handle(), buffer_c.handle(), 1, &region);
259 m_errorMonitor->VerifyFound();
260
261 m_commandBuffer->end();
262 }
263}
264
Jeremy Gebben170781d2020-11-19 16:21:21 -0700265TEST_F(VkSyncValTest, SyncCopyOptimalImageHazards) {
266 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
267 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
268
269 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
270 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
271 VkImageObj image_a(m_device);
272 auto image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 2, format, usage, VK_IMAGE_TILING_OPTIMAL);
273 image_a.Init(image_ci);
274 ASSERT_TRUE(image_a.initialized());
275
276 VkImageObj image_b(m_device);
277 image_b.Init(image_ci);
278 ASSERT_TRUE(image_b.initialized());
279
280 VkImageObj image_c(m_device);
281 image_c.Init(image_ci);
282 ASSERT_TRUE(image_c.initialized());
283
284 VkImageSubresourceLayers layers_all{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 2};
285 VkImageSubresourceLayers layers_0{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
286 VkImageSubresourceLayers layers_1{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1};
287 VkImageSubresourceRange full_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 2};
288 VkOffset3D zero_offset{0, 0, 0};
289 VkOffset3D half_offset{64, 64, 0};
290 VkExtent3D full_extent{128, 128, 1}; // <-- image type is 2D
291 VkExtent3D half_extent{64, 64, 1}; // <-- image type is 2D
292
293 VkImageCopy full_region = {layers_all, zero_offset, layers_all, zero_offset, full_extent};
294 VkImageCopy region_0_to_0 = {layers_0, zero_offset, layers_0, zero_offset, full_extent};
295 VkImageCopy region_0_to_1 = {layers_0, zero_offset, layers_1, zero_offset, full_extent};
296 VkImageCopy region_1_to_1 = {layers_1, zero_offset, layers_1, zero_offset, full_extent};
297 VkImageCopy region_0_front = {layers_0, zero_offset, layers_0, zero_offset, half_extent};
298 VkImageCopy region_0_back = {layers_0, half_offset, layers_0, half_offset, half_extent};
299
300 m_commandBuffer->begin();
301
302 image_c.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
303 image_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
304 image_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
305
306 auto cb = m_commandBuffer->handle();
307
308 vk::CmdCopyImage(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
309
310 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
311 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
312 m_errorMonitor->VerifyFound();
313
314 // 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 -0700315 auto image_barrier = LvlInitStruct<VkImageMemoryBarrier>();
Jeremy Gebben170781d2020-11-19 16:21:21 -0700316 image_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
317 image_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
318 image_barrier.image = image_a.handle();
319 image_barrier.subresourceRange = full_subresource_range;
320 image_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
321 image_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
322 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1,
323 &image_barrier);
324
325 m_errorMonitor->ExpectSuccess();
326 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_0_to_0);
327 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_1_to_1);
328 m_errorMonitor->VerifyNotFound();
329
330 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
331 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_0_to_1);
332 m_errorMonitor->VerifyFound();
333
334 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
335 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
336 m_errorMonitor->VerifyFound();
337
338 // NOTE: Since the previous command skips in validation, the state update is never done, and the validation layer thus doesn't
339 // record the write operation to b. So we'll need to repeat it successfully to set up for the *next* test.
340
341 // 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 -0700342 auto mem_barrier = LvlInitStruct<VkMemoryBarrier>();
Jeremy Gebben170781d2020-11-19 16:21:21 -0700343 mem_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
344 mem_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
345 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1, &mem_barrier, 0, nullptr, 0,
346 nullptr);
347 m_errorMonitor->ExpectSuccess();
348 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
349 m_errorMonitor->VerifyNotFound();
350
351 // Use barrier to protect last reader, but not last writer...
352 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
353 mem_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; // Protects C but not B
354 mem_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
355 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1, &mem_barrier, 0, nullptr, 0,
356 nullptr);
357 vk::CmdCopyImage(cb, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
358 m_errorMonitor->VerifyFound();
359
360 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_0_front);
361 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
362 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_0_front);
363 m_errorMonitor->VerifyFound();
364
365 m_errorMonitor->ExpectSuccess();
366 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_0_back);
367 m_errorMonitor->VerifyNotFound();
368
369 m_commandBuffer->end();
370
371 // CmdResolveImage
372 VkImageFormatProperties formProps = {{0, 0, 0}, 0, 0, 0, 0};
373 vk::GetPhysicalDeviceImageFormatProperties(m_device->phy().handle(), VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TYPE_2D,
374 VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 0, &formProps);
375
376 if (!(formProps.sampleCounts & VK_SAMPLE_COUNT_2_BIT)) {
377 printf("%s CmdResolveImage Test requires unsupported VK_SAMPLE_COUNT_2_BIT feature. Skipped.\n", kSkipPrefix);
378 } else {
379 m_errorMonitor->ExpectSuccess();
380 VkImageObj image_s2_a(m_device), image_s2_b(m_device);
381 image_ci.samples = VK_SAMPLE_COUNT_2_BIT;
382 image_s2_a.Init(image_ci);
383 ASSERT_TRUE(image_s2_a.initialized());
384
385 image_s2_b.Init(image_ci);
386 ASSERT_TRUE(image_s2_b.initialized());
387
388 VkImageResolve r_full_region = {layers_all, zero_offset, layers_all, zero_offset, full_extent};
389
390 m_commandBuffer->reset();
391 m_commandBuffer->begin();
392 image_s2_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
393 image_s2_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
394 vk::CmdResolveImage(cb, image_s2_a.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
395 &r_full_region);
396 m_commandBuffer->end();
397 m_errorMonitor->VerifyNotFound();
398
399 m_commandBuffer->reset();
400 m_commandBuffer->begin();
401 vk::CmdCopyImage(cb, image_s2_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_s2_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
402 &full_region);
403 vk::CmdCopyImage(cb, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
404
405 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
406 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
407 vk::CmdResolveImage(cb, image_s2_a.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
408 &r_full_region);
409 m_errorMonitor->VerifyFound();
410
411 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
412 vk::CmdResolveImage(cb, image_s2_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
413 &r_full_region);
414 m_errorMonitor->VerifyFound();
415 m_commandBuffer->end();
416 }
417}
418
Jeremy Gebben5c1bb2d2021-02-15 08:58:04 -0700419TEST_F(VkSyncValTest, Sync2CopyOptimalImageHazards) {
420 SetTargetApiVersion(VK_API_VERSION_1_2);
421 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
422 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME)) {
423 m_device_extension_names.push_back(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME);
424 } else {
425 printf("%s Synchronization2 not supported, skipping test\n", kSkipPrefix);
426 return;
427 }
428
429 if (!CheckSynchronization2SupportAndInitState(this)) {
430 printf("%s Synchronization2 not supported, skipping test\n", kSkipPrefix);
431 return;
432 }
433 auto fpCmdPipelineBarrier2KHR = (PFN_vkCmdPipelineBarrier2KHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdPipelineBarrier2KHR");
434
435 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
436 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
437 VkImageObj image_a(m_device);
438 auto image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 2, format, usage, VK_IMAGE_TILING_OPTIMAL);
439 image_a.Init(image_ci);
440 ASSERT_TRUE(image_a.initialized());
441
442 VkImageObj image_b(m_device);
443 image_b.Init(image_ci);
444 ASSERT_TRUE(image_b.initialized());
445
446 VkImageObj image_c(m_device);
447 image_c.Init(image_ci);
448 ASSERT_TRUE(image_c.initialized());
449
450 VkImageSubresourceLayers layers_all{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 2};
451 VkImageSubresourceLayers layers_0{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
452 VkImageSubresourceLayers layers_1{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1};
453 VkImageSubresourceRange full_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 2};
454 VkOffset3D zero_offset{0, 0, 0};
455 VkOffset3D half_offset{64, 64, 0};
456 VkExtent3D full_extent{128, 128, 1}; // <-- image type is 2D
457 VkExtent3D half_extent{64, 64, 1}; // <-- image type is 2D
458
459 VkImageCopy full_region = {layers_all, zero_offset, layers_all, zero_offset, full_extent};
460 VkImageCopy region_0_to_0 = {layers_0, zero_offset, layers_0, zero_offset, full_extent};
461 VkImageCopy region_0_to_1 = {layers_0, zero_offset, layers_1, zero_offset, full_extent};
462 VkImageCopy region_1_to_1 = {layers_1, zero_offset, layers_1, zero_offset, full_extent};
463 VkImageCopy region_0_front = {layers_0, zero_offset, layers_0, zero_offset, half_extent};
464 VkImageCopy region_0_back = {layers_0, half_offset, layers_0, half_offset, half_extent};
465
466 m_commandBuffer->begin();
467
468 image_c.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
469 image_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
470 image_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
471
472 auto cb = m_commandBuffer->handle();
473
474 vk::CmdCopyImage(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
475
476 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
477 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
478 m_errorMonitor->VerifyFound();
479
480 // Use the barrier to clean up the WAW, and try again. (and show that validation is accounting for the barrier effect too.)
481 {
482 auto image_barrier = lvl_init_struct<VkImageMemoryBarrier2KHR>();
483 image_barrier.srcStageMask = VK_PIPELINE_STAGE_2_COPY_BIT_KHR;
484 image_barrier.dstStageMask = VK_PIPELINE_STAGE_2_COPY_BIT_KHR;
485 image_barrier.srcAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT_KHR;
486 image_barrier.dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR;
487 image_barrier.image = image_a.handle();
488 image_barrier.subresourceRange = full_subresource_range;
489 image_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
490 image_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
491 auto dep_info = lvl_init_struct<VkDependencyInfoKHR>();
492 dep_info.imageMemoryBarrierCount = 1;
493 dep_info.pImageMemoryBarriers = &image_barrier;
494 fpCmdPipelineBarrier2KHR(cb, &dep_info);
495 }
496
497 m_errorMonitor->ExpectSuccess();
498 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_0_to_0);
499 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_1_to_1);
500 m_errorMonitor->VerifyNotFound();
501
502 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
503 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_0_to_1);
504 m_errorMonitor->VerifyFound();
505
506 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
507 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
508 m_errorMonitor->VerifyFound();
509
510 // NOTE: Since the previous command skips in validation, the state update is never done, and the validation layer thus doesn't
511 // record the write operation to b. So we'll need to repeat it successfully to set up for the *next* test.
512
513 // Use the barrier to clean up the WAW, and try again. (and show that validation is accounting for the barrier effect too.)
514 {
515 auto mem_barrier = lvl_init_struct<VkMemoryBarrier2KHR>();
516 mem_barrier.srcStageMask = VK_PIPELINE_STAGE_2_COPY_BIT_KHR;
517 mem_barrier.dstStageMask = VK_PIPELINE_STAGE_2_COPY_BIT_KHR;
518 mem_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
519 mem_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
520 auto dep_info = lvl_init_struct<VkDependencyInfoKHR>();
521 dep_info.memoryBarrierCount = 1;
522 dep_info.pMemoryBarriers = &mem_barrier;
523 fpCmdPipelineBarrier2KHR(cb, &dep_info);
524 m_errorMonitor->ExpectSuccess();
525 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
526 m_errorMonitor->VerifyNotFound();
527
528 // Use barrier to protect last reader, but not last writer...
529 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
530 mem_barrier.srcAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT_KHR; // Protects C but not B
531 mem_barrier.dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR;
532 fpCmdPipelineBarrier2KHR(cb, &dep_info);
533 vk::CmdCopyImage(cb, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
534 m_errorMonitor->VerifyFound();
535 }
536
537 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_0_front);
538 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
539 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_0_front);
540 m_errorMonitor->VerifyFound();
541
542 m_errorMonitor->ExpectSuccess();
543 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_0_back);
544 m_errorMonitor->VerifyNotFound();
545
546 m_commandBuffer->end();
547}
548
Jeremy Gebben170781d2020-11-19 16:21:21 -0700549TEST_F(VkSyncValTest, SyncCopyOptimalMultiPlanarHazards) {
550 // TODO: Add code to enable sync validation
551 // Enable KHR multiplane req'd extensions
552 bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
553 VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION);
554 if (mp_extensions) {
555 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
556 }
557 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
558 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
559 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
560 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
561 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
562 if (mp_extensions) {
563 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
564 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
565 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
566 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
567 } else {
568 printf("%s test requires KHR multiplane extensions, not available. Skipping.\n", kSkipPrefix);
569 return;
570 }
571
572 ASSERT_NO_FATAL_FAILURE(InitState());
573
574 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
575 VkFormat format = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM;
576 VkImageObj image_a(m_device);
577 const auto image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 2, format, usage, VK_IMAGE_TILING_OPTIMAL);
578 // Verify format
579 bool supported = ImageFormatAndFeaturesSupported(instance(), gpu(), image_ci,
580 VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT);
581 if (!supported) {
582 printf("%s Multiplane image format not supported. Skipping test.\n", kSkipPrefix);
583 return; // Assume there's low ROI on searching for different mp formats
584 }
585
586 image_a.Init(image_ci);
587 VkImageObj image_b(m_device);
588 image_b.Init(image_ci);
589 VkImageObj image_c(m_device);
590 image_c.Init(image_ci);
591
592 VkImageSubresourceLayers layer_all_plane0{VK_IMAGE_ASPECT_PLANE_0_BIT_KHR, 0, 0, 2};
593 VkImageSubresourceLayers layer0_plane0{VK_IMAGE_ASPECT_PLANE_0_BIT_KHR, 0, 0, 1};
594 VkImageSubresourceLayers layer0_plane1{VK_IMAGE_ASPECT_PLANE_1_BIT_KHR, 0, 0, 1};
595 VkImageSubresourceLayers layer1_plane1{VK_IMAGE_ASPECT_PLANE_1_BIT_KHR, 0, 1, 1};
596 VkImageSubresourceRange full_subresource_range{
597 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};
598 VkOffset3D zero_offset{0, 0, 0};
599 VkOffset3D one_four_offset{32, 32, 0};
600 VkExtent3D full_extent{128, 128, 1}; // <-- image type is 2D
601 VkExtent3D half_extent{64, 64, 1}; // <-- image type is 2D
602 VkExtent3D one_four_extent{32, 32, 1}; // <-- image type is 2D
603
604 VkImageCopy region_all_plane0_to_all_plane0 = {layer_all_plane0, zero_offset, layer_all_plane0, zero_offset, full_extent};
605 VkImageCopy region_layer0_plane0_to_layer0_plane0 = {layer0_plane0, zero_offset, layer0_plane0, zero_offset, full_extent};
606 VkImageCopy region_layer0_plane0_to_layer0_plane1 = {layer0_plane0, zero_offset, layer0_plane1, zero_offset, half_extent};
607 VkImageCopy region_layer1_plane1_to_layer1_plane1_front = {layer1_plane1, zero_offset, layer1_plane1, zero_offset,
608 one_four_extent};
609 VkImageCopy region_layer1_plane1_to_layer1_plane1_back = {layer1_plane1, one_four_offset, layer1_plane1, one_four_offset,
610 one_four_extent};
611
612 m_commandBuffer->begin();
613
614 image_c.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
615 image_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
616 image_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
617
618 auto cb = m_commandBuffer->handle();
619
620 vk::CmdCopyImage(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
621 &region_all_plane0_to_all_plane0);
622
623 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
624 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
625 &region_all_plane0_to_all_plane0);
626 m_errorMonitor->VerifyFound();
627
628 // 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 -0700629 auto image_barrier = LvlInitStruct<VkImageMemoryBarrier>();
Jeremy Gebben170781d2020-11-19 16:21:21 -0700630 image_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
631 image_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
632 image_barrier.image = image_a.handle();
633 image_barrier.subresourceRange = full_subresource_range;
634 image_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
635 image_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
636 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1,
637 &image_barrier);
638
639 m_errorMonitor->ExpectSuccess();
640 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
641 &region_layer0_plane0_to_layer0_plane0);
642 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
643 &region_layer0_plane0_to_layer0_plane1);
644 m_errorMonitor->VerifyNotFound();
645
646 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
647 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
648 &region_layer0_plane0_to_layer0_plane1);
649 m_errorMonitor->VerifyFound();
650
651 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
652 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
653 &region_all_plane0_to_all_plane0);
654 m_errorMonitor->VerifyFound();
655
656 // NOTE: Since the previous command skips in validation, the state update is never done, and the validation layer thus doesn't
657 // record the write operation to b. So we'll need to repeat it successfully to set up for the *next* test.
658
659 // 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 -0700660 auto mem_barrier = LvlInitStruct<VkMemoryBarrier>();
Jeremy Gebben170781d2020-11-19 16:21:21 -0700661 mem_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
662 mem_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
663 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1, &mem_barrier, 0, nullptr, 0,
664 nullptr);
665 m_errorMonitor->ExpectSuccess();
666 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
667 &region_all_plane0_to_all_plane0);
668 m_errorMonitor->VerifyNotFound();
669
670 // Use barrier to protect last reader, but not last writer...
671 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
672 mem_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; // Protects C but not B
673 mem_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
674 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1, &mem_barrier, 0, nullptr, 0,
675 nullptr);
676 vk::CmdCopyImage(cb, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
677 &region_all_plane0_to_all_plane0);
678 m_errorMonitor->VerifyFound();
679
680 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
681 &region_layer1_plane1_to_layer1_plane1_front);
682 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
683 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
684 &region_layer1_plane1_to_layer1_plane1_front);
685 m_errorMonitor->VerifyFound();
686
687 m_errorMonitor->ExpectSuccess();
688 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
689 &region_layer1_plane1_to_layer1_plane1_back);
690 m_errorMonitor->VerifyNotFound();
691
692 m_commandBuffer->end();
693}
694
695TEST_F(VkSyncValTest, SyncCopyLinearImageHazards) {
696 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
697 ASSERT_NO_FATAL_FAILURE(InitState());
698
699 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
700 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
701 VkImageObj image_a(m_device);
702 const auto image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 1, format, usage, VK_IMAGE_TILING_LINEAR);
703 image_a.Init(image_ci);
704 VkImageObj image_b(m_device);
705 image_b.Init(image_ci);
706 VkImageObj image_c(m_device);
707 image_c.Init(image_ci);
708
709 VkImageSubresourceLayers layers_all{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
710 VkImageSubresourceRange full_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
711 VkOffset3D zero_offset{0, 0, 0};
712 VkOffset3D half_offset{64, 64, 0};
713 VkExtent3D full_extent{128, 128, 1}; // <-- image type is 2D
714 VkExtent3D half_extent{64, 64, 1}; // <-- image type is 2D
715
716 VkImageCopy full_region = {layers_all, zero_offset, layers_all, zero_offset, full_extent};
717 VkImageCopy region_front = {layers_all, zero_offset, layers_all, zero_offset, half_extent};
718 VkImageCopy region_back = {layers_all, half_offset, layers_all, half_offset, half_extent};
719
720 m_commandBuffer->begin();
721
722 image_c.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
723 image_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
724 image_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
725
726 auto cb = m_commandBuffer->handle();
727
728 vk::CmdCopyImage(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
729
730 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
731 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
732 m_errorMonitor->VerifyFound();
733
734 // 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 -0700735 auto image_barrier = LvlInitStruct<VkImageMemoryBarrier>();
Jeremy Gebben170781d2020-11-19 16:21:21 -0700736 image_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
737 image_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
738 image_barrier.image = image_b.handle();
739 image_barrier.subresourceRange = full_subresource_range;
740 image_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
741 image_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
742 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1,
743 &image_barrier);
744
745 m_errorMonitor->ExpectSuccess();
746 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
747 m_errorMonitor->VerifyNotFound();
748
749 // Use barrier to protect last reader, but not last writer...
750 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
751 image_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; // Protects C but not B
752 image_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
753 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1,
754 &image_barrier);
755 vk::CmdCopyImage(cb, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
756 m_errorMonitor->VerifyFound();
757
758 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_front);
759 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
760 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_front);
761 m_errorMonitor->VerifyFound();
762
763 m_errorMonitor->ExpectSuccess();
764 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_back);
765 m_errorMonitor->VerifyNotFound();
766}
767
768TEST_F(VkSyncValTest, SyncCopyLinearMultiPlanarHazards) {
769 // TODO: Add code to enable sync validation
770 // Enable KHR multiplane req'd extensions
771 bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
772 VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION);
773 if (mp_extensions) {
774 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
775 }
776 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
777 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
778 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
779 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
780 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
781 if (mp_extensions) {
782 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
783 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
784 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
785 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
786 } else {
787 printf("%s test requires KHR multiplane extensions, not available. Skipping.\n", kSkipPrefix);
788 return;
789 }
790
791 ASSERT_NO_FATAL_FAILURE(InitState());
792
793 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
794 VkFormat format = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM;
795 VkImageObj image_a(m_device);
796 const auto image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 1, format, usage, VK_IMAGE_TILING_LINEAR);
797 // Verify format
798 bool supported = ImageFormatAndFeaturesSupported(instance(), gpu(), image_ci,
799 VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT);
800 if (!supported) {
801 printf("%s Multiplane image format not supported. Skipping test.\n", kSkipPrefix);
802 return; // Assume there's low ROI on searching for different mp formats
803 }
804
805 image_a.Init(image_ci);
806 VkImageObj image_b(m_device);
807 image_b.Init(image_ci);
808 VkImageObj image_c(m_device);
809 image_c.Init(image_ci);
810
811 VkImageSubresourceLayers layer_all_plane0{VK_IMAGE_ASPECT_PLANE_0_BIT_KHR, 0, 0, 1};
812 VkImageSubresourceLayers layer_all_plane1{VK_IMAGE_ASPECT_PLANE_1_BIT_KHR, 0, 0, 1};
813 VkImageSubresourceRange full_subresource_range{
814 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};
815 VkOffset3D zero_offset{0, 0, 0};
816 VkOffset3D one_four_offset{32, 32, 0};
817 VkExtent3D full_extent{128, 128, 1}; // <-- image type is 2D
818 VkExtent3D half_extent{64, 64, 1}; // <-- image type is 2D
819 VkExtent3D one_four_extent{32, 32, 1}; // <-- image type is 2D
820
821 VkImageCopy region_plane0_to_plane0 = {layer_all_plane0, zero_offset, layer_all_plane0, zero_offset, full_extent};
822 VkImageCopy region_plane0_to_plane1 = {layer_all_plane0, zero_offset, layer_all_plane1, zero_offset, half_extent};
823 VkImageCopy region_plane1_to_plane1_front = {layer_all_plane1, zero_offset, layer_all_plane1, zero_offset, one_four_extent};
824 VkImageCopy region_plane1_to_plane1_back = {layer_all_plane1, one_four_offset, layer_all_plane1, one_four_offset,
825 one_four_extent};
826
827 m_commandBuffer->begin();
828
829 image_c.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
830 image_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
831 image_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
832
833 auto cb = m_commandBuffer->handle();
834
835 vk::CmdCopyImage(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
836 &region_plane0_to_plane0);
837
838 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
839 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
840 &region_plane0_to_plane0);
841 m_errorMonitor->VerifyFound();
842
843 // 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 -0700844 auto image_barrier = LvlInitStruct<VkImageMemoryBarrier>();
Jeremy Gebben170781d2020-11-19 16:21:21 -0700845 image_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
846 image_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
847 image_barrier.image = image_a.handle();
848 image_barrier.subresourceRange = full_subresource_range;
849 image_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
850 image_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
851 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1,
852 &image_barrier);
853
854 m_errorMonitor->ExpectSuccess();
855 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
856 &region_plane0_to_plane0);
857 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
858 &region_plane0_to_plane1);
859 m_errorMonitor->VerifyNotFound();
860
861 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
862 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
863 &region_plane0_to_plane1);
864 m_errorMonitor->VerifyFound();
865
866 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
867 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
868 &region_plane0_to_plane0);
869 m_errorMonitor->VerifyFound();
870
871 // NOTE: Since the previous command skips in validation, the state update is never done, and the validation layer thus doesn't
872 // record the write operation to b. So we'll need to repeat it successfully to set up for the *next* test.
873
874 // 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 -0700875 auto mem_barrier = LvlInitStruct<VkMemoryBarrier>();
Jeremy Gebben170781d2020-11-19 16:21:21 -0700876 mem_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
877 mem_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
878 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1, &mem_barrier, 0, nullptr, 0,
879 nullptr);
880 m_errorMonitor->ExpectSuccess();
881 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
882 &region_plane0_to_plane0);
883 m_errorMonitor->VerifyNotFound();
884
885 // Use barrier to protect last reader, but not last writer...
886 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
887 mem_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; // Protects C but not B
888 mem_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
889 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1, &mem_barrier, 0, nullptr, 0,
890 nullptr);
891 vk::CmdCopyImage(cb, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
892 &region_plane0_to_plane0);
893 m_errorMonitor->VerifyFound();
894
895 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
896 &region_plane1_to_plane1_front);
897 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
898 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
899 &region_plane1_to_plane1_front);
900 m_errorMonitor->VerifyFound();
901
902 m_errorMonitor->ExpectSuccess();
903 vk::CmdCopyImage(cb, image_c.handle(), VK_IMAGE_LAYOUT_GENERAL, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
904 &region_plane1_to_plane1_back);
905 m_errorMonitor->VerifyNotFound();
906
907 m_commandBuffer->end();
908}
909
910TEST_F(VkSyncValTest, SyncCopyBufferImageHazards) {
911 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
912 ASSERT_NO_FATAL_FAILURE(InitState());
913
914 VkBufferObj buffer_a, buffer_b;
915 VkMemoryPropertyFlags mem_prop = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
916 buffer_a.init_as_src_and_dst(*m_device, 2048, mem_prop);
917 buffer_b.init_as_src_and_dst(*m_device, 2048, mem_prop);
918
919 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
920 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
921 VkImageObj image_a(m_device), image_b(m_device);
922 const auto image_ci = VkImageObj::ImageCreateInfo2D(32, 32, 1, 2, format, usage, VK_IMAGE_TILING_OPTIMAL);
923 image_a.Init(image_ci);
924 image_b.Init(image_ci);
925
926 VkImageSubresourceLayers layers_0{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
927 VkImageSubresourceLayers layers_1{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1};
928 VkOffset3D zero_offset{0, 0, 0};
929 VkOffset3D half_offset{16, 16, 0};
930 VkExtent3D half_extent{16, 16, 1}; // <-- image type is 2D
931
932 VkBufferImageCopy region_buffer_front_image_0_front = {0, 16, 16, layers_0, zero_offset, half_extent};
933 VkBufferImageCopy region_buffer_front_image_1_front = {0, 16, 16, layers_1, zero_offset, half_extent};
934 VkBufferImageCopy region_buffer_front_image_1_back = {0, 16, 16, layers_1, half_offset, half_extent};
935 VkBufferImageCopy region_buffer_back_image_0_front = {1024, 16, 16, layers_0, zero_offset, half_extent};
936 VkBufferImageCopy region_buffer_back_image_0_back = {1024, 16, 16, layers_0, half_offset, half_extent};
937 VkBufferImageCopy region_buffer_back_image_1_front = {1024, 16, 16, layers_1, zero_offset, half_extent};
938 VkBufferImageCopy region_buffer_back_image_1_back = {1024, 16, 16, layers_1, half_offset, half_extent};
939
940 m_commandBuffer->begin();
941 image_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
942 image_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
943
944 auto cb = m_commandBuffer->handle();
945 vk::CmdCopyBufferToImage(cb, buffer_a.handle(), image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
946 &region_buffer_front_image_0_front);
947
948 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
949 vk::CmdCopyBufferToImage(cb, buffer_a.handle(), image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
950 &region_buffer_front_image_0_front);
951 m_errorMonitor->VerifyFound();
952
953 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
954 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
955 vk::CmdCopyImageToBuffer(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_a.handle(), 1,
956 &region_buffer_front_image_0_front);
957 m_errorMonitor->VerifyFound();
958
959 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
960 vk::CmdCopyImageToBuffer(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_a.handle(), 1,
961 &region_buffer_back_image_0_front);
962 m_errorMonitor->VerifyFound();
963
964 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
965 vk::CmdCopyImageToBuffer(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_a.handle(), 1,
966 &region_buffer_front_image_1_front);
967 m_errorMonitor->VerifyFound();
968
969 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
970 vk::CmdCopyImageToBuffer(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_a.handle(), 1,
971 &region_buffer_front_image_1_back);
972 m_errorMonitor->VerifyFound();
973
974 m_errorMonitor->ExpectSuccess();
975 vk::CmdCopyImageToBuffer(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_a.handle(), 1, &region_buffer_back_image_0_back);
976 m_errorMonitor->VerifyNotFound();
977
Mark Lobodzinski07d0a612020-12-30 15:42:31 -0700978 auto buffer_barrier = LvlInitStruct<VkBufferMemoryBarrier>();
Jeremy Gebben170781d2020-11-19 16:21:21 -0700979 buffer_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
980 buffer_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
981 buffer_barrier.buffer = buffer_a.handle();
982 buffer_barrier.offset = 1024;
983 buffer_barrier.size = 2048;
984 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, &buffer_barrier, 0,
985 nullptr);
986
987 m_errorMonitor->ExpectSuccess();
988 vk::CmdCopyImageToBuffer(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_a.handle(), 1,
989 &region_buffer_back_image_1_front);
990 m_errorMonitor->VerifyNotFound();
991
992 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, &buffer_barrier, 0,
993 nullptr);
994
995 m_errorMonitor->ExpectSuccess();
996 vk::CmdCopyImageToBuffer(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_a.handle(), 1, &region_buffer_back_image_1_back);
997 m_errorMonitor->VerifyNotFound();
998
999 vk::CmdCopyImageToBuffer(cb, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_b.handle(), 1,
1000 &region_buffer_front_image_0_front);
1001
1002 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1003 vk::CmdCopyImageToBuffer(cb, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_b.handle(), 1,
1004 &region_buffer_front_image_0_front);
1005 m_errorMonitor->VerifyFound();
1006
1007 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1008 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1009 vk::CmdCopyBufferToImage(cb, buffer_b.handle(), image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1010 &region_buffer_front_image_0_front);
1011 m_errorMonitor->VerifyFound();
1012
1013 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1014 vk::CmdCopyBufferToImage(cb, buffer_b.handle(), image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1015 &region_buffer_back_image_0_front);
1016 m_errorMonitor->VerifyFound();
1017
1018 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1019 vk::CmdCopyBufferToImage(cb, buffer_b.handle(), image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1020 &region_buffer_front_image_1_front);
1021 m_errorMonitor->VerifyFound();
1022
1023 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1024 vk::CmdCopyBufferToImage(cb, buffer_b.handle(), image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1025 &region_buffer_front_image_1_back);
1026 m_errorMonitor->VerifyFound();
1027
1028 m_errorMonitor->ExpectSuccess();
1029 vk::CmdCopyBufferToImage(cb, buffer_b.handle(), image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_buffer_back_image_0_back);
1030 m_errorMonitor->VerifyNotFound();
1031
1032 buffer_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
1033 buffer_barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
1034 buffer_barrier.buffer = buffer_b.handle();
1035 buffer_barrier.offset = 1024;
1036 buffer_barrier.size = 2048;
1037 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, &buffer_barrier, 0,
1038 nullptr);
1039
1040 m_errorMonitor->ExpectSuccess();
1041 vk::CmdCopyBufferToImage(cb, buffer_b.handle(), image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1042 &region_buffer_back_image_1_front);
1043 m_errorMonitor->VerifyNotFound();
1044
1045 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, &buffer_barrier, 0,
1046 nullptr);
1047
1048 m_errorMonitor->ExpectSuccess();
1049 vk::CmdCopyBufferToImage(cb, buffer_b.handle(), image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_buffer_back_image_1_back);
1050 m_errorMonitor->VerifyNotFound();
1051
1052 m_commandBuffer->end();
1053}
1054
1055TEST_F(VkSyncValTest, SyncBlitImageHazards) {
1056 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
1057 ASSERT_NO_FATAL_FAILURE(InitState());
1058
1059 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1060 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
1061 VkImageObj image_a(m_device), image_b(m_device);
1062 const auto image_ci = VkImageObj::ImageCreateInfo2D(32, 32, 1, 2, format, usage, VK_IMAGE_TILING_OPTIMAL);
1063 image_a.Init(image_ci);
1064 image_b.Init(image_ci);
1065
1066 VkImageSubresourceLayers layers_0{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
1067 VkImageSubresourceLayers layers_1{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1};
1068 VkOffset3D zero_offset{0, 0, 0};
1069 VkOffset3D half_0_offset{16, 16, 0};
1070 VkOffset3D half_1_offset{16, 16, 1};
1071 VkOffset3D full_offset{32, 32, 1};
1072 VkImageBlit region_0_front_1_front = {layers_0, {zero_offset, half_1_offset}, layers_1, {zero_offset, half_1_offset}};
1073 VkImageBlit region_1_front_0_front = {layers_1, {zero_offset, half_1_offset}, layers_0, {zero_offset, half_1_offset}};
1074 VkImageBlit region_1_back_0_back = {layers_1, {half_0_offset, full_offset}, layers_0, {half_0_offset, full_offset}};
1075
1076 m_commandBuffer->begin();
1077 image_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1078 image_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1079
1080 auto cb = m_commandBuffer->handle();
1081
1082 vk::CmdBlitImage(cb, image_a.image(), VK_IMAGE_LAYOUT_GENERAL, image_b.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
1083 &region_0_front_1_front, VK_FILTER_NEAREST);
1084
1085 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1086 vk::CmdBlitImage(cb, image_a.image(), VK_IMAGE_LAYOUT_GENERAL, image_b.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
1087 &region_0_front_1_front, VK_FILTER_NEAREST);
1088 m_errorMonitor->VerifyFound();
1089
1090 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1091 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1092 vk::CmdBlitImage(cb, image_b.image(), VK_IMAGE_LAYOUT_GENERAL, image_a.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
1093 &region_1_front_0_front, VK_FILTER_NEAREST);
1094 m_errorMonitor->VerifyFound();
1095
1096 m_errorMonitor->ExpectSuccess();
1097 vk::CmdBlitImage(cb, image_b.image(), VK_IMAGE_LAYOUT_GENERAL, image_a.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
1098 &region_1_back_0_back, VK_FILTER_NEAREST);
1099 m_errorMonitor->VerifyNotFound();
1100
1101 m_commandBuffer->end();
1102}
1103
1104TEST_F(VkSyncValTest, SyncRenderPassBeginTransitionHazard) {
1105 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
1106 ASSERT_NO_FATAL_FAILURE(InitState());
1107 ASSERT_NO_FATAL_FAILURE(InitRenderTarget(2));
1108
1109 // Render Target Information
1110 auto width = static_cast<uint32_t>(m_width);
1111 auto height = static_cast<uint32_t>(m_height);
1112 auto *rt_0 = m_renderTargets[0].get();
1113 auto *rt_1 = m_renderTargets[1].get();
1114
1115 // Other buffers with which to interact
1116 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1117 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
1118 VkImageObj image_a(m_device), image_b(m_device);
1119 const auto image_ci = VkImageObj::ImageCreateInfo2D(width, height, 1, 1, format, usage, VK_IMAGE_TILING_OPTIMAL);
1120 image_a.Init(image_ci);
1121 image_b.Init(image_ci);
1122
1123 VkOffset3D zero_offset{0, 0, 0};
1124 VkExtent3D full_extent{width, height, 1}; // <-- image type is 2D
1125 VkImageSubresourceLayers layer_color{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
1126 VkImageCopy region_to_copy = {layer_color, zero_offset, layer_color, zero_offset, full_extent};
1127
1128 auto cb = m_commandBuffer->handle();
1129
1130 m_errorMonitor->ExpectSuccess();
1131 m_commandBuffer->begin();
1132 image_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1133 image_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1134 rt_0->SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1135 rt_1->SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1136
1137 rt_0->SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1138 vk::CmdCopyImage(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, rt_0->handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_to_copy);
1139 m_errorMonitor->VerifyNotFound();
1140
1141 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1142 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); // This fails so the driver call is skip and no end is valid
1143 m_errorMonitor->VerifyFound();
1144
1145 m_errorMonitor->ExpectSuccess();
1146 // Use the barrier to clean up the WAW, and try again. (and show that validation is accounting for the barrier effect too.)
1147 VkImageSubresourceRange rt_full_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07001148 auto image_barrier = LvlInitStruct<VkImageMemoryBarrier>();
Jeremy Gebben170781d2020-11-19 16:21:21 -07001149 image_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1150 image_barrier.dstAccessMask = 0;
1151 image_barrier.image = rt_0->handle();
1152 image_barrier.subresourceRange = rt_full_subresource_range;
1153 image_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
1154 image_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
1155 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, 1,
1156 &image_barrier);
1157 vk::CmdCopyImage(cb, rt_1->handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_to_copy);
1158 m_errorMonitor->VerifyNotFound();
1159
1160 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1161 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); // This fails so the driver call is skip and no end is valid
1162 m_errorMonitor->VerifyFound();
1163
1164 m_errorMonitor->ExpectSuccess();
1165 // A global execution barrier that the implict external dependency can chain with should work...
1166 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, 0,
1167 nullptr);
1168
1169 // With the barrier above, the layout transition has a chained execution sync operation, and the default
1170 // implict VkSubpassDependency safes the load op clear vs. the layout transition...
1171 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1172 m_commandBuffer->EndRenderPass();
1173 m_errorMonitor->VerifyNotFound();
1174}
1175
1176TEST_F(VkSyncValTest, SyncCmdDispatchDrawHazards) {
1177 // TODO: Add code to enable sync validation
1178 SetTargetApiVersion(VK_API_VERSION_1_2);
1179
1180 // Enable VK_KHR_draw_indirect_count for KHR variants
1181 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
1182 VkPhysicalDeviceVulkan12Features features12 = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, nullptr};
1183 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME)) {
1184 m_device_extension_names.push_back(VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME);
1185 if (DeviceValidationVersion() >= VK_API_VERSION_1_2) {
1186 features12.drawIndirectCount = VK_TRUE;
1187 }
1188 }
1189 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features12, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
1190 bool has_khr_indirect = DeviceExtensionEnabled(VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME);
1191 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1192
1193 VkImageUsageFlags image_usage_combine = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
1194 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1195 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
1196 VkImageObj image_c_a(m_device), image_c_b(m_device);
1197 const auto image_c_ci = VkImageObj::ImageCreateInfo2D(16, 16, 1, 1, format, image_usage_combine, VK_IMAGE_TILING_OPTIMAL);
1198 image_c_a.Init(image_c_ci);
1199 image_c_b.Init(image_c_ci);
1200
1201 VkImageView imageview_c = image_c_a.targetView(format);
1202 VkImageUsageFlags image_usage_storage =
1203 VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1204 VkImageObj image_s_a(m_device), image_s_b(m_device);
1205 const auto image_s_ci = VkImageObj::ImageCreateInfo2D(16, 16, 1, 1, format, image_usage_storage, VK_IMAGE_TILING_OPTIMAL);
1206 image_s_a.Init(image_s_ci);
1207 image_s_b.Init(image_s_ci);
1208 image_s_a.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1209 image_s_b.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1210
1211 VkImageView imageview_s = image_s_a.targetView(format);
1212
1213 VkSampler sampler_s, sampler_c;
1214 VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
1215 VkResult err = vk::CreateSampler(m_device->device(), &sampler_ci, nullptr, &sampler_s);
1216 ASSERT_VK_SUCCESS(err);
1217 err = vk::CreateSampler(m_device->device(), &sampler_ci, nullptr, &sampler_c);
1218 ASSERT_VK_SUCCESS(err);
1219
1220 VkBufferObj buffer_a, buffer_b;
1221 VkMemoryPropertyFlags mem_prop = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
1222 VkBufferUsageFlags buffer_usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT |
1223 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1224 buffer_a.init(*m_device, buffer_a.create_info(2048, buffer_usage, nullptr), mem_prop);
1225 buffer_b.init(*m_device, buffer_b.create_info(2048, buffer_usage, nullptr), mem_prop);
1226
1227 VkBufferView bufferview;
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07001228 auto bvci = LvlInitStruct<VkBufferViewCreateInfo>();
Jeremy Gebben170781d2020-11-19 16:21:21 -07001229 bvci.buffer = buffer_a.handle();
1230 bvci.format = VK_FORMAT_R32_SFLOAT;
1231 bvci.offset = 0;
1232 bvci.range = VK_WHOLE_SIZE;
1233
1234 err = vk::CreateBufferView(m_device->device(), &bvci, NULL, &bufferview);
1235 ASSERT_VK_SUCCESS(err);
1236
1237 OneOffDescriptorSet descriptor_set(m_device,
1238 {
1239 {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
1240 {1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr},
1241 {2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_ALL, nullptr},
1242 {3, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
1243 });
1244
sfricke-samsung36428462021-02-10 01:23:34 -08001245 descriptor_set.WriteDescriptorBufferInfo(0, buffer_a.handle(), 0, 2048);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001246 descriptor_set.WriteDescriptorImageInfo(1, imageview_c, sampler_c, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
1247 VK_IMAGE_LAYOUT_GENERAL);
1248 descriptor_set.WriteDescriptorImageInfo(2, imageview_s, sampler_s, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_IMAGE_LAYOUT_GENERAL);
1249 descriptor_set.WriteDescriptorBufferView(3, bufferview);
1250 descriptor_set.UpdateDescriptorSets();
1251
1252 // Dispatch
1253 std::string csSource =
1254 "#version 450\n"
1255 "layout(set=0, binding=0) uniform foo { float x; } ub0;\n"
1256 "layout(set=0, binding=1) uniform sampler2D cis1;\n"
1257 "layout(set=0, binding=2, rgba8) uniform readonly image2D si2;\n"
1258 "layout(set=0, binding=3, r32f) uniform readonly imageBuffer stb3;\n"
1259 "void main(){\n"
1260 " vec4 vColor4;\n"
1261 " vColor4.x = ub0.x;\n"
1262 " vColor4 = texture(cis1, vec2(0));\n"
1263 " vColor4 = imageLoad(si2, ivec2(0));\n"
1264 " vColor4 = imageLoad(stb3, 0);\n"
1265 "}\n";
1266
John Zulaufbe8562b2020-12-15 14:21:01 -07001267 VkEventObj event;
1268 event.init(*m_device, VkEventObj::create_info(0));
1269 VkEvent event_handle = event.handle();
1270
Jeremy Gebben170781d2020-11-19 16:21:21 -07001271 CreateComputePipelineHelper pipe(*this);
1272 pipe.InitInfo();
1273 pipe.cs_.reset(new VkShaderObj(m_device, csSource.c_str(), VK_SHADER_STAGE_COMPUTE_BIT, this));
1274 pipe.InitState();
1275 pipe.pipeline_layout_ = VkPipelineLayoutObj(m_device, {&descriptor_set.layout_});
1276 pipe.CreateComputePipeline();
1277
1278 m_commandBuffer->begin();
1279
1280 VkBufferCopy buffer_region = {0, 0, 2048};
1281 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_b.handle(), buffer_a.handle(), 1, &buffer_region);
1282
1283 VkImageSubresourceLayers layer{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
1284 VkOffset3D zero_offset{0, 0, 0};
1285 VkExtent3D full_extent{16, 16, 1};
1286 VkImageCopy image_region = {layer, zero_offset, layer, zero_offset, full_extent};
1287 vk::CmdCopyImage(m_commandBuffer->handle(), image_c_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_c_a.handle(),
1288 VK_IMAGE_LAYOUT_GENERAL, 1, &image_region);
1289 vk::CmdCopyImage(m_commandBuffer->handle(), image_s_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_s_a.handle(),
1290 VK_IMAGE_LAYOUT_GENERAL, 1, &image_region);
1291
1292 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_);
1293 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_layout_.handle(), 0, 1,
1294 &descriptor_set.set_, 0, nullptr);
1295
1296 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1297 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1298 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1299 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1300 vk::CmdDispatch(m_commandBuffer->handle(), 1, 1, 1);
1301 m_errorMonitor->VerifyFound();
1302
1303 m_commandBuffer->end();
1304 m_commandBuffer->reset();
1305 m_commandBuffer->begin();
1306
1307 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_);
1308 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_layout_.handle(), 0, 1,
1309 &descriptor_set.set_, 0, nullptr);
1310 vk::CmdDispatch(m_commandBuffer->handle(), 1, 1, 1);
1311
1312 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1313 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_b.handle(), buffer_a.handle(), 1, &buffer_region);
1314 m_errorMonitor->VerifyFound();
1315
1316 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1317 vk::CmdCopyImage(m_commandBuffer->handle(), image_c_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_c_a.handle(),
1318 VK_IMAGE_LAYOUT_GENERAL, 1, &image_region);
1319 m_errorMonitor->VerifyFound();
1320
1321 m_commandBuffer->end();
1322 m_commandBuffer->reset();
1323
1324 // DispatchIndirect
1325 m_errorMonitor->ExpectSuccess();
1326 VkBufferObj buffer_dispatchIndirect, buffer_dispatchIndirect2;
1327 buffer_usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1328 buffer_dispatchIndirect.init(
1329 *m_device, buffer_dispatchIndirect.create_info(sizeof(VkDispatchIndirectCommand), buffer_usage, nullptr), mem_prop);
1330 buffer_dispatchIndirect2.init(
1331 *m_device, buffer_dispatchIndirect2.create_info(sizeof(VkDispatchIndirectCommand), buffer_usage, nullptr), mem_prop);
1332 m_commandBuffer->begin();
1333 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_);
1334 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_layout_.handle(), 0, 1,
1335 &descriptor_set.set_, 0, nullptr);
1336 vk::CmdDispatchIndirect(m_commandBuffer->handle(), buffer_dispatchIndirect.handle(), 0);
1337 m_commandBuffer->end();
1338 m_errorMonitor->VerifyNotFound();
1339
1340 m_commandBuffer->reset();
1341 m_commandBuffer->begin();
1342
1343 buffer_region = {0, 0, sizeof(VkDispatchIndirectCommand)};
1344 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_dispatchIndirect2.handle(), buffer_dispatchIndirect.handle(), 1,
1345 &buffer_region);
1346 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_);
1347 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_layout_.handle(), 0, 1,
1348 &descriptor_set.set_, 0, nullptr);
1349 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1350 vk::CmdDispatchIndirect(m_commandBuffer->handle(), buffer_dispatchIndirect.handle(), 0);
1351 m_errorMonitor->VerifyFound();
1352 m_commandBuffer->end();
1353
1354 // Draw
1355 m_errorMonitor->ExpectSuccess();
1356 const float vbo_data[3] = {1.f, 0.f, 1.f};
1357 VkVertexInputAttributeDescription VertexInputAttributeDescription = {0, 0, VK_FORMAT_R32G32B32_SFLOAT, sizeof(vbo_data)};
1358 VkVertexInputBindingDescription VertexInputBindingDescription = {0, sizeof(vbo_data), VK_VERTEX_INPUT_RATE_VERTEX};
1359 VkBufferObj vbo, vbo2;
1360 buffer_usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1361 vbo.init(*m_device, vbo.create_info(sizeof(vbo_data), buffer_usage, nullptr), mem_prop);
1362 vbo2.init(*m_device, vbo2.create_info(sizeof(vbo_data), buffer_usage, nullptr), mem_prop);
1363
1364 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
1365 VkShaderObj fs(m_device, csSource.c_str(), VK_SHADER_STAGE_FRAGMENT_BIT, this);
1366
1367 CreatePipelineHelper g_pipe(*this);
1368 g_pipe.InitInfo();
1369 g_pipe.InitState();
1370 g_pipe.vi_ci_.pVertexBindingDescriptions = &VertexInputBindingDescription;
1371 g_pipe.vi_ci_.vertexBindingDescriptionCount = 1;
1372 g_pipe.vi_ci_.pVertexAttributeDescriptions = &VertexInputAttributeDescription;
1373 g_pipe.vi_ci_.vertexAttributeDescriptionCount = 1;
1374 g_pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
1375 g_pipe.pipeline_layout_ = VkPipelineLayoutObj(m_device, {&descriptor_set.layout_});
1376 ASSERT_VK_SUCCESS(g_pipe.CreateGraphicsPipeline());
1377
1378 m_commandBuffer->reset();
1379 m_commandBuffer->begin();
1380 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1381 VkDeviceSize offset = 0;
1382 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1383
1384 VkViewport viewport = {0, 0, 16, 16, 0, 1};
1385 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1386 VkRect2D scissor = {{0, 0}, {16, 16}};
1387 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1388
1389 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1390 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1391 &descriptor_set.set_, 0, nullptr);
1392 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1393 m_commandBuffer->EndRenderPass();
1394 m_commandBuffer->end();
1395 m_errorMonitor->VerifyNotFound();
1396
1397 m_commandBuffer->reset();
1398 m_commandBuffer->begin();
1399
1400 buffer_region = {0, 0, sizeof(vbo_data)};
1401 vk::CmdCopyBuffer(m_commandBuffer->handle(), vbo2.handle(), vbo.handle(), 1, &buffer_region);
1402
1403 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1404 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1405 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1406 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1407 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1408 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1409 &descriptor_set.set_, 0, nullptr);
1410
1411 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1412 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1413 m_errorMonitor->VerifyFound();
1414
1415 m_commandBuffer->EndRenderPass();
1416 m_commandBuffer->end();
1417
John Zulaufbe8562b2020-12-15 14:21:01 -07001418 // Repeat the draw test with a WaitEvent to protect it.
1419 m_errorMonitor->ExpectSuccess();
1420 m_commandBuffer->reset();
1421 m_commandBuffer->begin();
1422
1423 vk::CmdCopyBuffer(m_commandBuffer->handle(), vbo2.handle(), vbo.handle(), 1, &buffer_region);
1424
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07001425 auto vbo_barrier = LvlInitStruct<VkBufferMemoryBarrier>();
John Zulaufbe8562b2020-12-15 14:21:01 -07001426 vbo_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1427 vbo_barrier.dstAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
1428 vbo_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1429 vbo_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1430 vbo_barrier.buffer = vbo.handle();
1431 vbo_barrier.offset = buffer_region.dstOffset;
1432 vbo_barrier.size = buffer_region.size;
1433
1434 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
1435
1436 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1437 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1438 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1439 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1440 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1441 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1442 &descriptor_set.set_, 0, nullptr);
1443
1444 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0, nullptr, 1,
1445 &vbo_barrier, 0, nullptr);
1446 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1447
1448 m_commandBuffer->EndRenderPass();
1449 m_commandBuffer->end();
1450 m_errorMonitor->VerifyNotFound();
1451
Jeremy Gebben170781d2020-11-19 16:21:21 -07001452 // DrawIndexed
1453 m_errorMonitor->ExpectSuccess();
1454 const float ibo_data[3] = {0.f, 0.f, 0.f};
1455 VkBufferObj ibo, ibo2;
1456 buffer_usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1457 ibo.init(*m_device, ibo.create_info(sizeof(ibo_data), buffer_usage, nullptr), mem_prop);
1458 ibo2.init(*m_device, ibo2.create_info(sizeof(ibo_data), buffer_usage, nullptr), mem_prop);
1459
1460 m_commandBuffer->reset();
1461 m_commandBuffer->begin();
1462 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1463 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1464 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), ibo.handle(), 0, VK_INDEX_TYPE_UINT16);
1465 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1466 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1467
1468 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1469 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1470 &descriptor_set.set_, 0, nullptr);
1471 m_commandBuffer->DrawIndexed(3, 1, 0, 0, 0);
1472 m_commandBuffer->EndRenderPass();
1473 m_commandBuffer->end();
1474 m_errorMonitor->VerifyNotFound();
1475
1476 m_commandBuffer->reset();
1477 m_commandBuffer->begin();
1478
1479 buffer_region = {0, 0, sizeof(ibo_data)};
1480 vk::CmdCopyBuffer(m_commandBuffer->handle(), ibo2.handle(), ibo.handle(), 1, &buffer_region);
1481
1482 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1483 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1484 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), ibo.handle(), 0, VK_INDEX_TYPE_UINT16);
1485 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1486 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1487 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1488 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1489 &descriptor_set.set_, 0, nullptr);
1490
1491 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1492 m_commandBuffer->DrawIndexed(3, 1, 0, 0, 0);
1493 m_errorMonitor->VerifyFound();
1494
1495 m_commandBuffer->EndRenderPass();
1496 m_commandBuffer->end();
1497
1498 // DrawIndirect
1499 m_errorMonitor->ExpectSuccess();
1500 VkBufferObj buffer_drawIndirect, buffer_drawIndirect2;
1501 buffer_usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1502 buffer_drawIndirect.init(*m_device, buffer_drawIndirect.create_info(sizeof(VkDrawIndirectCommand), buffer_usage, nullptr),
1503 mem_prop);
1504 buffer_drawIndirect2.init(*m_device, buffer_drawIndirect2.create_info(sizeof(VkDrawIndirectCommand), buffer_usage, nullptr),
1505 mem_prop);
1506
1507 m_commandBuffer->reset();
1508 m_commandBuffer->begin();
1509 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1510 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1511 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1512 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1513
1514 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1515 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1516 &descriptor_set.set_, 0, nullptr);
1517 vk::CmdDrawIndirect(m_commandBuffer->handle(), buffer_drawIndirect.handle(), 0, 1, sizeof(VkDrawIndirectCommand));
1518 m_commandBuffer->EndRenderPass();
1519 m_commandBuffer->end();
1520 m_errorMonitor->VerifyNotFound();
1521
1522 m_commandBuffer->reset();
1523 m_commandBuffer->begin();
1524
1525 buffer_region = {0, 0, sizeof(VkDrawIndirectCommand)};
1526 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_drawIndirect2.handle(), buffer_drawIndirect.handle(), 1, &buffer_region);
1527
1528 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1529 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1530 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1531 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1532 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1533 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1534 &descriptor_set.set_, 0, nullptr);
1535
1536 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1537 vk::CmdDrawIndirect(m_commandBuffer->handle(), buffer_drawIndirect.handle(), 0, 1, sizeof(VkDrawIndirectCommand));
1538 m_errorMonitor->VerifyFound();
1539
1540 m_commandBuffer->EndRenderPass();
1541 m_commandBuffer->end();
1542
1543 // DrawIndexedIndirect
1544 m_errorMonitor->ExpectSuccess();
1545 VkBufferObj buffer_drawIndexedIndirect, buffer_drawIndexedIndirect2;
1546 buffer_usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1547 buffer_drawIndexedIndirect.init(
1548 *m_device, buffer_drawIndexedIndirect.create_info(sizeof(VkDrawIndexedIndirectCommand), buffer_usage, nullptr), mem_prop);
1549 buffer_drawIndexedIndirect2.init(
1550 *m_device, buffer_drawIndexedIndirect2.create_info(sizeof(VkDrawIndexedIndirectCommand), buffer_usage, nullptr), mem_prop);
1551
1552 m_commandBuffer->reset();
1553 m_commandBuffer->begin();
1554 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1555 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1556 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), ibo.handle(), 0, VK_INDEX_TYPE_UINT16);
1557 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1558 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1559
1560 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1561 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1562 &descriptor_set.set_, 0, nullptr);
1563 vk::CmdDrawIndexedIndirect(m_commandBuffer->handle(), buffer_drawIndirect.handle(), 0, 1, sizeof(VkDrawIndexedIndirectCommand));
1564 m_commandBuffer->EndRenderPass();
1565 m_commandBuffer->end();
1566 m_errorMonitor->VerifyNotFound();
1567
1568 m_commandBuffer->reset();
1569 m_commandBuffer->begin();
1570
1571 buffer_region = {0, 0, sizeof(VkDrawIndexedIndirectCommand)};
1572 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_drawIndexedIndirect2.handle(), buffer_drawIndexedIndirect.handle(), 1,
1573 &buffer_region);
1574
1575 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1576 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1577 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), ibo.handle(), 0, VK_INDEX_TYPE_UINT16);
1578 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1579 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1580 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1581 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1582 &descriptor_set.set_, 0, nullptr);
1583
1584 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1585 vk::CmdDrawIndexedIndirect(m_commandBuffer->handle(), buffer_drawIndexedIndirect.handle(), 0, 1,
1586 sizeof(VkDrawIndexedIndirectCommand));
1587 m_errorMonitor->VerifyFound();
1588
1589 m_commandBuffer->EndRenderPass();
1590 m_commandBuffer->end();
1591
1592 if (has_khr_indirect) {
1593 // DrawIndirectCount
1594 auto fpCmdDrawIndirectCountKHR =
1595 (PFN_vkCmdDrawIndirectCount)vk::GetDeviceProcAddr(m_device->device(), "vkCmdDrawIndirectCountKHR");
1596 if (!fpCmdDrawIndirectCountKHR) {
1597 printf("%s Test requires unsupported vkCmdDrawIndirectCountKHR feature. Skipped.\n", kSkipPrefix);
1598 } else {
1599 m_errorMonitor->ExpectSuccess();
1600 VkBufferObj buffer_count, buffer_count2;
1601 buffer_usage =
1602 VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1603 buffer_count.init(*m_device, buffer_count.create_info(sizeof(uint32_t), buffer_usage, nullptr), mem_prop);
1604 buffer_count2.init(*m_device, buffer_count2.create_info(sizeof(uint32_t), buffer_usage, nullptr), mem_prop);
1605
1606 m_commandBuffer->reset();
1607 m_commandBuffer->begin();
1608 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1609 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1610 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1611 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1612
1613 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1614 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(),
1615 0, 1, &descriptor_set.set_, 0, nullptr);
1616 fpCmdDrawIndirectCountKHR(m_commandBuffer->handle(), buffer_drawIndirect.handle(), 0, buffer_count.handle(), 0, 1,
1617 sizeof(VkDrawIndirectCommand));
1618 m_commandBuffer->EndRenderPass();
1619 m_commandBuffer->end();
1620 m_errorMonitor->VerifyNotFound();
1621
1622 m_commandBuffer->reset();
1623 m_commandBuffer->begin();
1624
1625 buffer_region = {0, 0, sizeof(uint32_t)};
1626 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_count2.handle(), buffer_count.handle(), 1, &buffer_region);
1627
1628 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1629 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1630 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1631 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1632 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1633 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(),
1634 0, 1, &descriptor_set.set_, 0, nullptr);
1635
1636 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1637 fpCmdDrawIndirectCountKHR(m_commandBuffer->handle(), buffer_drawIndirect.handle(), 0, buffer_count.handle(), 0, 1,
1638 sizeof(VkDrawIndirectCommand));
1639 m_errorMonitor->VerifyFound();
1640
1641 m_commandBuffer->EndRenderPass();
1642 m_commandBuffer->end();
1643 }
1644
1645 // DrawIndexedIndirectCount
1646 auto fpCmdDrawIndexIndirectCountKHR =
1647 (PFN_vkCmdDrawIndirectCount)vk::GetDeviceProcAddr(m_device->device(), "vkCmdDrawIndexedIndirectCountKHR");
1648 if (!fpCmdDrawIndexIndirectCountKHR) {
1649 printf("%s Test requires unsupported vkCmdDrawIndexedIndirectCountKHR feature. Skipped.\n", kSkipPrefix);
1650 } else {
1651 m_errorMonitor->ExpectSuccess();
1652 VkBufferObj buffer_count, buffer_count2;
1653 buffer_usage =
1654 VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1655 buffer_count.init(*m_device, buffer_count.create_info(sizeof(uint32_t), buffer_usage, nullptr), mem_prop);
1656 buffer_count2.init(*m_device, buffer_count2.create_info(sizeof(uint32_t), buffer_usage, nullptr), mem_prop);
1657
1658 m_commandBuffer->reset();
1659 m_commandBuffer->begin();
1660 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1661 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1662 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), ibo.handle(), 0, VK_INDEX_TYPE_UINT16);
1663 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1664 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1665
1666 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1667 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(),
1668 0, 1, &descriptor_set.set_, 0, nullptr);
1669 fpCmdDrawIndexIndirectCountKHR(m_commandBuffer->handle(), buffer_drawIndexedIndirect.handle(), 0, buffer_count.handle(),
1670 0, 1, sizeof(VkDrawIndexedIndirectCommand));
1671 m_commandBuffer->EndRenderPass();
1672 m_commandBuffer->end();
1673 m_errorMonitor->VerifyNotFound();
1674
1675 m_commandBuffer->reset();
1676 m_commandBuffer->begin();
1677
1678 buffer_region = {0, 0, sizeof(uint32_t)};
1679 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_count2.handle(), buffer_count.handle(), 1, &buffer_region);
1680
1681 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1682 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1683 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), ibo.handle(), 0, VK_INDEX_TYPE_UINT16);
1684 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1685 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1686 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1687 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(),
1688 0, 1, &descriptor_set.set_, 0, nullptr);
1689
1690 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1691 fpCmdDrawIndexIndirectCountKHR(m_commandBuffer->handle(), buffer_drawIndexedIndirect.handle(), 0, buffer_count.handle(),
1692 0, 1, sizeof(VkDrawIndexedIndirectCommand));
1693 m_errorMonitor->VerifyFound();
1694
1695 m_commandBuffer->EndRenderPass();
1696 m_commandBuffer->end();
1697 }
1698 } else {
1699 printf("%s Test requires unsupported vkCmdDrawIndirectCountKHR & vkDrawIndexedIndirectCountKHR feature. Skipped.\n",
1700 kSkipPrefix);
1701 }
1702}
1703
1704TEST_F(VkSyncValTest, SyncCmdClear) {
1705 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
1706 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
1707 // CmdClearColorImage
1708 m_errorMonitor->ExpectSuccess();
1709 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1710 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
1711 VkImageObj image_a(m_device), image_b(m_device);
1712 auto image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 1, format, usage, VK_IMAGE_TILING_OPTIMAL);
1713 image_a.Init(image_ci);
1714 image_b.Init(image_ci);
1715
1716 VkImageSubresourceLayers layers_all{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
1717 VkOffset3D zero_offset{0, 0, 0};
1718 VkExtent3D full_extent{128, 128, 1}; // <-- image type is 2D
1719 VkImageSubresourceRange full_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
1720
1721 VkImageCopy full_region = {layers_all, zero_offset, layers_all, zero_offset, full_extent};
1722
1723 m_commandBuffer->begin();
1724
1725 image_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1726 image_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1727
1728 auto cb = m_commandBuffer->handle();
1729 VkClearColorValue ccv = {};
1730 vk::CmdClearColorImage(m_commandBuffer->handle(), image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &full_subresource_range);
1731 m_commandBuffer->end();
1732 m_errorMonitor->VerifyNotFound();
1733
1734 m_commandBuffer->reset();
1735 m_commandBuffer->begin();
1736 vk::CmdCopyImage(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
1737
1738 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1739 vk::CmdClearColorImage(m_commandBuffer->handle(), image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &full_subresource_range);
1740 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1741 vk::CmdClearColorImage(m_commandBuffer->handle(), image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &full_subresource_range);
1742 m_errorMonitor->VerifyFound();
1743
1744 m_commandBuffer->end();
1745
1746 // CmdClearDepthStencilImage
1747 format = FindSupportedDepthStencilFormat(gpu());
1748 if (!format) {
1749 printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix);
1750 return;
1751 }
1752 m_errorMonitor->ExpectSuccess();
1753 VkImageObj image_ds_a(m_device), image_ds_b(m_device);
1754 image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 1, format, usage, VK_IMAGE_TILING_OPTIMAL);
1755 image_ds_a.Init(image_ci);
1756 image_ds_b.Init(image_ci);
1757
1758 const VkImageAspectFlags ds_aspect = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
1759 image_ds_a.SetLayout(ds_aspect, VK_IMAGE_LAYOUT_GENERAL);
1760 image_ds_b.SetLayout(ds_aspect, VK_IMAGE_LAYOUT_GENERAL);
1761
1762 m_commandBuffer->begin();
1763 const VkClearDepthStencilValue clear_value = {};
1764 VkImageSubresourceRange ds_range = {ds_aspect, 0, 1, 0, 1};
1765
1766 vk::CmdClearDepthStencilImage(cb, image_ds_a.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1, &ds_range);
1767 m_commandBuffer->end();
1768 m_errorMonitor->VerifyNotFound();
1769
1770 VkImageSubresourceLayers ds_layers_all{ds_aspect, 0, 0, 1};
1771 VkImageCopy ds_full_region = {ds_layers_all, zero_offset, ds_layers_all, zero_offset, full_extent};
1772
1773 m_commandBuffer->reset();
1774 m_commandBuffer->begin();
1775 vk::CmdCopyImage(cb, image_ds_a.handle(), VK_IMAGE_LAYOUT_GENERAL, image_ds_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1776 &ds_full_region);
1777
1778 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1779 vk::CmdClearDepthStencilImage(m_commandBuffer->handle(), image_ds_a.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1,
1780 &ds_range);
1781 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1782 vk::CmdClearDepthStencilImage(m_commandBuffer->handle(), image_ds_b.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1,
1783 &ds_range);
1784 m_errorMonitor->VerifyFound();
1785
1786 m_commandBuffer->end();
1787}
1788
1789TEST_F(VkSyncValTest, SyncCmdQuery) {
1790 // CmdCopyQueryPoolResults
1791 m_errorMonitor->ExpectSuccess();
1792 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
1793 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
1794 if (IsPlatform(kNexusPlayer)) {
1795 printf("%s This test should not run on Nexus Player\n", kSkipPrefix);
1796 return;
1797 }
1798 if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) {
1799 printf("%s Queue family needs to have multiple queues to run this test.\n", kSkipPrefix);
1800 return;
1801 }
1802 uint32_t queue_count;
1803 vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_count, NULL);
1804 VkQueueFamilyProperties *queue_props = new VkQueueFamilyProperties[queue_count];
1805 vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_count, queue_props);
1806 if (queue_props[m_device->graphics_queue_node_index_].timestampValidBits == 0) {
1807 printf("%s Device graphic queue has timestampValidBits of 0, skipping.\n", kSkipPrefix);
1808 return;
1809 }
1810
1811 VkQueryPool query_pool;
1812 VkQueryPoolCreateInfo query_pool_create_info{};
1813 query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
1814 query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
1815 query_pool_create_info.queryCount = 1;
1816 vk::CreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
1817
1818 VkBufferObj buffer_a, buffer_b;
1819 VkMemoryPropertyFlags mem_prop = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
1820 buffer_a.init_as_src_and_dst(*m_device, 256, mem_prop);
1821 buffer_b.init_as_src_and_dst(*m_device, 256, mem_prop);
1822
1823 VkBufferCopy region = {0, 0, 256};
1824
1825 auto cb = m_commandBuffer->handle();
1826 m_commandBuffer->begin();
1827 vk::CmdResetQueryPool(cb, query_pool, 0, 1);
1828 vk::CmdWriteTimestamp(cb, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool, 0);
1829 vk::CmdCopyQueryPoolResults(cb, query_pool, 0, 1, buffer_a.handle(), 0, 0, VK_QUERY_RESULT_WAIT_BIT);
1830 m_commandBuffer->end();
1831 m_errorMonitor->VerifyNotFound();
1832
1833 m_commandBuffer->reset();
1834 m_commandBuffer->begin();
1835 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &region);
1836 vk::CmdResetQueryPool(cb, query_pool, 0, 1);
1837 vk::CmdWriteTimestamp(cb, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool, 0);
1838 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1839 vk::CmdCopyQueryPoolResults(cb, query_pool, 0, 1, buffer_a.handle(), 0, 256, VK_QUERY_RESULT_WAIT_BIT);
1840 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1841 vk::CmdCopyQueryPoolResults(cb, query_pool, 0, 1, buffer_b.handle(), 0, 256, VK_QUERY_RESULT_WAIT_BIT);
1842 m_commandBuffer->end();
1843 m_errorMonitor->VerifyFound();
1844
1845 // TODO:Track VkQueryPool
1846 // TODO:CmdWriteTimestamp
1847 vk::DestroyQueryPool(m_device->device(), query_pool, nullptr);
1848}
1849
1850TEST_F(VkSyncValTest, SyncCmdDrawDepthStencil) {
1851 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
1852 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
1853 m_errorMonitor->ExpectSuccess();
1854
1855 const auto format_ds = FindSupportedDepthStencilFormat(gpu());
1856 if (!format_ds) {
1857 printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix);
1858 return;
1859 }
1860 const auto format_dp = FindSupportedDepthOnlyFormat(gpu());
1861 if (!format_dp) {
1862 printf("%s No only Depth format found. Skipped.\n", kSkipPrefix);
1863 return;
1864 }
1865 const auto format_st = FindSupportedStencilOnlyFormat(gpu());
1866 if (!format_st) {
1867 printf("%s No only Stencil format found. Skipped.\n", kSkipPrefix);
1868 return;
1869 }
1870
1871 VkDepthStencilObj image_ds(m_device), image_dp(m_device), image_st(m_device);
1872 image_ds.Init(m_device, 16, 16, format_ds);
1873 image_dp.Init(m_device, 16, 16, format_dp);
1874 image_st.Init(m_device, 16, 16, format_st);
1875
1876 VkRenderpassObj rp_ds(m_device, format_ds, true), rp_dp(m_device, format_dp, true), rp_st(m_device, format_st, true);
1877
1878 VkFramebuffer fb_ds, fb_dp, fb_st;
1879 VkFramebufferCreateInfo fbci = {
1880 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp_ds.handle(), 1, image_ds.BindInfo(), 16, 16, 1};
1881 ASSERT_VK_SUCCESS(vk::CreateFramebuffer(device(), &fbci, nullptr, &fb_ds));
1882 fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp_dp.handle(), 1, image_dp.BindInfo(), 16, 16, 1};
1883 ASSERT_VK_SUCCESS(vk::CreateFramebuffer(device(), &fbci, nullptr, &fb_dp));
1884 fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp_st.handle(), 1, image_st.BindInfo(), 16, 16, 1};
1885 ASSERT_VK_SUCCESS(vk::CreateFramebuffer(device(), &fbci, nullptr, &fb_st));
1886
1887 VkStencilOpState stencil = {};
1888 stencil.failOp = VK_STENCIL_OP_KEEP;
1889 stencil.passOp = VK_STENCIL_OP_KEEP;
1890 stencil.depthFailOp = VK_STENCIL_OP_KEEP;
1891 stencil.compareOp = VK_COMPARE_OP_NEVER;
1892
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07001893 auto ds_ci = LvlInitStruct<VkPipelineDepthStencilStateCreateInfo>();
Jeremy Gebben170781d2020-11-19 16:21:21 -07001894 ds_ci.depthTestEnable = VK_TRUE;
1895 ds_ci.depthWriteEnable = VK_TRUE;
1896 ds_ci.depthCompareOp = VK_COMPARE_OP_NEVER;
1897 ds_ci.stencilTestEnable = VK_TRUE;
1898 ds_ci.front = stencil;
1899 ds_ci.back = stencil;
1900
1901 CreatePipelineHelper g_pipe_ds(*this), g_pipe_dp(*this), g_pipe_st(*this);
1902 g_pipe_ds.InitInfo();
1903 g_pipe_ds.gp_ci_.renderPass = rp_ds.handle();
1904 g_pipe_ds.gp_ci_.pDepthStencilState = &ds_ci;
1905 g_pipe_ds.InitState();
1906 ASSERT_VK_SUCCESS(g_pipe_ds.CreateGraphicsPipeline());
1907 g_pipe_dp.InitInfo();
1908 g_pipe_dp.gp_ci_.renderPass = rp_dp.handle();
1909 ds_ci.stencilTestEnable = VK_FALSE;
1910 g_pipe_dp.gp_ci_.pDepthStencilState = &ds_ci;
1911 g_pipe_dp.InitState();
1912 ASSERT_VK_SUCCESS(g_pipe_dp.CreateGraphicsPipeline());
1913 g_pipe_st.InitInfo();
1914 g_pipe_st.gp_ci_.renderPass = rp_st.handle();
1915 ds_ci.depthTestEnable = VK_FALSE;
1916 ds_ci.stencilTestEnable = VK_TRUE;
1917 g_pipe_st.gp_ci_.pDepthStencilState = &ds_ci;
1918 g_pipe_st.InitState();
1919 ASSERT_VK_SUCCESS(g_pipe_st.CreateGraphicsPipeline());
1920
1921 m_commandBuffer->begin();
1922 m_renderPassBeginInfo.renderArea = {{0, 0}, {16, 16}};
1923 m_renderPassBeginInfo.pClearValues = nullptr;
1924 m_renderPassBeginInfo.clearValueCount = 0;
1925
1926 m_renderPassBeginInfo.renderPass = rp_ds.handle();
1927 m_renderPassBeginInfo.framebuffer = fb_ds;
1928 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1929 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_ds.pipeline_);
1930 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1931 m_commandBuffer->EndRenderPass();
1932
1933 m_renderPassBeginInfo.renderPass = rp_dp.handle();
1934 m_renderPassBeginInfo.framebuffer = fb_dp;
1935 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1936 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_dp.pipeline_);
1937 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1938 m_commandBuffer->EndRenderPass();
1939
1940 m_renderPassBeginInfo.renderPass = rp_st.handle();
1941 m_renderPassBeginInfo.framebuffer = fb_st;
1942 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1943 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_st.pipeline_);
1944 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1945 m_commandBuffer->EndRenderPass();
1946
1947 m_commandBuffer->end();
1948 m_errorMonitor->VerifyNotFound();
1949
1950 m_commandBuffer->reset();
1951 m_commandBuffer->begin();
1952
1953 VkImageCopy copyRegion;
1954 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
1955 copyRegion.srcSubresource.mipLevel = 0;
1956 copyRegion.srcSubresource.baseArrayLayer = 0;
1957 copyRegion.srcSubresource.layerCount = 1;
1958 copyRegion.srcOffset = {0, 0, 0};
1959 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
1960 copyRegion.dstSubresource.mipLevel = 0;
1961 copyRegion.dstSubresource.baseArrayLayer = 0;
1962 copyRegion.dstSubresource.layerCount = 1;
1963 copyRegion.dstOffset = {0, 0, 0};
1964 copyRegion.extent = {16, 16, 1};
1965
1966 m_commandBuffer->CopyImage(image_ds.handle(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, image_dp.handle(),
1967 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 1, &copyRegion);
1968
1969 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
1970 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
1971 m_commandBuffer->CopyImage(image_ds.handle(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, image_st.handle(),
1972 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 1, &copyRegion);
1973 m_renderPassBeginInfo.renderPass = rp_ds.handle();
1974 m_renderPassBeginInfo.framebuffer = fb_ds;
1975 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1976 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1977 m_errorMonitor->VerifyFound();
1978 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1979 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_ds.pipeline_);
1980 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1981 m_commandBuffer->EndRenderPass();
1982
1983 m_renderPassBeginInfo.renderPass = rp_dp.handle();
1984 m_renderPassBeginInfo.framebuffer = fb_dp;
1985 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1986 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1987 m_errorMonitor->VerifyFound();
1988 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1989 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_dp.pipeline_);
1990 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1991 m_commandBuffer->EndRenderPass();
1992
1993 m_renderPassBeginInfo.renderPass = rp_st.handle();
1994 m_renderPassBeginInfo.framebuffer = fb_st;
1995 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1996 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1997 m_errorMonitor->VerifyFound();
1998 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1999 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_st.pipeline_);
2000 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
2001 m_commandBuffer->EndRenderPass();
2002
2003 m_commandBuffer->end();
2004 vk::DestroyFramebuffer(m_device->device(), fb_ds, nullptr);
2005 vk::DestroyFramebuffer(m_device->device(), fb_dp, nullptr);
2006 vk::DestroyFramebuffer(m_device->device(), fb_st, nullptr);
2007}
2008
2009TEST_F(VkSyncValTest, RenderPassLoadHazardVsInitialLayout) {
2010 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
2011 ASSERT_NO_FATAL_FAILURE(InitState());
2012 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2013
2014 VkImageUsageFlags usage_color = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
2015 VkImageUsageFlags usage_input = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
2016 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
2017 VkImageObj image_color(m_device), image_input(m_device);
2018 auto image_ci = VkImageObj::ImageCreateInfo2D(32, 32, 1, 1, format, usage_color, VK_IMAGE_TILING_OPTIMAL);
2019 image_color.Init(image_ci);
2020 image_ci.usage = usage_input;
2021 image_input.Init(image_ci);
2022 VkImageView attachments[] = {image_color.targetView(format), image_input.targetView(format)};
2023
2024 const VkAttachmentDescription attachmentDescriptions[] = {
2025 // Result attachment
2026 {(VkAttachmentDescriptionFlags)0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR,
2027 VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
2028 VK_IMAGE_LAYOUT_UNDEFINED, // Here causes DesiredError that SYNC-HAZARD-NONE in BeginRenderPass.
2029 // It should be VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
2030 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
2031 // Input attachment
2032 {(VkAttachmentDescriptionFlags)0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD,
2033 VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
2034 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL}};
2035
2036 const VkAttachmentReference resultAttachmentRef = {0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
2037 const VkAttachmentReference inputAttachmentRef = {1u, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};
2038
2039 const VkSubpassDescription subpassDescription = {(VkSubpassDescriptionFlags)0,
2040 VK_PIPELINE_BIND_POINT_GRAPHICS,
2041 1u,
2042 &inputAttachmentRef,
2043 1u,
2044 &resultAttachmentRef,
2045 0,
2046 0,
2047 0u,
2048 0};
2049
2050 const VkSubpassDependency subpassDependency = {VK_SUBPASS_EXTERNAL,
2051 0,
2052 VK_PIPELINE_STAGE_TRANSFER_BIT,
2053 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
2054 VK_ACCESS_TRANSFER_WRITE_BIT,
2055 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | VK_ACCESS_SHADER_READ_BIT,
2056 VK_DEPENDENCY_BY_REGION_BIT};
2057
2058 const VkRenderPassCreateInfo renderPassInfo = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
2059 0,
2060 (VkRenderPassCreateFlags)0,
2061 2u,
2062 attachmentDescriptions,
2063 1u,
2064 &subpassDescription,
2065 1u,
2066 &subpassDependency};
2067 VkRenderPass rp;
2068 ASSERT_VK_SUCCESS(vk::CreateRenderPass(device(), &renderPassInfo, nullptr, &rp));
2069
2070 VkFramebuffer fb;
2071 VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 2, attachments, 32, 32, 1};
2072 ASSERT_VK_SUCCESS(vk::CreateFramebuffer(device(), &fbci, nullptr, &fb));
2073
2074 image_input.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
2075
2076 m_commandBuffer->begin();
2077
2078 m_renderPassBeginInfo.renderArea = {{0, 0}, {32, 32}};
2079 m_renderPassBeginInfo.renderPass = rp;
2080 m_renderPassBeginInfo.framebuffer = fb;
2081
2082 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
2083 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
2084 // Even though we have no accesses prior, the layout transition *is* an access, so load can be validated vs. layout transition
2085 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2086 m_errorMonitor->VerifyFound();
2087}
2088
2089TEST_F(VkSyncValTest, SyncRenderPassWithWrongDepthStencilInitialLayout) {
2090 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
2091 ASSERT_NO_FATAL_FAILURE(InitState());
2092 if (IsPlatform(kNexusPlayer)) {
2093 printf("%s This test should not run on Nexus Player\n", kSkipPrefix);
2094 return;
2095 }
2096
2097 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2098
2099 VkFormat color_format = VK_FORMAT_R8G8B8A8_UNORM;
2100 VkFormat ds_format = FindSupportedDepthStencilFormat(gpu());
2101 if (!ds_format) {
2102 printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix);
2103 return;
2104 }
2105 VkImageUsageFlags usage_color = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
2106 VkImageUsageFlags usage_ds = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
2107 VkImageObj image_color(m_device), image_color2(m_device);
2108 auto image_ci = VkImageObj::ImageCreateInfo2D(32, 32, 1, 1, color_format, usage_color, VK_IMAGE_TILING_OPTIMAL);
2109 image_color.Init(image_ci);
2110 image_color2.Init(image_ci);
2111 VkDepthStencilObj image_ds(m_device);
2112 image_ds.Init(m_device, 32, 32, ds_format, usage_ds);
2113
2114 const VkAttachmentDescription colorAttachmentDescription = {(VkAttachmentDescriptionFlags)0,
2115 color_format,
2116 VK_SAMPLE_COUNT_1_BIT,
2117 VK_ATTACHMENT_LOAD_OP_CLEAR,
2118 VK_ATTACHMENT_STORE_OP_STORE,
2119 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2120 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2121 VK_IMAGE_LAYOUT_UNDEFINED,
2122 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
2123
2124 const VkAttachmentDescription depthStencilAttachmentDescription = {
2125 (VkAttachmentDescriptionFlags)0, ds_format, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR,
2126 VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE,
2127 VK_IMAGE_LAYOUT_UNDEFINED, // Here causes DesiredError that SYNC-HAZARD-WRITE_AFTER_WRITE in BeginRenderPass.
2128 // It should be VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
2129 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
2130
2131 std::vector<VkAttachmentDescription> attachmentDescriptions;
2132 attachmentDescriptions.push_back(colorAttachmentDescription);
2133 attachmentDescriptions.push_back(depthStencilAttachmentDescription);
2134
2135 const VkAttachmentReference colorAttachmentRef = {0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
2136
2137 const VkAttachmentReference depthStencilAttachmentRef = {1u, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
2138
2139 const VkSubpassDescription subpassDescription = {(VkSubpassDescriptionFlags)0,
2140 VK_PIPELINE_BIND_POINT_GRAPHICS,
2141 0u,
2142 0,
2143 1u,
2144 &colorAttachmentRef,
2145 0,
2146 &depthStencilAttachmentRef,
2147 0u,
2148 0};
2149
2150 const VkRenderPassCreateInfo renderPassInfo = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
2151 0,
2152 (VkRenderPassCreateFlags)0,
2153 (uint32_t)attachmentDescriptions.size(),
2154 &attachmentDescriptions[0],
2155 1u,
2156 &subpassDescription,
2157 0u,
2158 0};
2159 VkRenderPass rp;
2160 ASSERT_VK_SUCCESS(vk::CreateRenderPass(device(), &renderPassInfo, nullptr, &rp));
2161
2162 VkImageView fb_attachments[] = {image_color.targetView(color_format),
2163 image_ds.targetView(ds_format, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)};
2164 const VkFramebufferCreateInfo fbci = {
2165 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, 0, 0u, rp, 2u, fb_attachments, 32, 32, 1u,
2166 };
2167 VkFramebuffer fb;
2168 ASSERT_VK_SUCCESS(vk::CreateFramebuffer(device(), &fbci, nullptr, &fb));
2169 fb_attachments[0] = image_color2.targetView(color_format);
2170 VkFramebuffer fb1;
2171 ASSERT_VK_SUCCESS(vk::CreateFramebuffer(device(), &fbci, nullptr, &fb1));
2172
2173 CreatePipelineHelper g_pipe(*this);
2174 g_pipe.InitInfo();
2175 g_pipe.gp_ci_.renderPass = rp;
2176
2177 VkStencilOpState stencil = {};
2178 stencil.failOp = VK_STENCIL_OP_KEEP;
2179 stencil.passOp = VK_STENCIL_OP_KEEP;
2180 stencil.depthFailOp = VK_STENCIL_OP_KEEP;
2181 stencil.compareOp = VK_COMPARE_OP_NEVER;
2182
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07002183 auto ds_ci = LvlInitStruct<VkPipelineDepthStencilStateCreateInfo>();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002184 ds_ci.depthTestEnable = VK_TRUE;
2185 ds_ci.depthWriteEnable = VK_TRUE;
2186 ds_ci.depthCompareOp = VK_COMPARE_OP_NEVER;
2187 ds_ci.stencilTestEnable = VK_TRUE;
2188 ds_ci.front = stencil;
2189 ds_ci.back = stencil;
2190
2191 g_pipe.gp_ci_.pDepthStencilState = &ds_ci;
2192 g_pipe.InitState();
2193 ASSERT_VK_SUCCESS(g_pipe.CreateGraphicsPipeline());
2194
2195 m_commandBuffer->begin();
2196 m_renderPassBeginInfo.renderArea = {{0, 0}, {32, 32}};
2197 m_renderPassBeginInfo.renderPass = rp;
2198
2199 m_renderPassBeginInfo.framebuffer = fb;
2200 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2201 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
2202 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
2203 m_commandBuffer->EndRenderPass();
2204
2205 m_renderPassBeginInfo.framebuffer = fb1;
2206
2207 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
2208 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2209 m_errorMonitor->VerifyFound();
2210}
2211
2212TEST_F(VkSyncValTest, SyncLayoutTransition) {
2213 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
2214 ASSERT_NO_FATAL_FAILURE(InitState());
2215 if (IsPlatform(kNexusPlayer)) {
2216 printf("%s This test should not run on Nexus Player\n", kSkipPrefix);
2217 return;
2218 }
2219
2220 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2221
2222 VkImageUsageFlags usage_color = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
2223 VkImageUsageFlags usage_input =
2224 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
2225 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
2226 VkImageObj image_color(m_device), image_input(m_device);
2227 auto image_ci = VkImageObj::ImageCreateInfo2D(64, 64, 1, 1, format, usage_input, VK_IMAGE_TILING_OPTIMAL);
2228 image_input.InitNoLayout(image_ci);
2229 image_ci.usage = usage_color;
2230 image_color.InitNoLayout(image_ci);
2231 VkImageView view_input = image_input.targetView(format);
2232 VkImageView view_color = image_color.targetView(format);
2233 VkImageView attachments[] = {view_color, view_input};
2234
2235 const VkAttachmentDescription fbAttachment = {
2236 0u,
2237 format,
2238 VK_SAMPLE_COUNT_1_BIT,
2239 VK_ATTACHMENT_LOAD_OP_CLEAR,
2240 VK_ATTACHMENT_STORE_OP_STORE,
2241 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2242 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2243 VK_IMAGE_LAYOUT_UNDEFINED,
2244 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
2245 };
2246
2247 std::vector<VkAttachmentDescription> attachmentDescs;
2248 attachmentDescs.push_back(fbAttachment);
2249
2250 // Add it as a frame buffer attachment.
2251 const VkAttachmentDescription inputAttachment = {
2252 0u,
2253 format,
2254 VK_SAMPLE_COUNT_1_BIT,
2255 VK_ATTACHMENT_LOAD_OP_LOAD,
2256 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2257 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2258 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2259 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
2260 VK_IMAGE_LAYOUT_GENERAL,
2261 };
2262 attachmentDescs.push_back(inputAttachment);
2263
2264 std::vector<VkAttachmentReference> inputAttachments;
2265 const VkAttachmentReference inputRef = {
2266 1u,
2267 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
2268 };
2269 inputAttachments.push_back(inputRef);
2270
2271 const VkAttachmentReference colorRef = {
2272 0u,
2273 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
2274 };
2275 const std::vector<VkAttachmentReference> colorAttachments(1u, colorRef);
2276
2277 const VkSubpassDescription subpass = {
2278 0u,
2279 VK_PIPELINE_BIND_POINT_GRAPHICS,
2280 static_cast<uint32_t>(inputAttachments.size()),
2281 inputAttachments.data(),
2282 static_cast<uint32_t>(colorAttachments.size()),
2283 colorAttachments.data(),
2284 0u,
2285 nullptr,
2286 0u,
2287 nullptr,
2288 };
2289 const std::vector<VkSubpassDescription> subpasses(1u, subpass);
2290
2291 const VkRenderPassCreateInfo renderPassInfo = {
2292 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
2293 nullptr,
2294 0u,
2295 static_cast<uint32_t>(attachmentDescs.size()),
2296 attachmentDescs.data(),
2297 static_cast<uint32_t>(subpasses.size()),
2298 subpasses.data(),
2299 0u,
2300 nullptr,
2301 };
2302 VkRenderPass rp;
2303 ASSERT_VK_SUCCESS(vk::CreateRenderPass(device(), &renderPassInfo, nullptr, &rp));
2304
2305 const VkFramebufferCreateInfo fbci = {
2306 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, 0, 0u, rp, 2u, attachments, 64, 64, 1u,
2307 };
2308 VkFramebuffer fb;
2309 ASSERT_VK_SUCCESS(vk::CreateFramebuffer(device(), &fbci, nullptr, &fb));
2310
2311 VkSampler sampler = VK_NULL_HANDLE;
2312 VkSamplerCreateInfo sampler_info = SafeSaneSamplerCreateInfo();
2313 vk::CreateSampler(m_device->device(), &sampler_info, NULL, &sampler);
2314
2315 char const *fsSource =
2316 "#version 450\n"
2317 "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n"
2318 "void main() {\n"
2319 " vec4 color = subpassLoad(x);\n"
2320 "}\n";
2321
2322 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
2323 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
2324
2325 CreatePipelineHelper g_pipe(*this);
2326 g_pipe.InitInfo();
2327 g_pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
2328 g_pipe.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
2329 g_pipe.gp_ci_.renderPass = rp;
2330 g_pipe.InitState();
2331 ASSERT_VK_SUCCESS(g_pipe.CreateGraphicsPipeline());
2332
2333 g_pipe.descriptor_set_->WriteDescriptorImageInfo(0, view_input, sampler, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
2334 g_pipe.descriptor_set_->UpdateDescriptorSets();
2335
2336 m_commandBuffer->begin();
2337 auto cb = m_commandBuffer->handle();
2338 VkClearColorValue ccv = {};
2339 VkImageSubresourceRange full_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
2340
2341 const VkImageMemoryBarrier preClearBarrier = {
2342 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, 0, 0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
2343 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, 0, image_input.handle(), full_subresource_range,
2344 };
2345 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u,
2346 &preClearBarrier);
2347
2348 vk::CmdClearColorImage(m_commandBuffer->handle(), image_input.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &ccv, 1,
2349 &full_subresource_range);
2350
2351 const VkImageMemoryBarrier postClearBarrier = {
2352 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
2353 0,
2354 VK_ACCESS_TRANSFER_WRITE_BIT,
2355 VK_ACCESS_SHADER_READ_BIT,
2356 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
2357 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
2358 0,
2359 0,
2360 image_input.handle(),
2361 full_subresource_range,
2362 };
2363 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u, nullptr, 0u, nullptr,
2364 1u, &postClearBarrier);
2365
2366 m_renderPassBeginInfo.renderArea = {{0, 0}, {64, 64}};
2367 m_renderPassBeginInfo.renderPass = rp;
2368 m_renderPassBeginInfo.framebuffer = fb;
2369
2370 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2371 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
2372 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
2373 &g_pipe.descriptor_set_->set_, 0, nullptr);
2374
2375 // Positive test for ordering rules between load and input attachment usage
2376 m_errorMonitor->ExpectSuccess();
2377 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
2378
2379 // Positive test for store ordering vs. input attachment and dependency *to* external for layout transition
2380 m_commandBuffer->EndRenderPass();
2381 m_errorMonitor->VerifyNotFound();
2382
2383 // Catch a conflict with the input attachment final layout transition
2384 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
2385 vk::CmdClearColorImage(m_commandBuffer->handle(), image_input.handle(), VK_IMAGE_LAYOUT_GENERAL, &ccv, 1,
2386 &full_subresource_range);
2387 m_errorMonitor->VerifyFound();
2388}
2389
2390TEST_F(VkSyncValTest, SyncSubpassMultiDep) {
2391 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
2392 ASSERT_NO_FATAL_FAILURE(InitState());
2393 if (IsPlatform(kNexusPlayer)) {
2394 printf("%s This test should not run on Nexus Player\n", kSkipPrefix);
2395 return;
2396 }
2397
2398 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2399
2400 VkImageUsageFlags usage_color = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
2401 VkImageUsageFlags usage_input =
2402 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
2403 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
2404 VkImageObj image_color(m_device), image_input(m_device);
2405 auto image_ci = VkImageObj::ImageCreateInfo2D(64, 64, 1, 1, format, usage_input, VK_IMAGE_TILING_OPTIMAL);
2406 image_input.InitNoLayout(image_ci);
2407 image_ci.usage = usage_color;
2408 image_color.InitNoLayout(image_ci);
2409 VkImageView view_input = image_input.targetView(format);
2410 VkImageView view_color = image_color.targetView(format);
2411 VkImageView attachments[] = {view_color, view_input};
2412 VkImageSubresourceRange full_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
2413 VkImageSubresourceLayers mip_0_layer_0{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
2414 VkOffset3D image_zero{0, 0, 0};
2415 VkExtent3D image_size{64, 64, 1};
2416 VkImageCopy full_region{mip_0_layer_0, image_zero, mip_0_layer_0, image_zero, image_size};
2417
2418 const VkAttachmentDescription fbAttachment = {
2419 0u,
2420 format,
2421 VK_SAMPLE_COUNT_1_BIT,
2422 VK_ATTACHMENT_LOAD_OP_CLEAR,
2423 VK_ATTACHMENT_STORE_OP_STORE,
2424 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2425 VK_ATTACHMENT_STORE_OP_STORE,
2426 VK_IMAGE_LAYOUT_GENERAL,
2427 VK_IMAGE_LAYOUT_GENERAL,
2428 };
2429
2430 std::vector<VkAttachmentDescription> attachmentDescs;
2431 attachmentDescs.push_back(fbAttachment);
2432
2433 // Add it as a frame buffer attachment.
2434 const VkAttachmentDescription inputAttachment = {
2435 0u,
2436 format,
2437 VK_SAMPLE_COUNT_1_BIT,
2438 VK_ATTACHMENT_LOAD_OP_LOAD,
2439 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2440 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2441 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2442 VK_IMAGE_LAYOUT_GENERAL,
2443 VK_IMAGE_LAYOUT_GENERAL,
2444 };
2445 attachmentDescs.push_back(inputAttachment);
2446
2447 std::vector<VkAttachmentReference> inputAttachments;
2448 const VkAttachmentReference inputRef = {
2449 1u,
2450 VK_IMAGE_LAYOUT_GENERAL,
2451 };
2452 inputAttachments.push_back(inputRef);
2453
2454 const VkAttachmentReference colorRef = {
2455 0u,
2456 VK_IMAGE_LAYOUT_GENERAL,
2457 };
2458 const std::vector<VkAttachmentReference> colorAttachments(1u, colorRef);
2459
2460 const VkSubpassDescription subpass = {
2461 0u,
2462 VK_PIPELINE_BIND_POINT_GRAPHICS,
2463 static_cast<uint32_t>(inputAttachments.size()),
2464 inputAttachments.data(),
2465 static_cast<uint32_t>(colorAttachments.size()),
2466 colorAttachments.data(),
2467 0u,
2468 nullptr,
2469 0u,
2470 nullptr,
2471 };
2472 const std::vector<VkSubpassDescription> subpasses(1u, subpass);
2473
2474 std::vector<VkSubpassDependency> subpass_dep_postive;
2475 subpass_dep_postive.push_back({VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_TRANSFER_BIT,
2476 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2477 VK_DEPENDENCY_VIEW_LOCAL_BIT});
2478 subpass_dep_postive.push_back({VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_TRANSFER_BIT,
2479 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_TRANSFER_WRITE_BIT,
2480 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, VK_DEPENDENCY_VIEW_LOCAL_BIT});
2481 subpass_dep_postive.push_back({0, VK_SUBPASS_EXTERNAL, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2482 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2483 VK_ACCESS_TRANSFER_READ_BIT, VK_DEPENDENCY_VIEW_LOCAL_BIT});
2484 subpass_dep_postive.push_back({0, VK_SUBPASS_EXTERNAL, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2485 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2486 VK_ACCESS_TRANSFER_WRITE_BIT, VK_DEPENDENCY_VIEW_LOCAL_BIT});
2487
2488 VkRenderPassCreateInfo renderPassInfo = {
2489 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
2490 nullptr,
2491 0u,
2492 static_cast<uint32_t>(attachmentDescs.size()),
2493 attachmentDescs.data(),
2494 static_cast<uint32_t>(subpasses.size()),
2495 subpasses.data(),
2496 static_cast<uint32_t>(subpass_dep_postive.size()),
2497 subpass_dep_postive.data(),
2498 };
2499 VkRenderPass rp_positive;
2500 ASSERT_VK_SUCCESS(vk::CreateRenderPass(device(), &renderPassInfo, nullptr, &rp_positive));
2501
2502 std::vector<VkSubpassDependency> subpass_dep_negative;
2503 subpass_dep_negative.push_back({VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_TRANSFER_BIT,
2504 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2505 VK_DEPENDENCY_VIEW_LOCAL_BIT});
2506 // Show that the two barriers do *not* chain by breaking the positive barrier into two bits.
2507 subpass_dep_negative.push_back({VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_TRANSFER_BIT,
2508 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, 0,
2509 VK_DEPENDENCY_VIEW_LOCAL_BIT});
2510 subpass_dep_negative.push_back({VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2511 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
2512 VK_DEPENDENCY_VIEW_LOCAL_BIT});
2513
2514 renderPassInfo.dependencyCount = static_cast<uint32_t>(subpass_dep_negative.size());
2515 renderPassInfo.pDependencies = subpass_dep_negative.data();
2516 VkRenderPass rp_negative;
2517 ASSERT_VK_SUCCESS(vk::CreateRenderPass(device(), &renderPassInfo, nullptr, &rp_negative));
2518
2519 // rp_postive and rp_negative should be compatible for the same fb object
2520 const VkFramebufferCreateInfo fbci = {
2521 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, 0, 0u, rp_positive, 2u, attachments, 64, 64, 1u,
2522 };
2523 VkFramebuffer fb;
2524 ASSERT_VK_SUCCESS(vk::CreateFramebuffer(device(), &fbci, nullptr, &fb));
2525
2526 VkSampler sampler = VK_NULL_HANDLE;
2527 VkSamplerCreateInfo sampler_info = SafeSaneSamplerCreateInfo();
2528 vk::CreateSampler(m_device->device(), &sampler_info, NULL, &sampler);
2529
2530 char const *fsSource =
2531 "#version 450\n"
2532 "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n"
2533 "void main() {\n"
2534 " vec4 color = subpassLoad(x);\n"
2535 "}\n";
2536
2537 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
2538 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
2539
2540 CreatePipelineHelper g_pipe(*this);
2541 g_pipe.InitInfo();
2542 g_pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
2543 g_pipe.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
2544 g_pipe.gp_ci_.renderPass = rp_positive;
2545 g_pipe.InitState();
2546 ASSERT_VK_SUCCESS(g_pipe.CreateGraphicsPipeline());
2547
2548 g_pipe.descriptor_set_->WriteDescriptorImageInfo(0, view_input, sampler, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
2549 g_pipe.descriptor_set_->UpdateDescriptorSets();
2550
2551 m_commandBuffer->begin();
2552 auto cb = m_commandBuffer->handle();
2553 VkClearColorValue ccv = {};
2554
2555 const VkImageMemoryBarrier xferDestBarrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
2556 nullptr,
2557 VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT,
2558 VK_ACCESS_TRANSFER_WRITE_BIT,
2559 VK_IMAGE_LAYOUT_GENERAL,
2560 VK_IMAGE_LAYOUT_GENERAL,
2561 VK_QUEUE_FAMILY_IGNORED,
2562 VK_QUEUE_FAMILY_IGNORED,
2563 VK_NULL_HANDLE,
2564 full_subresource_range};
2565 const VkImageMemoryBarrier xferDestToSrcBarrier = {
2566 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
2567 nullptr,
2568 VK_ACCESS_TRANSFER_WRITE_BIT,
2569 VK_ACCESS_TRANSFER_READ_BIT,
2570 VK_IMAGE_LAYOUT_GENERAL,
2571 VK_IMAGE_LAYOUT_GENERAL,
2572 VK_QUEUE_FAMILY_IGNORED,
2573 VK_QUEUE_FAMILY_IGNORED,
2574 VK_NULL_HANDLE,
2575 full_subresource_range,
2576 };
2577
2578 VkImageMemoryBarrier preClearBarrier = xferDestBarrier;
2579 preClearBarrier.image = image_color.handle();
2580
2581 VkImageMemoryBarrier preCopyBarriers[2] = {xferDestToSrcBarrier, xferDestBarrier};
2582 preCopyBarriers[0].image = image_color.handle();
2583 preCopyBarriers[1].image = image_input.handle();
2584 // Positive test for ordering rules between load and input attachment usage
2585 m_errorMonitor->ExpectSuccess();
2586
2587 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u,
2588 &preClearBarrier);
2589
2590 vk::CmdClearColorImage(m_commandBuffer->handle(), image_color.handle(), VK_IMAGE_LAYOUT_GENERAL, &ccv, 1,
2591 &full_subresource_range);
2592
2593 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 2u,
2594 preCopyBarriers);
2595
2596 vk::CmdCopyImage(m_commandBuffer->handle(), image_color.handle(), VK_IMAGE_LAYOUT_GENERAL, image_input.handle(),
2597 VK_IMAGE_LAYOUT_GENERAL, 1u, &full_region);
2598
2599 // No post copy image barrier, we are testing the subpass dependencies
2600
2601 m_renderPassBeginInfo.renderArea = {{0, 0}, {64, 64}};
2602 m_renderPassBeginInfo.renderPass = rp_positive;
2603 m_renderPassBeginInfo.framebuffer = fb;
2604
2605 // Postive renderpass multidependency test
2606 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2607 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
2608 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
2609 &g_pipe.descriptor_set_->set_, 0, nullptr);
2610
2611 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
2612
2613 // Positive test for store ordering vs. input attachment and dependency *to* external for layout transition
2614 m_commandBuffer->EndRenderPass();
2615 // m_errorMonitor->VerifyNotFound();
2616
2617 vk::CmdCopyImage(m_commandBuffer->handle(), image_color.handle(), VK_IMAGE_LAYOUT_GENERAL, image_input.handle(),
2618 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &full_region);
2619 m_errorMonitor->VerifyNotFound();
2620
2621 m_renderPassBeginInfo.renderArea = {{0, 0}, {64, 64}};
2622 m_renderPassBeginInfo.renderPass = rp_negative;
2623 m_renderPassBeginInfo.framebuffer = fb;
2624
2625 // Postive renderpass multidependency test, will fail IFF the dependencies are acting indepently.
2626 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "SYNC-HAZARD-READ_AFTER_WRITE");
2627 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2628 m_errorMonitor->VerifyFound();
2629}
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002630
2631TEST_F(VkSyncValTest, RenderPassAsyncHazard) {
2632 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
2633 ASSERT_NO_FATAL_FAILURE(InitState());
2634
2635 // overall set up:
2636 // subpass 0:
2637 // write image 0
2638 // subpass 1:
2639 // read image 0
2640 // write image 1
2641 // subpass 2:
2642 // read image 0
2643 // write image 2
2644 // subpass 3:
2645 // read image 0
2646 // write image 3
2647 //
2648 // subpasses 1 & 2 can run in parallel but both should depend on 0
2649 // subpass 3 must run after 1 & 2 because otherwise the store operation will
2650 // race with the reads in the other subpasses.
2651
2652 constexpr VkFormat kFormat = VK_FORMAT_R8G8B8A8_UNORM;
2653 constexpr uint32_t kWidth = 32, kHeight = 32;
2654 constexpr uint32_t kNumImages = 4;
2655
2656 VkImageCreateInfo src_img_info = {};
2657 src_img_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2658 src_img_info.pNext = NULL;
2659 src_img_info.flags = 0;
2660 src_img_info.imageType = VK_IMAGE_TYPE_2D;
2661 src_img_info.format = kFormat;
2662 src_img_info.extent = {kWidth, kHeight, 1};
2663 src_img_info.mipLevels = 1;
2664 src_img_info.arrayLayers = 1;
2665 src_img_info.samples = VK_SAMPLE_COUNT_2_BIT;
2666 src_img_info.tiling = VK_IMAGE_TILING_OPTIMAL;
2667 src_img_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
2668 src_img_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2669 src_img_info.queueFamilyIndexCount = 0;
2670 src_img_info.pQueueFamilyIndices = nullptr;
2671 src_img_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2672
2673 VkImageCreateInfo dst_img_info = {};
2674 dst_img_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2675 dst_img_info.pNext = nullptr;
2676 dst_img_info.flags = 0;
2677 dst_img_info.imageType = VK_IMAGE_TYPE_2D;
2678 dst_img_info.format = kFormat;
2679 dst_img_info.extent = {kWidth, kHeight, 1};
2680 dst_img_info.mipLevels = 1;
2681 dst_img_info.arrayLayers = 1;
2682 dst_img_info.samples = VK_SAMPLE_COUNT_1_BIT;
2683 dst_img_info.tiling = VK_IMAGE_TILING_OPTIMAL;
2684 dst_img_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
2685 dst_img_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2686 dst_img_info.queueFamilyIndexCount = 0;
2687 dst_img_info.pQueueFamilyIndices = nullptr;
2688 dst_img_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2689
2690 std::vector<std::unique_ptr<VkImageObj>> images;
2691 for (uint32_t i = 0; i < kNumImages; i++) {
2692 images.emplace_back(new VkImageObj(m_device));
2693 }
2694 images[0]->Init(src_img_info);
2695 for (uint32_t i = 1; i < images.size(); i++) {
2696 images[i]->Init(dst_img_info);
2697 }
2698
2699 std::array<VkImageView, kNumImages> attachments{};
2700 std::array<VkAttachmentDescription, kNumImages> attachment_descriptions{};
2701 std::array<VkAttachmentReference, kNumImages> color_refs{};
2702 std::array<VkImageMemoryBarrier, kNumImages> img_barriers{};
2703
2704 for (uint32_t i = 0; i < attachments.size(); i++) {
2705 attachments[i] = images[i]->targetView(kFormat);
2706 attachment_descriptions[i] = {};
2707 attachment_descriptions[i].flags = 0;
2708 attachment_descriptions[i].format = kFormat;
2709 attachment_descriptions[i].samples = VK_SAMPLE_COUNT_1_BIT;
2710 attachment_descriptions[i].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
2711 attachment_descriptions[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
2712 attachment_descriptions[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
2713 attachment_descriptions[i].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
2714 attachment_descriptions[i].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
2715 attachment_descriptions[i].finalLayout =
2716 (i == 0) ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
2717
2718 color_refs[i] = {i, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
2719
2720 img_barriers[i].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
2721 img_barriers[i].srcAccessMask = 0;
2722 img_barriers[i].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
2723 img_barriers[i].oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2724 img_barriers[i].newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
2725 img_barriers[i].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
2726 img_barriers[i].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
2727 img_barriers[i].image = images[i]->handle();
2728 img_barriers[i].subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS};
2729 }
2730
2731 const VkAttachmentReference input_ref{0u, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};
2732
2733 std::array<std::array<uint32_t, 2>, kNumImages - 1> preserve_subpass{{{2, 3}, {1, 3}, {1, 2}}};
2734
2735 std::array<VkSubpassDescription, kNumImages> subpasses{};
2736
2737 subpasses[0].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
2738 subpasses[0].inputAttachmentCount = 0;
2739 subpasses[0].pInputAttachments = nullptr;
2740 subpasses[0].colorAttachmentCount = 1;
2741 subpasses[0].pColorAttachments = &color_refs[0];
2742
2743 for (uint32_t i = 1; i < subpasses.size(); i++) {
2744 subpasses[i].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
2745 subpasses[i].inputAttachmentCount = 1;
2746 subpasses[i].pInputAttachments = &input_ref;
2747 subpasses[i].colorAttachmentCount = 1;
2748 subpasses[i].pColorAttachments = &color_refs[1];
2749 subpasses[i].preserveAttachmentCount = preserve_subpass[i - 1].size();
2750 subpasses[i].pPreserveAttachments = preserve_subpass[i - 1].data();
2751 }
2752
2753 VkRenderPassCreateInfo renderpass_info = {};
2754 renderpass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
2755 renderpass_info.pNext = nullptr;
2756 renderpass_info.flags = 0;
2757 renderpass_info.attachmentCount = attachment_descriptions.size();
2758 renderpass_info.pAttachments = attachment_descriptions.data();
2759 renderpass_info.subpassCount = subpasses.size();
2760 renderpass_info.pSubpasses = subpasses.data();
2761 renderpass_info.dependencyCount = 0;
2762 renderpass_info.pDependencies = nullptr;
2763
2764 VkFramebufferCreateInfo fbci = {};
2765 fbci.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
2766 fbci.pNext = nullptr;
2767 fbci.flags = 0;
2768 fbci.attachmentCount = attachments.size();
2769 fbci.pAttachments = attachments.data();
2770 fbci.width = kWidth;
2771 fbci.height = kHeight;
2772 fbci.layers = 1;
2773
2774 VkSampler sampler = VK_NULL_HANDLE;
2775 VkSamplerCreateInfo sampler_info = SafeSaneSamplerCreateInfo();
2776 vk::CreateSampler(m_device->device(), &sampler_info, NULL, &sampler);
2777
2778 char const *fsSource =
2779 "#version 450\n"
2780 "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n"
2781 "void main() {\n"
2782 " vec4 color = subpassLoad(x);\n"
2783 "}\n";
2784
2785 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
2786 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
2787
2788 VkClearValue clear = {};
2789 clear.color = m_clear_color;
2790 std::array<VkClearValue, 3> clear_values = {{clear, clear, clear}};
2791
2792 // run the renderpass with no dependencies
2793 {
2794 VkRenderPass rp;
2795 VkFramebuffer fb;
2796 ASSERT_VK_SUCCESS(vk::CreateRenderPass(device(), &renderpass_info, nullptr, &rp));
2797
2798 fbci.renderPass = rp;
2799 ASSERT_VK_SUCCESS(vk::CreateFramebuffer(device(), &fbci, nullptr, &fb));
2800
2801 CreatePipelineHelper g_pipe_0(*this);
2802 g_pipe_0.InitInfo();
2803 g_pipe_0.gp_ci_.renderPass = rp;
2804 g_pipe_0.InitState();
2805 ASSERT_VK_SUCCESS(g_pipe_0.CreateGraphicsPipeline());
2806
2807 CreatePipelineHelper g_pipe_12(*this);
2808 g_pipe_12.InitInfo();
2809 g_pipe_12.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
2810 g_pipe_12.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
2811 g_pipe_12.gp_ci_.renderPass = rp;
2812 g_pipe_12.InitState();
2813 ASSERT_VK_SUCCESS(g_pipe_12.CreateGraphicsPipeline());
2814
2815 g_pipe_12.descriptor_set_->WriteDescriptorImageInfo(0, attachments[0], sampler, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
2816 g_pipe_12.descriptor_set_->UpdateDescriptorSets();
2817
2818 m_commandBuffer->begin();
2819
2820 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
2821 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0, nullptr, img_barriers.size(),
2822 img_barriers.data());
2823
2824 m_renderPassBeginInfo.renderArea = {{0, 0}, {16, 16}};
2825 m_renderPassBeginInfo.pClearValues = clear_values.data();
2826 m_renderPassBeginInfo.clearValueCount = clear_values.size();
2827
2828 m_renderPassBeginInfo.renderArea = {{0, 0}, {kWidth, kHeight}};
2829 m_renderPassBeginInfo.renderPass = rp;
2830 m_renderPassBeginInfo.framebuffer = fb;
2831
2832 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
2833 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_);
2834 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_layout_.handle(), 0,
2835 1, &g_pipe_0.descriptor_set_->set_, 0, NULL);
2836
2837 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
2838
2839 for (uint32_t i = 1; i < subpasses.size(); i++) {
2840 vk::CmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
2841 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_12.pipeline_);
2842 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS,
2843 g_pipe_12.pipeline_layout_.handle(), 0, 1, &g_pipe_12.descriptor_set_->set_, 0, NULL);
2844
2845 // we're racing the writes from subpass 0 with our shader reads
2846 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ-RACING-WRITE");
2847 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
2848 m_errorMonitor->VerifyFound();
2849 }
2850
2851 // we should get an error from async checking in both subpasses 2 & 3
2852 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE-RACING-WRITE");
2853 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE-RACING-WRITE");
2854 vk::CmdEndRenderPass(m_commandBuffer->handle());
2855 m_errorMonitor->VerifyFound();
2856
2857 m_commandBuffer->end();
2858
2859 vk::DestroyFramebuffer(device(), fb, nullptr);
2860 vk::DestroyRenderPass(device(), rp, nullptr);
2861 }
2862
2863 // add dependencies from subpass 0 to the others, which are necessary but not sufficient
2864 std::vector<VkSubpassDependency> subpass_dependencies;
2865 for (uint32_t i = 1; i < subpasses.size(); i++) {
2866 VkSubpassDependency dep{0,
2867 i,
2868 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2869 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
2870 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2871 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
2872 0};
2873 subpass_dependencies.push_back(dep);
2874 }
2875 renderpass_info.dependencyCount = subpass_dependencies.size();
2876 renderpass_info.pDependencies = subpass_dependencies.data();
2877
2878 {
2879 VkRenderPass rp;
2880 VkFramebuffer fb;
2881 ASSERT_VK_SUCCESS(vk::CreateRenderPass(device(), &renderpass_info, nullptr, &rp));
2882
2883 fbci.renderPass = rp;
2884 ASSERT_VK_SUCCESS(vk::CreateFramebuffer(device(), &fbci, nullptr, &fb));
2885
2886 CreatePipelineHelper g_pipe_0(*this);
2887 g_pipe_0.InitInfo();
2888 g_pipe_0.gp_ci_.renderPass = rp;
2889 g_pipe_0.InitState();
2890 ASSERT_VK_SUCCESS(g_pipe_0.CreateGraphicsPipeline());
2891
2892 CreatePipelineHelper g_pipe_12(*this);
2893 g_pipe_12.InitInfo();
2894 g_pipe_12.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
2895 g_pipe_12.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
2896 g_pipe_12.gp_ci_.renderPass = rp;
2897 g_pipe_12.InitState();
2898 ASSERT_VK_SUCCESS(g_pipe_12.CreateGraphicsPipeline());
2899
2900 g_pipe_12.descriptor_set_->WriteDescriptorImageInfo(0, attachments[0], sampler, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
2901 g_pipe_12.descriptor_set_->UpdateDescriptorSets();
2902
2903 m_commandBuffer->begin();
2904
2905 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
2906 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0, nullptr, img_barriers.size(),
2907 img_barriers.data());
2908
2909 m_renderPassBeginInfo.renderArea = {{0, 0}, {16, 16}};
2910 m_renderPassBeginInfo.pClearValues = clear_values.data();
2911 m_renderPassBeginInfo.clearValueCount = clear_values.size();
2912
2913 m_renderPassBeginInfo.renderArea = {{0, 0}, {kWidth, kHeight}};
2914 m_renderPassBeginInfo.renderPass = rp;
2915 m_renderPassBeginInfo.framebuffer = fb;
2916
2917 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
2918 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_);
2919 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_layout_.handle(), 0,
2920 1, &g_pipe_0.descriptor_set_->set_, 0, NULL);
2921
2922 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
2923
2924 m_errorMonitor->ExpectSuccess();
2925 for (uint32_t i = 1; i < subpasses.size(); i++) {
2926 vk::CmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
2927 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_12.pipeline_);
2928 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS,
2929 g_pipe_12.pipeline_layout_.handle(), 0, 1, &g_pipe_12.descriptor_set_->set_, 0, NULL);
2930 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
2931 }
2932 m_errorMonitor->VerifyNotFound();
2933 // expect this error because 2 subpasses could try to do the store operation
2934 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE-RACING-WRITE");
2935 // ... and this one because the store could happen during a shader read from another subpass
2936 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE-RACING-READ");
2937 vk::CmdEndRenderPass(m_commandBuffer->handle());
2938 m_errorMonitor->VerifyFound();
2939
2940 m_commandBuffer->end();
2941
2942 m_errorMonitor->VerifyFound();
2943 vk::DestroyFramebuffer(device(), fb, nullptr);
2944 vk::DestroyRenderPass(device(), rp, nullptr);
2945 }
2946
2947 // try again with correct dependencies to make subpass 3 depend on 1 & 2
2948 for (uint32_t i = 1; i < (subpasses.size() - 1); i++) {
2949 VkSubpassDependency dep{i,
2950 static_cast<uint32_t>(subpasses.size() - 1),
2951 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2952 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
2953 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2954 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
2955 0};
2956 subpass_dependencies.push_back(dep);
2957 }
2958 renderpass_info.dependencyCount = subpass_dependencies.size();
2959 renderpass_info.pDependencies = subpass_dependencies.data();
2960 {
2961 VkRenderPass rp;
2962 VkFramebuffer fb;
2963 ASSERT_VK_SUCCESS(vk::CreateRenderPass(device(), &renderpass_info, nullptr, &rp));
2964
2965 fbci.renderPass = rp;
2966 ASSERT_VK_SUCCESS(vk::CreateFramebuffer(device(), &fbci, nullptr, &fb));
2967
2968 CreatePipelineHelper g_pipe_0(*this);
2969 g_pipe_0.InitInfo();
2970 g_pipe_0.gp_ci_.renderPass = rp;
2971 g_pipe_0.InitState();
2972 ASSERT_VK_SUCCESS(g_pipe_0.CreateGraphicsPipeline());
2973
2974 CreatePipelineHelper g_pipe_12(*this);
2975 g_pipe_12.InitInfo();
2976 g_pipe_12.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
2977 g_pipe_12.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
2978 g_pipe_12.gp_ci_.renderPass = rp;
2979 g_pipe_12.InitState();
2980 ASSERT_VK_SUCCESS(g_pipe_12.CreateGraphicsPipeline());
2981
2982 g_pipe_12.descriptor_set_->WriteDescriptorImageInfo(0, attachments[0], sampler, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
2983 g_pipe_12.descriptor_set_->UpdateDescriptorSets();
2984
2985 m_errorMonitor->ExpectSuccess();
2986 m_commandBuffer->begin();
2987 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
2988 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0, nullptr, img_barriers.size(),
2989 img_barriers.data());
2990
2991 m_renderPassBeginInfo.renderArea = {{0, 0}, {16, 16}};
2992 m_renderPassBeginInfo.pClearValues = clear_values.data();
2993 m_renderPassBeginInfo.clearValueCount = clear_values.size();
2994
2995 m_renderPassBeginInfo.renderArea = {{0, 0}, {kWidth, kHeight}};
2996 m_renderPassBeginInfo.renderPass = rp;
2997 m_renderPassBeginInfo.framebuffer = fb;
2998
2999 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
3000 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_);
3001 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_layout_.handle(), 0,
3002 1, &g_pipe_0.descriptor_set_->set_, 0, NULL);
3003
3004 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
3005
3006 for (uint32_t i = 1; i < subpasses.size(); i++) {
3007 vk::CmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
3008 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_12.pipeline_);
3009 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS,
3010 g_pipe_12.pipeline_layout_.handle(), 0, 1, &g_pipe_12.descriptor_set_->set_, 0, NULL);
3011 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
3012 }
3013
3014 vk::CmdEndRenderPass(m_commandBuffer->handle());
3015
3016 m_commandBuffer->end();
3017
3018 m_errorMonitor->VerifyNotFound();
3019 vk::DestroyFramebuffer(device(), fb, nullptr);
3020 vk::DestroyRenderPass(device(), rp, nullptr);
3021 }
3022}
John Zulauf025ee442020-12-15 11:44:19 -07003023
3024TEST_F(VkSyncValTest, SyncEventsBufferCopy) {
3025 TEST_DESCRIPTION("Check Set/Wait protection for a variety of use cases using buffer copies");
3026 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
3027 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
3028
3029 VkBufferObj buffer_a;
3030 VkBufferObj buffer_b;
3031 VkBufferObj buffer_c;
3032 VkMemoryPropertyFlags mem_prop = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
3033 buffer_a.init_as_src_and_dst(*m_device, 256, mem_prop);
3034 buffer_b.init_as_src_and_dst(*m_device, 256, mem_prop);
3035 buffer_c.init_as_src_and_dst(*m_device, 256, mem_prop);
3036
3037 VkBufferCopy region = {0, 0, 256};
3038 VkBufferCopy front2front = {0, 0, 128};
3039 VkBufferCopy front2back = {0, 128, 128};
3040 VkBufferCopy back2back = {128, 128, 128};
3041
3042 VkEventObj event;
3043 event.init(*m_device, VkEventObj::create_info(0));
3044 VkEvent event_handle = event.handle();
3045
3046 auto cb = m_commandBuffer->handle();
3047 m_commandBuffer->begin();
3048
3049 // Copy after set for WAR (note we are writing to the back half of c but only reading from the front
3050 m_errorMonitor->ExpectSuccess();
3051 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &region);
3052 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3053 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_c.handle(), 1, &back2back);
3054 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3055 nullptr, 0, nullptr);
3056 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &front2front);
3057 m_errorMonitor->VerifyNotFound();
3058 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
3059 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &front2back);
3060 m_errorMonitor->VerifyFound();
3061 m_commandBuffer->end();
3062
3063 // WAR prevented
3064 m_commandBuffer->reset();
3065 m_commandBuffer->begin();
3066 m_errorMonitor->ExpectSuccess();
3067 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &region);
3068 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3069 // Just protect against WAR, only need a sync barrier.
3070 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3071 nullptr, 0, nullptr);
3072 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &region);
3073 m_errorMonitor->VerifyNotFound();
3074
3075 // Wait shouldn't prevent this WAW though, as it's only a synchronization barrier
3076 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
3077 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_b.handle(), 1, &region);
3078 m_errorMonitor->VerifyFound();
3079 m_commandBuffer->end();
3080
3081 // Prevent WAR and WAW
3082 m_commandBuffer->reset();
3083 m_commandBuffer->begin();
3084 m_errorMonitor->ExpectSuccess();
3085 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &region);
3086 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07003087 auto mem_barrier_waw = LvlInitStruct<VkMemoryBarrier>();
John Zulauf025ee442020-12-15 11:44:19 -07003088 mem_barrier_waw.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3089 mem_barrier_waw.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3090 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 1,
3091 &mem_barrier_waw, 0, nullptr, 0, nullptr);
3092 // The WAW should be safe (on a memory barrier)
3093 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_b.handle(), 1, &region);
3094 // The WAR should also be safe (on a sync barrier)
3095 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &region);
3096 m_errorMonitor->VerifyNotFound();
3097 m_commandBuffer->end();
3098
3099 // Barrier range check for WAW
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07003100 auto buffer_barrier_front_waw = LvlInitStruct<VkBufferMemoryBarrier>();
John Zulauf025ee442020-12-15 11:44:19 -07003101 buffer_barrier_front_waw.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3102 buffer_barrier_front_waw.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3103 buffer_barrier_front_waw.buffer = buffer_b.handle();
3104 buffer_barrier_front_waw.offset = front2front.dstOffset;
3105 buffer_barrier_front_waw.size = front2front.size;
3106
3107 // Front safe, back WAW
3108 m_commandBuffer->reset();
3109 m_commandBuffer->begin();
3110 m_errorMonitor->ExpectSuccess();
3111 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &region);
3112 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3113 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 1,
3114 &buffer_barrier_front_waw, 0, nullptr);
3115 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &front2front);
3116 m_errorMonitor->VerifyNotFound();
3117 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
3118 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &back2back);
3119 m_errorMonitor->VerifyFound();
3120 m_commandBuffer->end();
3121}
3122
3123TEST_F(VkSyncValTest, SyncEventsCopyImageHazards) {
3124 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
3125 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
3126
3127 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3128 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
3129 VkImageObj image_a(m_device);
3130 auto image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 2, format, usage, VK_IMAGE_TILING_OPTIMAL);
3131 image_a.Init(image_ci);
3132 ASSERT_TRUE(image_a.initialized());
3133
3134 VkImageObj image_b(m_device);
3135 image_b.Init(image_ci);
3136 ASSERT_TRUE(image_b.initialized());
3137
3138 VkImageObj image_c(m_device);
3139 image_c.Init(image_ci);
3140 ASSERT_TRUE(image_c.initialized());
3141
3142 VkEventObj event;
3143 event.init(*m_device, VkEventObj::create_info(0));
3144 VkEvent event_handle = event.handle();
3145
3146 VkImageSubresourceLayers layers_all{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 2};
3147 VkImageSubresourceLayers layers_0{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
3148 VkImageSubresourceLayers layers_1{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1};
3149 VkImageSubresourceRange layers_0_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
3150 VkOffset3D zero_offset{0, 0, 0};
3151 VkOffset3D half_offset{64, 64, 0};
3152 VkExtent3D full_extent{128, 128, 1}; // <-- image type is 2D
3153 VkExtent3D half_extent{64, 64, 1}; // <-- image type is 2D
3154
3155 VkImageCopy full_region = {layers_all, zero_offset, layers_all, zero_offset, full_extent};
3156 VkImageCopy region_0_to_0 = {layers_0, zero_offset, layers_0, zero_offset, full_extent};
3157 VkImageCopy region_1_to_1 = {layers_1, zero_offset, layers_1, zero_offset, full_extent};
3158 VkImageCopy region_0_q0toq0 = {layers_0, zero_offset, layers_0, zero_offset, half_extent};
3159 VkImageCopy region_0_q0toq3 = {layers_0, zero_offset, layers_0, half_offset, half_extent};
3160 VkImageCopy region_0_q3toq3 = {layers_0, half_offset, layers_0, half_offset, half_extent};
3161
3162 auto cb = m_commandBuffer->handle();
3163 auto copy_general = [cb](const VkImageObj &from, const VkImageObj &to, const VkImageCopy &region) {
3164 vk::CmdCopyImage(cb, from.handle(), VK_IMAGE_LAYOUT_GENERAL, to.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
3165 };
3166
3167 auto set_layouts = [this, &image_a, &image_b, &image_c]() {
3168 image_c.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
3169 image_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
3170 image_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
3171 };
3172
John Zulaufdd462092020-12-18 12:00:35 -07003173 // Scope check. One access in, one access not
John Zulauf025ee442020-12-15 11:44:19 -07003174 m_commandBuffer->begin();
3175 set_layouts();
3176 m_errorMonitor->ExpectSuccess();
3177 copy_general(image_a, image_b, full_region);
3178 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3179 copy_general(image_a, image_c, region_0_q3toq3);
3180 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3181 nullptr, 0, nullptr);
3182 copy_general(image_c, image_a, region_0_q0toq0);
3183 m_errorMonitor->VerifyNotFound();
3184 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
3185 copy_general(image_c, image_a, region_0_q0toq3);
3186 m_errorMonitor->VerifyFound();
3187 m_commandBuffer->end();
3188
3189 // WAR prevented
3190 m_commandBuffer->reset();
3191 m_commandBuffer->begin();
3192 set_layouts();
3193 m_errorMonitor->ExpectSuccess();
3194 copy_general(image_a, image_b, full_region);
3195 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3196 // Just protect against WAR, only need a sync barrier.
3197 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3198 nullptr, 0, nullptr);
3199 copy_general(image_c, image_a, full_region);
3200 m_errorMonitor->VerifyNotFound();
3201
3202 // Wait shouldn't prevent this WAW though, as it's only a synchronization barrier
3203 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
3204 copy_general(image_c, image_b, full_region);
3205 m_errorMonitor->VerifyFound();
3206 m_commandBuffer->end();
3207
3208 // Prevent WAR and WAW
3209 m_commandBuffer->reset();
3210 m_commandBuffer->begin();
3211 m_errorMonitor->ExpectSuccess();
3212 set_layouts();
3213 copy_general(image_a, image_b, full_region);
3214 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07003215 auto mem_barrier_waw = LvlInitStruct<VkMemoryBarrier>();
John Zulauf025ee442020-12-15 11:44:19 -07003216 mem_barrier_waw.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3217 mem_barrier_waw.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3218 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 1,
3219 &mem_barrier_waw, 0, nullptr, 0, nullptr);
3220 // The WAW should be safe (on a memory barrier)
3221 copy_general(image_c, image_b, full_region);
3222 // The WAR should also be safe (on a sync barrier)
3223 copy_general(image_c, image_a, full_region);
3224 m_errorMonitor->VerifyNotFound();
3225 m_commandBuffer->end();
3226
3227 // Barrier range check for WAW
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07003228 auto image_barrier_region0_waw = LvlInitStruct<VkImageMemoryBarrier>();
John Zulauf025ee442020-12-15 11:44:19 -07003229 image_barrier_region0_waw.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3230 image_barrier_region0_waw.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3231 image_barrier_region0_waw.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
3232 image_barrier_region0_waw.newLayout = VK_IMAGE_LAYOUT_GENERAL;
3233 image_barrier_region0_waw.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
3234 image_barrier_region0_waw.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
3235 image_barrier_region0_waw.image = image_b.handle();
3236 image_barrier_region0_waw.subresourceRange = layers_0_subresource_range;
3237
3238 // Region 0 safe, back WAW
3239 m_commandBuffer->reset();
3240 m_commandBuffer->begin();
3241 set_layouts();
3242 m_errorMonitor->ExpectSuccess();
3243 copy_general(image_a, image_b, full_region);
3244 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3245 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3246 nullptr, 1, &image_barrier_region0_waw);
3247 copy_general(image_a, image_b, region_0_to_0);
3248 m_errorMonitor->VerifyNotFound();
3249 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
3250 copy_general(image_a, image_b, region_1_to_1);
3251 m_errorMonitor->VerifyFound();
3252 m_commandBuffer->end();
3253}
John Zulauf4b5e4632020-12-15 11:48:59 -07003254
3255TEST_F(VkSyncValTest, SyncEventsCommandHazards) {
3256 TEST_DESCRIPTION("Check Set/Reset/Wait command hazard checking");
3257 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
3258 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
3259
3260 VkEventObj event;
3261 event.init(*m_device, VkEventObj::create_info(0));
3262
3263 const VkEvent event_handle = event.handle();
3264
3265 m_commandBuffer->begin();
3266 m_errorMonitor->ExpectSuccess();
3267 m_commandBuffer->ResetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3268 m_errorMonitor->VerifyNotFound();
3269
John Zulauf4edde622021-02-15 08:54:50 -07003270 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdResetEvent-event-03834");
John Zulauf4b5e4632020-12-15 11:48:59 -07003271 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdWaitEvents-srcStageMask-01158");
3272 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3273 nullptr, 0, nullptr);
3274 m_errorMonitor->VerifyFound();
3275 m_errorMonitor->ExpectSuccess();
3276 m_commandBuffer->end();
3277
3278 m_commandBuffer->begin();
3279 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3280 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, nullptr,
3281 0, nullptr, 0, nullptr);
3282 m_errorMonitor->VerifyNotFound();
3283 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-vkCmdResetEvent-missingbarrier-wait");
3284 m_commandBuffer->ResetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3285 m_errorMonitor->VerifyFound();
3286 m_errorMonitor->ExpectSuccess();
3287 m_commandBuffer->end();
3288
3289 m_commandBuffer->begin();
3290 m_commandBuffer->ResetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3291 m_errorMonitor->VerifyNotFound();
3292 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-vkCmdSetEvent-missingbarrier-reset");
3293 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3294 m_errorMonitor->VerifyFound();
3295
3296 m_errorMonitor->ExpectSuccess();
3297 m_commandBuffer->PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0U, 0, nullptr, 0,
3298 nullptr, 0, nullptr);
3299 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3300 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3301 nullptr, 0, nullptr);
3302 m_commandBuffer->ResetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3303 m_commandBuffer->PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0U, 0, nullptr, 0,
3304 nullptr, 0, nullptr);
3305 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3306 m_errorMonitor->VerifyNotFound();
3307
3308 // Need a barrier between set and a reset
3309 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-vkCmdResetEvent-missingbarrier-set");
3310 m_commandBuffer->ResetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3311 m_errorMonitor->VerifyFound();
3312 m_errorMonitor->ExpectSuccess();
3313 m_commandBuffer->end();
3314
3315 m_commandBuffer->begin();
3316 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3317 m_errorMonitor->VerifyNotFound();
3318 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-vkCmdSetEvent-missingbarrier-set");
3319 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3320 m_errorMonitor->VerifyFound();
3321
3322 m_commandBuffer->end();
3323}