blob: 3a18a8f9bbf93bcdaf423e3d3ce61d9012054c3d [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);
Jeremy Gebbend2573fc2021-05-12 17:17:38 -06001804 std::vector<VkQueueFamilyProperties> queue_props(queue_count);
1805 vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_count, queue_props.data());
Jeremy Gebben170781d2020-11-19 16:21:21 -07001806 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();
Tony-LunarG73f37032021-06-07 11:47:03 -06002196 VkClearValue clear = {};
2197 std::array<VkClearValue, 2> clear_values = { {clear, clear} };
2198 m_renderPassBeginInfo.pClearValues = clear_values.data();
2199 m_renderPassBeginInfo.clearValueCount = clear_values.size();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002200 m_renderPassBeginInfo.renderArea = {{0, 0}, {32, 32}};
2201 m_renderPassBeginInfo.renderPass = rp;
2202
2203 m_renderPassBeginInfo.framebuffer = fb;
2204 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2205 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
2206 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
2207 m_commandBuffer->EndRenderPass();
2208
2209 m_renderPassBeginInfo.framebuffer = fb1;
2210
2211 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
2212 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2213 m_errorMonitor->VerifyFound();
2214}
2215
2216TEST_F(VkSyncValTest, SyncLayoutTransition) {
2217 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
2218 ASSERT_NO_FATAL_FAILURE(InitState());
2219 if (IsPlatform(kNexusPlayer)) {
2220 printf("%s This test should not run on Nexus Player\n", kSkipPrefix);
2221 return;
2222 }
2223
2224 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2225
2226 VkImageUsageFlags usage_color = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
2227 VkImageUsageFlags usage_input =
2228 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
2229 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
2230 VkImageObj image_color(m_device), image_input(m_device);
2231 auto image_ci = VkImageObj::ImageCreateInfo2D(64, 64, 1, 1, format, usage_input, VK_IMAGE_TILING_OPTIMAL);
2232 image_input.InitNoLayout(image_ci);
2233 image_ci.usage = usage_color;
2234 image_color.InitNoLayout(image_ci);
2235 VkImageView view_input = image_input.targetView(format);
2236 VkImageView view_color = image_color.targetView(format);
2237 VkImageView attachments[] = {view_color, view_input};
2238
2239 const VkAttachmentDescription fbAttachment = {
2240 0u,
2241 format,
2242 VK_SAMPLE_COUNT_1_BIT,
2243 VK_ATTACHMENT_LOAD_OP_CLEAR,
2244 VK_ATTACHMENT_STORE_OP_STORE,
2245 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2246 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2247 VK_IMAGE_LAYOUT_UNDEFINED,
2248 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
2249 };
2250
2251 std::vector<VkAttachmentDescription> attachmentDescs;
2252 attachmentDescs.push_back(fbAttachment);
2253
2254 // Add it as a frame buffer attachment.
2255 const VkAttachmentDescription inputAttachment = {
2256 0u,
2257 format,
2258 VK_SAMPLE_COUNT_1_BIT,
2259 VK_ATTACHMENT_LOAD_OP_LOAD,
2260 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2261 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2262 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2263 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
2264 VK_IMAGE_LAYOUT_GENERAL,
2265 };
2266 attachmentDescs.push_back(inputAttachment);
2267
2268 std::vector<VkAttachmentReference> inputAttachments;
2269 const VkAttachmentReference inputRef = {
2270 1u,
2271 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
2272 };
2273 inputAttachments.push_back(inputRef);
2274
2275 const VkAttachmentReference colorRef = {
2276 0u,
2277 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
2278 };
2279 const std::vector<VkAttachmentReference> colorAttachments(1u, colorRef);
2280
2281 const VkSubpassDescription subpass = {
2282 0u,
2283 VK_PIPELINE_BIND_POINT_GRAPHICS,
2284 static_cast<uint32_t>(inputAttachments.size()),
2285 inputAttachments.data(),
2286 static_cast<uint32_t>(colorAttachments.size()),
2287 colorAttachments.data(),
2288 0u,
2289 nullptr,
2290 0u,
2291 nullptr,
2292 };
2293 const std::vector<VkSubpassDescription> subpasses(1u, subpass);
2294
2295 const VkRenderPassCreateInfo renderPassInfo = {
2296 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
2297 nullptr,
2298 0u,
2299 static_cast<uint32_t>(attachmentDescs.size()),
2300 attachmentDescs.data(),
2301 static_cast<uint32_t>(subpasses.size()),
2302 subpasses.data(),
2303 0u,
2304 nullptr,
2305 };
2306 VkRenderPass rp;
2307 ASSERT_VK_SUCCESS(vk::CreateRenderPass(device(), &renderPassInfo, nullptr, &rp));
2308
2309 const VkFramebufferCreateInfo fbci = {
2310 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, 0, 0u, rp, 2u, attachments, 64, 64, 1u,
2311 };
2312 VkFramebuffer fb;
2313 ASSERT_VK_SUCCESS(vk::CreateFramebuffer(device(), &fbci, nullptr, &fb));
2314
2315 VkSampler sampler = VK_NULL_HANDLE;
2316 VkSamplerCreateInfo sampler_info = SafeSaneSamplerCreateInfo();
2317 vk::CreateSampler(m_device->device(), &sampler_info, NULL, &sampler);
2318
2319 char const *fsSource =
2320 "#version 450\n"
2321 "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n"
2322 "void main() {\n"
2323 " vec4 color = subpassLoad(x);\n"
2324 "}\n";
2325
2326 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
2327 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
2328
2329 CreatePipelineHelper g_pipe(*this);
2330 g_pipe.InitInfo();
2331 g_pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
2332 g_pipe.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
2333 g_pipe.gp_ci_.renderPass = rp;
2334 g_pipe.InitState();
2335 ASSERT_VK_SUCCESS(g_pipe.CreateGraphicsPipeline());
2336
2337 g_pipe.descriptor_set_->WriteDescriptorImageInfo(0, view_input, sampler, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
2338 g_pipe.descriptor_set_->UpdateDescriptorSets();
2339
2340 m_commandBuffer->begin();
2341 auto cb = m_commandBuffer->handle();
2342 VkClearColorValue ccv = {};
2343 VkImageSubresourceRange full_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
2344
2345 const VkImageMemoryBarrier preClearBarrier = {
2346 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, 0, 0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
2347 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, 0, image_input.handle(), full_subresource_range,
2348 };
2349 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u,
2350 &preClearBarrier);
2351
2352 vk::CmdClearColorImage(m_commandBuffer->handle(), image_input.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &ccv, 1,
2353 &full_subresource_range);
2354
2355 const VkImageMemoryBarrier postClearBarrier = {
2356 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
2357 0,
2358 VK_ACCESS_TRANSFER_WRITE_BIT,
2359 VK_ACCESS_SHADER_READ_BIT,
2360 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
2361 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
2362 0,
2363 0,
2364 image_input.handle(),
2365 full_subresource_range,
2366 };
2367 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u, nullptr, 0u, nullptr,
2368 1u, &postClearBarrier);
2369
2370 m_renderPassBeginInfo.renderArea = {{0, 0}, {64, 64}};
2371 m_renderPassBeginInfo.renderPass = rp;
2372 m_renderPassBeginInfo.framebuffer = fb;
2373
2374 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2375 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
2376 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
2377 &g_pipe.descriptor_set_->set_, 0, nullptr);
2378
2379 // Positive test for ordering rules between load and input attachment usage
2380 m_errorMonitor->ExpectSuccess();
2381 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
2382
2383 // Positive test for store ordering vs. input attachment and dependency *to* external for layout transition
2384 m_commandBuffer->EndRenderPass();
2385 m_errorMonitor->VerifyNotFound();
2386
2387 // Catch a conflict with the input attachment final layout transition
2388 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
2389 vk::CmdClearColorImage(m_commandBuffer->handle(), image_input.handle(), VK_IMAGE_LAYOUT_GENERAL, &ccv, 1,
2390 &full_subresource_range);
2391 m_errorMonitor->VerifyFound();
2392}
2393
2394TEST_F(VkSyncValTest, SyncSubpassMultiDep) {
2395 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
2396 ASSERT_NO_FATAL_FAILURE(InitState());
2397 if (IsPlatform(kNexusPlayer)) {
2398 printf("%s This test should not run on Nexus Player\n", kSkipPrefix);
2399 return;
2400 }
2401
2402 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2403
2404 VkImageUsageFlags usage_color = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
2405 VkImageUsageFlags usage_input =
2406 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
2407 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
2408 VkImageObj image_color(m_device), image_input(m_device);
2409 auto image_ci = VkImageObj::ImageCreateInfo2D(64, 64, 1, 1, format, usage_input, VK_IMAGE_TILING_OPTIMAL);
2410 image_input.InitNoLayout(image_ci);
2411 image_ci.usage = usage_color;
2412 image_color.InitNoLayout(image_ci);
2413 VkImageView view_input = image_input.targetView(format);
2414 VkImageView view_color = image_color.targetView(format);
2415 VkImageView attachments[] = {view_color, view_input};
2416 VkImageSubresourceRange full_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
2417 VkImageSubresourceLayers mip_0_layer_0{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
2418 VkOffset3D image_zero{0, 0, 0};
2419 VkExtent3D image_size{64, 64, 1};
2420 VkImageCopy full_region{mip_0_layer_0, image_zero, mip_0_layer_0, image_zero, image_size};
2421
2422 const VkAttachmentDescription fbAttachment = {
2423 0u,
2424 format,
2425 VK_SAMPLE_COUNT_1_BIT,
2426 VK_ATTACHMENT_LOAD_OP_CLEAR,
2427 VK_ATTACHMENT_STORE_OP_STORE,
2428 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2429 VK_ATTACHMENT_STORE_OP_STORE,
2430 VK_IMAGE_LAYOUT_GENERAL,
2431 VK_IMAGE_LAYOUT_GENERAL,
2432 };
2433
2434 std::vector<VkAttachmentDescription> attachmentDescs;
2435 attachmentDescs.push_back(fbAttachment);
2436
2437 // Add it as a frame buffer attachment.
2438 const VkAttachmentDescription inputAttachment = {
2439 0u,
2440 format,
2441 VK_SAMPLE_COUNT_1_BIT,
2442 VK_ATTACHMENT_LOAD_OP_LOAD,
2443 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2444 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2445 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2446 VK_IMAGE_LAYOUT_GENERAL,
2447 VK_IMAGE_LAYOUT_GENERAL,
2448 };
2449 attachmentDescs.push_back(inputAttachment);
2450
2451 std::vector<VkAttachmentReference> inputAttachments;
2452 const VkAttachmentReference inputRef = {
2453 1u,
2454 VK_IMAGE_LAYOUT_GENERAL,
2455 };
2456 inputAttachments.push_back(inputRef);
2457
2458 const VkAttachmentReference colorRef = {
2459 0u,
2460 VK_IMAGE_LAYOUT_GENERAL,
2461 };
2462 const std::vector<VkAttachmentReference> colorAttachments(1u, colorRef);
2463
2464 const VkSubpassDescription subpass = {
2465 0u,
2466 VK_PIPELINE_BIND_POINT_GRAPHICS,
2467 static_cast<uint32_t>(inputAttachments.size()),
2468 inputAttachments.data(),
2469 static_cast<uint32_t>(colorAttachments.size()),
2470 colorAttachments.data(),
2471 0u,
2472 nullptr,
2473 0u,
2474 nullptr,
2475 };
2476 const std::vector<VkSubpassDescription> subpasses(1u, subpass);
2477
2478 std::vector<VkSubpassDependency> subpass_dep_postive;
2479 subpass_dep_postive.push_back({VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_TRANSFER_BIT,
2480 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2481 VK_DEPENDENCY_VIEW_LOCAL_BIT});
2482 subpass_dep_postive.push_back({VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_TRANSFER_BIT,
2483 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_TRANSFER_WRITE_BIT,
2484 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, VK_DEPENDENCY_VIEW_LOCAL_BIT});
2485 subpass_dep_postive.push_back({0, VK_SUBPASS_EXTERNAL, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2486 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2487 VK_ACCESS_TRANSFER_READ_BIT, VK_DEPENDENCY_VIEW_LOCAL_BIT});
2488 subpass_dep_postive.push_back({0, VK_SUBPASS_EXTERNAL, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2489 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2490 VK_ACCESS_TRANSFER_WRITE_BIT, VK_DEPENDENCY_VIEW_LOCAL_BIT});
2491
2492 VkRenderPassCreateInfo renderPassInfo = {
2493 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
2494 nullptr,
2495 0u,
2496 static_cast<uint32_t>(attachmentDescs.size()),
2497 attachmentDescs.data(),
2498 static_cast<uint32_t>(subpasses.size()),
2499 subpasses.data(),
2500 static_cast<uint32_t>(subpass_dep_postive.size()),
2501 subpass_dep_postive.data(),
2502 };
2503 VkRenderPass rp_positive;
2504 ASSERT_VK_SUCCESS(vk::CreateRenderPass(device(), &renderPassInfo, nullptr, &rp_positive));
2505
2506 std::vector<VkSubpassDependency> subpass_dep_negative;
2507 subpass_dep_negative.push_back({VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_TRANSFER_BIT,
2508 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2509 VK_DEPENDENCY_VIEW_LOCAL_BIT});
2510 // Show that the two barriers do *not* chain by breaking the positive barrier into two bits.
2511 subpass_dep_negative.push_back({VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_TRANSFER_BIT,
2512 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, 0,
2513 VK_DEPENDENCY_VIEW_LOCAL_BIT});
2514 subpass_dep_negative.push_back({VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2515 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
2516 VK_DEPENDENCY_VIEW_LOCAL_BIT});
2517
2518 renderPassInfo.dependencyCount = static_cast<uint32_t>(subpass_dep_negative.size());
2519 renderPassInfo.pDependencies = subpass_dep_negative.data();
2520 VkRenderPass rp_negative;
2521 ASSERT_VK_SUCCESS(vk::CreateRenderPass(device(), &renderPassInfo, nullptr, &rp_negative));
2522
2523 // rp_postive and rp_negative should be compatible for the same fb object
2524 const VkFramebufferCreateInfo fbci = {
2525 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, 0, 0u, rp_positive, 2u, attachments, 64, 64, 1u,
2526 };
2527 VkFramebuffer fb;
2528 ASSERT_VK_SUCCESS(vk::CreateFramebuffer(device(), &fbci, nullptr, &fb));
2529
2530 VkSampler sampler = VK_NULL_HANDLE;
2531 VkSamplerCreateInfo sampler_info = SafeSaneSamplerCreateInfo();
2532 vk::CreateSampler(m_device->device(), &sampler_info, NULL, &sampler);
2533
2534 char const *fsSource =
2535 "#version 450\n"
2536 "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n"
2537 "void main() {\n"
2538 " vec4 color = subpassLoad(x);\n"
2539 "}\n";
2540
2541 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
2542 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
2543
2544 CreatePipelineHelper g_pipe(*this);
2545 g_pipe.InitInfo();
2546 g_pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
2547 g_pipe.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
2548 g_pipe.gp_ci_.renderPass = rp_positive;
2549 g_pipe.InitState();
2550 ASSERT_VK_SUCCESS(g_pipe.CreateGraphicsPipeline());
2551
2552 g_pipe.descriptor_set_->WriteDescriptorImageInfo(0, view_input, sampler, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
2553 g_pipe.descriptor_set_->UpdateDescriptorSets();
2554
2555 m_commandBuffer->begin();
2556 auto cb = m_commandBuffer->handle();
2557 VkClearColorValue ccv = {};
2558
2559 const VkImageMemoryBarrier xferDestBarrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
2560 nullptr,
2561 VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT,
2562 VK_ACCESS_TRANSFER_WRITE_BIT,
2563 VK_IMAGE_LAYOUT_GENERAL,
2564 VK_IMAGE_LAYOUT_GENERAL,
2565 VK_QUEUE_FAMILY_IGNORED,
2566 VK_QUEUE_FAMILY_IGNORED,
2567 VK_NULL_HANDLE,
2568 full_subresource_range};
2569 const VkImageMemoryBarrier xferDestToSrcBarrier = {
2570 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
2571 nullptr,
2572 VK_ACCESS_TRANSFER_WRITE_BIT,
2573 VK_ACCESS_TRANSFER_READ_BIT,
2574 VK_IMAGE_LAYOUT_GENERAL,
2575 VK_IMAGE_LAYOUT_GENERAL,
2576 VK_QUEUE_FAMILY_IGNORED,
2577 VK_QUEUE_FAMILY_IGNORED,
2578 VK_NULL_HANDLE,
2579 full_subresource_range,
2580 };
2581
2582 VkImageMemoryBarrier preClearBarrier = xferDestBarrier;
2583 preClearBarrier.image = image_color.handle();
2584
2585 VkImageMemoryBarrier preCopyBarriers[2] = {xferDestToSrcBarrier, xferDestBarrier};
2586 preCopyBarriers[0].image = image_color.handle();
2587 preCopyBarriers[1].image = image_input.handle();
2588 // Positive test for ordering rules between load and input attachment usage
2589 m_errorMonitor->ExpectSuccess();
2590
2591 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u,
2592 &preClearBarrier);
2593
2594 vk::CmdClearColorImage(m_commandBuffer->handle(), image_color.handle(), VK_IMAGE_LAYOUT_GENERAL, &ccv, 1,
2595 &full_subresource_range);
2596
2597 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 2u,
2598 preCopyBarriers);
2599
2600 vk::CmdCopyImage(m_commandBuffer->handle(), image_color.handle(), VK_IMAGE_LAYOUT_GENERAL, image_input.handle(),
2601 VK_IMAGE_LAYOUT_GENERAL, 1u, &full_region);
2602
2603 // No post copy image barrier, we are testing the subpass dependencies
2604
2605 m_renderPassBeginInfo.renderArea = {{0, 0}, {64, 64}};
2606 m_renderPassBeginInfo.renderPass = rp_positive;
2607 m_renderPassBeginInfo.framebuffer = fb;
2608
2609 // Postive renderpass multidependency test
2610 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2611 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
2612 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
2613 &g_pipe.descriptor_set_->set_, 0, nullptr);
2614
2615 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
2616
2617 // Positive test for store ordering vs. input attachment and dependency *to* external for layout transition
2618 m_commandBuffer->EndRenderPass();
2619 // m_errorMonitor->VerifyNotFound();
2620
2621 vk::CmdCopyImage(m_commandBuffer->handle(), image_color.handle(), VK_IMAGE_LAYOUT_GENERAL, image_input.handle(),
2622 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &full_region);
2623 m_errorMonitor->VerifyNotFound();
2624
2625 m_renderPassBeginInfo.renderArea = {{0, 0}, {64, 64}};
2626 m_renderPassBeginInfo.renderPass = rp_negative;
2627 m_renderPassBeginInfo.framebuffer = fb;
2628
2629 // Postive renderpass multidependency test, will fail IFF the dependencies are acting indepently.
2630 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "SYNC-HAZARD-READ_AFTER_WRITE");
2631 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2632 m_errorMonitor->VerifyFound();
2633}
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002634
2635TEST_F(VkSyncValTest, RenderPassAsyncHazard) {
2636 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
2637 ASSERT_NO_FATAL_FAILURE(InitState());
2638
2639 // overall set up:
2640 // subpass 0:
2641 // write image 0
2642 // subpass 1:
2643 // read image 0
2644 // write image 1
2645 // subpass 2:
2646 // read image 0
2647 // write image 2
2648 // subpass 3:
2649 // read image 0
2650 // write image 3
2651 //
2652 // subpasses 1 & 2 can run in parallel but both should depend on 0
2653 // subpass 3 must run after 1 & 2 because otherwise the store operation will
2654 // race with the reads in the other subpasses.
2655
2656 constexpr VkFormat kFormat = VK_FORMAT_R8G8B8A8_UNORM;
2657 constexpr uint32_t kWidth = 32, kHeight = 32;
2658 constexpr uint32_t kNumImages = 4;
2659
2660 VkImageCreateInfo src_img_info = {};
2661 src_img_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2662 src_img_info.pNext = NULL;
2663 src_img_info.flags = 0;
2664 src_img_info.imageType = VK_IMAGE_TYPE_2D;
2665 src_img_info.format = kFormat;
2666 src_img_info.extent = {kWidth, kHeight, 1};
2667 src_img_info.mipLevels = 1;
2668 src_img_info.arrayLayers = 1;
2669 src_img_info.samples = VK_SAMPLE_COUNT_2_BIT;
2670 src_img_info.tiling = VK_IMAGE_TILING_OPTIMAL;
2671 src_img_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
2672 src_img_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2673 src_img_info.queueFamilyIndexCount = 0;
2674 src_img_info.pQueueFamilyIndices = nullptr;
2675 src_img_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2676
2677 VkImageCreateInfo dst_img_info = {};
2678 dst_img_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2679 dst_img_info.pNext = nullptr;
2680 dst_img_info.flags = 0;
2681 dst_img_info.imageType = VK_IMAGE_TYPE_2D;
2682 dst_img_info.format = kFormat;
2683 dst_img_info.extent = {kWidth, kHeight, 1};
2684 dst_img_info.mipLevels = 1;
2685 dst_img_info.arrayLayers = 1;
2686 dst_img_info.samples = VK_SAMPLE_COUNT_1_BIT;
2687 dst_img_info.tiling = VK_IMAGE_TILING_OPTIMAL;
2688 dst_img_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
2689 dst_img_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2690 dst_img_info.queueFamilyIndexCount = 0;
2691 dst_img_info.pQueueFamilyIndices = nullptr;
2692 dst_img_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2693
2694 std::vector<std::unique_ptr<VkImageObj>> images;
2695 for (uint32_t i = 0; i < kNumImages; i++) {
2696 images.emplace_back(new VkImageObj(m_device));
2697 }
2698 images[0]->Init(src_img_info);
2699 for (uint32_t i = 1; i < images.size(); i++) {
2700 images[i]->Init(dst_img_info);
2701 }
2702
2703 std::array<VkImageView, kNumImages> attachments{};
2704 std::array<VkAttachmentDescription, kNumImages> attachment_descriptions{};
2705 std::array<VkAttachmentReference, kNumImages> color_refs{};
2706 std::array<VkImageMemoryBarrier, kNumImages> img_barriers{};
2707
2708 for (uint32_t i = 0; i < attachments.size(); i++) {
2709 attachments[i] = images[i]->targetView(kFormat);
2710 attachment_descriptions[i] = {};
2711 attachment_descriptions[i].flags = 0;
2712 attachment_descriptions[i].format = kFormat;
2713 attachment_descriptions[i].samples = VK_SAMPLE_COUNT_1_BIT;
2714 attachment_descriptions[i].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
2715 attachment_descriptions[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
2716 attachment_descriptions[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
2717 attachment_descriptions[i].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
2718 attachment_descriptions[i].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
2719 attachment_descriptions[i].finalLayout =
2720 (i == 0) ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
2721
2722 color_refs[i] = {i, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
2723
2724 img_barriers[i].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
2725 img_barriers[i].srcAccessMask = 0;
2726 img_barriers[i].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
2727 img_barriers[i].oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2728 img_barriers[i].newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
2729 img_barriers[i].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
2730 img_barriers[i].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
2731 img_barriers[i].image = images[i]->handle();
2732 img_barriers[i].subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS};
2733 }
2734
2735 const VkAttachmentReference input_ref{0u, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};
2736
2737 std::array<std::array<uint32_t, 2>, kNumImages - 1> preserve_subpass{{{2, 3}, {1, 3}, {1, 2}}};
2738
2739 std::array<VkSubpassDescription, kNumImages> subpasses{};
2740
2741 subpasses[0].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
2742 subpasses[0].inputAttachmentCount = 0;
2743 subpasses[0].pInputAttachments = nullptr;
2744 subpasses[0].colorAttachmentCount = 1;
2745 subpasses[0].pColorAttachments = &color_refs[0];
2746
2747 for (uint32_t i = 1; i < subpasses.size(); i++) {
2748 subpasses[i].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
2749 subpasses[i].inputAttachmentCount = 1;
2750 subpasses[i].pInputAttachments = &input_ref;
2751 subpasses[i].colorAttachmentCount = 1;
2752 subpasses[i].pColorAttachments = &color_refs[1];
2753 subpasses[i].preserveAttachmentCount = preserve_subpass[i - 1].size();
2754 subpasses[i].pPreserveAttachments = preserve_subpass[i - 1].data();
2755 }
2756
2757 VkRenderPassCreateInfo renderpass_info = {};
2758 renderpass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
2759 renderpass_info.pNext = nullptr;
2760 renderpass_info.flags = 0;
2761 renderpass_info.attachmentCount = attachment_descriptions.size();
2762 renderpass_info.pAttachments = attachment_descriptions.data();
2763 renderpass_info.subpassCount = subpasses.size();
2764 renderpass_info.pSubpasses = subpasses.data();
2765 renderpass_info.dependencyCount = 0;
2766 renderpass_info.pDependencies = nullptr;
2767
2768 VkFramebufferCreateInfo fbci = {};
2769 fbci.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
2770 fbci.pNext = nullptr;
2771 fbci.flags = 0;
2772 fbci.attachmentCount = attachments.size();
2773 fbci.pAttachments = attachments.data();
2774 fbci.width = kWidth;
2775 fbci.height = kHeight;
2776 fbci.layers = 1;
2777
2778 VkSampler sampler = VK_NULL_HANDLE;
2779 VkSamplerCreateInfo sampler_info = SafeSaneSamplerCreateInfo();
2780 vk::CreateSampler(m_device->device(), &sampler_info, NULL, &sampler);
2781
2782 char const *fsSource =
2783 "#version 450\n"
2784 "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n"
2785 "void main() {\n"
2786 " vec4 color = subpassLoad(x);\n"
2787 "}\n";
2788
2789 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
2790 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
2791
2792 VkClearValue clear = {};
2793 clear.color = m_clear_color;
Tony-LunarG73f37032021-06-07 11:47:03 -06002794 std::array<VkClearValue, 4> clear_values = {{clear, clear, clear, clear}};
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002795
2796 // run the renderpass with no dependencies
2797 {
2798 VkRenderPass rp;
2799 VkFramebuffer fb;
2800 ASSERT_VK_SUCCESS(vk::CreateRenderPass(device(), &renderpass_info, nullptr, &rp));
2801
2802 fbci.renderPass = rp;
2803 ASSERT_VK_SUCCESS(vk::CreateFramebuffer(device(), &fbci, nullptr, &fb));
2804
2805 CreatePipelineHelper g_pipe_0(*this);
2806 g_pipe_0.InitInfo();
2807 g_pipe_0.gp_ci_.renderPass = rp;
2808 g_pipe_0.InitState();
2809 ASSERT_VK_SUCCESS(g_pipe_0.CreateGraphicsPipeline());
2810
2811 CreatePipelineHelper g_pipe_12(*this);
2812 g_pipe_12.InitInfo();
2813 g_pipe_12.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
2814 g_pipe_12.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
2815 g_pipe_12.gp_ci_.renderPass = rp;
2816 g_pipe_12.InitState();
2817 ASSERT_VK_SUCCESS(g_pipe_12.CreateGraphicsPipeline());
2818
2819 g_pipe_12.descriptor_set_->WriteDescriptorImageInfo(0, attachments[0], sampler, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
2820 g_pipe_12.descriptor_set_->UpdateDescriptorSets();
2821
2822 m_commandBuffer->begin();
2823
2824 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
2825 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0, nullptr, img_barriers.size(),
2826 img_barriers.data());
2827
2828 m_renderPassBeginInfo.renderArea = {{0, 0}, {16, 16}};
2829 m_renderPassBeginInfo.pClearValues = clear_values.data();
2830 m_renderPassBeginInfo.clearValueCount = clear_values.size();
2831
2832 m_renderPassBeginInfo.renderArea = {{0, 0}, {kWidth, kHeight}};
2833 m_renderPassBeginInfo.renderPass = rp;
2834 m_renderPassBeginInfo.framebuffer = fb;
2835
2836 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
2837 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_);
2838 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_layout_.handle(), 0,
2839 1, &g_pipe_0.descriptor_set_->set_, 0, NULL);
2840
2841 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
2842
2843 for (uint32_t i = 1; i < subpasses.size(); i++) {
2844 vk::CmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
2845 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_12.pipeline_);
2846 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS,
2847 g_pipe_12.pipeline_layout_.handle(), 0, 1, &g_pipe_12.descriptor_set_->set_, 0, NULL);
2848
2849 // we're racing the writes from subpass 0 with our shader reads
2850 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ-RACING-WRITE");
2851 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
2852 m_errorMonitor->VerifyFound();
2853 }
2854
2855 // we should get an error from async checking in both subpasses 2 & 3
2856 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE-RACING-WRITE");
2857 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE-RACING-WRITE");
2858 vk::CmdEndRenderPass(m_commandBuffer->handle());
2859 m_errorMonitor->VerifyFound();
2860
2861 m_commandBuffer->end();
2862
2863 vk::DestroyFramebuffer(device(), fb, nullptr);
2864 vk::DestroyRenderPass(device(), rp, nullptr);
2865 }
2866
2867 // add dependencies from subpass 0 to the others, which are necessary but not sufficient
2868 std::vector<VkSubpassDependency> subpass_dependencies;
2869 for (uint32_t i = 1; i < subpasses.size(); i++) {
2870 VkSubpassDependency dep{0,
2871 i,
2872 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2873 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
2874 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2875 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
2876 0};
2877 subpass_dependencies.push_back(dep);
2878 }
2879 renderpass_info.dependencyCount = subpass_dependencies.size();
2880 renderpass_info.pDependencies = subpass_dependencies.data();
2881
2882 {
2883 VkRenderPass rp;
2884 VkFramebuffer fb;
2885 ASSERT_VK_SUCCESS(vk::CreateRenderPass(device(), &renderpass_info, nullptr, &rp));
2886
2887 fbci.renderPass = rp;
2888 ASSERT_VK_SUCCESS(vk::CreateFramebuffer(device(), &fbci, nullptr, &fb));
2889
2890 CreatePipelineHelper g_pipe_0(*this);
2891 g_pipe_0.InitInfo();
2892 g_pipe_0.gp_ci_.renderPass = rp;
2893 g_pipe_0.InitState();
2894 ASSERT_VK_SUCCESS(g_pipe_0.CreateGraphicsPipeline());
2895
2896 CreatePipelineHelper g_pipe_12(*this);
2897 g_pipe_12.InitInfo();
2898 g_pipe_12.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
2899 g_pipe_12.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
2900 g_pipe_12.gp_ci_.renderPass = rp;
2901 g_pipe_12.InitState();
2902 ASSERT_VK_SUCCESS(g_pipe_12.CreateGraphicsPipeline());
2903
2904 g_pipe_12.descriptor_set_->WriteDescriptorImageInfo(0, attachments[0], sampler, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
2905 g_pipe_12.descriptor_set_->UpdateDescriptorSets();
2906
2907 m_commandBuffer->begin();
2908
2909 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
2910 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0, nullptr, img_barriers.size(),
2911 img_barriers.data());
2912
2913 m_renderPassBeginInfo.renderArea = {{0, 0}, {16, 16}};
2914 m_renderPassBeginInfo.pClearValues = clear_values.data();
2915 m_renderPassBeginInfo.clearValueCount = clear_values.size();
2916
2917 m_renderPassBeginInfo.renderArea = {{0, 0}, {kWidth, kHeight}};
2918 m_renderPassBeginInfo.renderPass = rp;
2919 m_renderPassBeginInfo.framebuffer = fb;
2920
2921 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
2922 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_);
2923 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_layout_.handle(), 0,
2924 1, &g_pipe_0.descriptor_set_->set_, 0, NULL);
2925
2926 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
2927
2928 m_errorMonitor->ExpectSuccess();
2929 for (uint32_t i = 1; i < subpasses.size(); i++) {
2930 vk::CmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
2931 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_12.pipeline_);
2932 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS,
2933 g_pipe_12.pipeline_layout_.handle(), 0, 1, &g_pipe_12.descriptor_set_->set_, 0, NULL);
2934 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
2935 }
2936 m_errorMonitor->VerifyNotFound();
2937 // expect this error because 2 subpasses could try to do the store operation
2938 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE-RACING-WRITE");
2939 // ... and this one because the store could happen during a shader read from another subpass
2940 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE-RACING-READ");
2941 vk::CmdEndRenderPass(m_commandBuffer->handle());
2942 m_errorMonitor->VerifyFound();
2943
2944 m_commandBuffer->end();
2945
2946 m_errorMonitor->VerifyFound();
2947 vk::DestroyFramebuffer(device(), fb, nullptr);
2948 vk::DestroyRenderPass(device(), rp, nullptr);
2949 }
2950
2951 // try again with correct dependencies to make subpass 3 depend on 1 & 2
2952 for (uint32_t i = 1; i < (subpasses.size() - 1); i++) {
2953 VkSubpassDependency dep{i,
2954 static_cast<uint32_t>(subpasses.size() - 1),
2955 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2956 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
2957 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2958 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
2959 0};
2960 subpass_dependencies.push_back(dep);
2961 }
2962 renderpass_info.dependencyCount = subpass_dependencies.size();
2963 renderpass_info.pDependencies = subpass_dependencies.data();
2964 {
2965 VkRenderPass rp;
2966 VkFramebuffer fb;
2967 ASSERT_VK_SUCCESS(vk::CreateRenderPass(device(), &renderpass_info, nullptr, &rp));
2968
2969 fbci.renderPass = rp;
2970 ASSERT_VK_SUCCESS(vk::CreateFramebuffer(device(), &fbci, nullptr, &fb));
2971
2972 CreatePipelineHelper g_pipe_0(*this);
2973 g_pipe_0.InitInfo();
2974 g_pipe_0.gp_ci_.renderPass = rp;
2975 g_pipe_0.InitState();
2976 ASSERT_VK_SUCCESS(g_pipe_0.CreateGraphicsPipeline());
2977
2978 CreatePipelineHelper g_pipe_12(*this);
2979 g_pipe_12.InitInfo();
2980 g_pipe_12.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
2981 g_pipe_12.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
2982 g_pipe_12.gp_ci_.renderPass = rp;
2983 g_pipe_12.InitState();
2984 ASSERT_VK_SUCCESS(g_pipe_12.CreateGraphicsPipeline());
2985
2986 g_pipe_12.descriptor_set_->WriteDescriptorImageInfo(0, attachments[0], sampler, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
2987 g_pipe_12.descriptor_set_->UpdateDescriptorSets();
2988
2989 m_errorMonitor->ExpectSuccess();
2990 m_commandBuffer->begin();
2991 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
2992 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0, nullptr, img_barriers.size(),
2993 img_barriers.data());
2994
2995 m_renderPassBeginInfo.renderArea = {{0, 0}, {16, 16}};
2996 m_renderPassBeginInfo.pClearValues = clear_values.data();
2997 m_renderPassBeginInfo.clearValueCount = clear_values.size();
2998
2999 m_renderPassBeginInfo.renderArea = {{0, 0}, {kWidth, kHeight}};
3000 m_renderPassBeginInfo.renderPass = rp;
3001 m_renderPassBeginInfo.framebuffer = fb;
3002
3003 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
3004 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_);
3005 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_layout_.handle(), 0,
3006 1, &g_pipe_0.descriptor_set_->set_, 0, NULL);
3007
3008 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
3009
3010 for (uint32_t i = 1; i < subpasses.size(); i++) {
3011 vk::CmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
3012 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_12.pipeline_);
3013 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS,
3014 g_pipe_12.pipeline_layout_.handle(), 0, 1, &g_pipe_12.descriptor_set_->set_, 0, NULL);
3015 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
3016 }
3017
3018 vk::CmdEndRenderPass(m_commandBuffer->handle());
3019
3020 m_commandBuffer->end();
3021
3022 m_errorMonitor->VerifyNotFound();
3023 vk::DestroyFramebuffer(device(), fb, nullptr);
3024 vk::DestroyRenderPass(device(), rp, nullptr);
3025 }
3026}
John Zulauf025ee442020-12-15 11:44:19 -07003027
3028TEST_F(VkSyncValTest, SyncEventsBufferCopy) {
3029 TEST_DESCRIPTION("Check Set/Wait protection for a variety of use cases using buffer copies");
3030 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
3031 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
3032
3033 VkBufferObj buffer_a;
3034 VkBufferObj buffer_b;
3035 VkBufferObj buffer_c;
3036 VkMemoryPropertyFlags mem_prop = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
3037 buffer_a.init_as_src_and_dst(*m_device, 256, mem_prop);
3038 buffer_b.init_as_src_and_dst(*m_device, 256, mem_prop);
3039 buffer_c.init_as_src_and_dst(*m_device, 256, mem_prop);
3040
3041 VkBufferCopy region = {0, 0, 256};
3042 VkBufferCopy front2front = {0, 0, 128};
3043 VkBufferCopy front2back = {0, 128, 128};
3044 VkBufferCopy back2back = {128, 128, 128};
3045
3046 VkEventObj event;
3047 event.init(*m_device, VkEventObj::create_info(0));
3048 VkEvent event_handle = event.handle();
3049
3050 auto cb = m_commandBuffer->handle();
3051 m_commandBuffer->begin();
3052
3053 // Copy after set for WAR (note we are writing to the back half of c but only reading from the front
3054 m_errorMonitor->ExpectSuccess();
3055 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &region);
3056 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3057 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_c.handle(), 1, &back2back);
3058 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3059 nullptr, 0, nullptr);
3060 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &front2front);
3061 m_errorMonitor->VerifyNotFound();
3062 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
3063 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &front2back);
3064 m_errorMonitor->VerifyFound();
3065 m_commandBuffer->end();
3066
3067 // WAR prevented
3068 m_commandBuffer->reset();
3069 m_commandBuffer->begin();
3070 m_errorMonitor->ExpectSuccess();
3071 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &region);
3072 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3073 // Just protect against WAR, only need a sync barrier.
3074 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3075 nullptr, 0, nullptr);
3076 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &region);
3077 m_errorMonitor->VerifyNotFound();
3078
3079 // Wait shouldn't prevent this WAW though, as it's only a synchronization barrier
3080 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
3081 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_b.handle(), 1, &region);
3082 m_errorMonitor->VerifyFound();
3083 m_commandBuffer->end();
3084
3085 // Prevent WAR and WAW
3086 m_commandBuffer->reset();
3087 m_commandBuffer->begin();
3088 m_errorMonitor->ExpectSuccess();
3089 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &region);
3090 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07003091 auto mem_barrier_waw = LvlInitStruct<VkMemoryBarrier>();
John Zulauf025ee442020-12-15 11:44:19 -07003092 mem_barrier_waw.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3093 mem_barrier_waw.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3094 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 1,
3095 &mem_barrier_waw, 0, nullptr, 0, nullptr);
3096 // The WAW should be safe (on a memory barrier)
3097 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_b.handle(), 1, &region);
3098 // The WAR should also be safe (on a sync barrier)
3099 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &region);
3100 m_errorMonitor->VerifyNotFound();
3101 m_commandBuffer->end();
3102
3103 // Barrier range check for WAW
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07003104 auto buffer_barrier_front_waw = LvlInitStruct<VkBufferMemoryBarrier>();
John Zulauf025ee442020-12-15 11:44:19 -07003105 buffer_barrier_front_waw.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3106 buffer_barrier_front_waw.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3107 buffer_barrier_front_waw.buffer = buffer_b.handle();
3108 buffer_barrier_front_waw.offset = front2front.dstOffset;
3109 buffer_barrier_front_waw.size = front2front.size;
3110
3111 // Front safe, back WAW
3112 m_commandBuffer->reset();
3113 m_commandBuffer->begin();
3114 m_errorMonitor->ExpectSuccess();
3115 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &region);
3116 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3117 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 1,
3118 &buffer_barrier_front_waw, 0, nullptr);
3119 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &front2front);
3120 m_errorMonitor->VerifyNotFound();
3121 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
3122 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &back2back);
3123 m_errorMonitor->VerifyFound();
3124 m_commandBuffer->end();
3125}
3126
3127TEST_F(VkSyncValTest, SyncEventsCopyImageHazards) {
3128 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
3129 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
3130
3131 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3132 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
3133 VkImageObj image_a(m_device);
3134 auto image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 2, format, usage, VK_IMAGE_TILING_OPTIMAL);
3135 image_a.Init(image_ci);
3136 ASSERT_TRUE(image_a.initialized());
3137
3138 VkImageObj image_b(m_device);
3139 image_b.Init(image_ci);
3140 ASSERT_TRUE(image_b.initialized());
3141
3142 VkImageObj image_c(m_device);
3143 image_c.Init(image_ci);
3144 ASSERT_TRUE(image_c.initialized());
3145
3146 VkEventObj event;
3147 event.init(*m_device, VkEventObj::create_info(0));
3148 VkEvent event_handle = event.handle();
3149
3150 VkImageSubresourceLayers layers_all{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 2};
3151 VkImageSubresourceLayers layers_0{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
3152 VkImageSubresourceLayers layers_1{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1};
3153 VkImageSubresourceRange layers_0_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
3154 VkOffset3D zero_offset{0, 0, 0};
3155 VkOffset3D half_offset{64, 64, 0};
3156 VkExtent3D full_extent{128, 128, 1}; // <-- image type is 2D
3157 VkExtent3D half_extent{64, 64, 1}; // <-- image type is 2D
3158
3159 VkImageCopy full_region = {layers_all, zero_offset, layers_all, zero_offset, full_extent};
3160 VkImageCopy region_0_to_0 = {layers_0, zero_offset, layers_0, zero_offset, full_extent};
3161 VkImageCopy region_1_to_1 = {layers_1, zero_offset, layers_1, zero_offset, full_extent};
3162 VkImageCopy region_0_q0toq0 = {layers_0, zero_offset, layers_0, zero_offset, half_extent};
3163 VkImageCopy region_0_q0toq3 = {layers_0, zero_offset, layers_0, half_offset, half_extent};
3164 VkImageCopy region_0_q3toq3 = {layers_0, half_offset, layers_0, half_offset, half_extent};
3165
3166 auto cb = m_commandBuffer->handle();
3167 auto copy_general = [cb](const VkImageObj &from, const VkImageObj &to, const VkImageCopy &region) {
3168 vk::CmdCopyImage(cb, from.handle(), VK_IMAGE_LAYOUT_GENERAL, to.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
3169 };
3170
3171 auto set_layouts = [this, &image_a, &image_b, &image_c]() {
3172 image_c.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
3173 image_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
3174 image_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
3175 };
3176
John Zulaufdd462092020-12-18 12:00:35 -07003177 // Scope check. One access in, one access not
John Zulauf025ee442020-12-15 11:44:19 -07003178 m_commandBuffer->begin();
3179 set_layouts();
3180 m_errorMonitor->ExpectSuccess();
3181 copy_general(image_a, image_b, full_region);
3182 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3183 copy_general(image_a, image_c, region_0_q3toq3);
3184 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3185 nullptr, 0, nullptr);
3186 copy_general(image_c, image_a, region_0_q0toq0);
3187 m_errorMonitor->VerifyNotFound();
3188 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
3189 copy_general(image_c, image_a, region_0_q0toq3);
3190 m_errorMonitor->VerifyFound();
3191 m_commandBuffer->end();
3192
3193 // WAR prevented
3194 m_commandBuffer->reset();
3195 m_commandBuffer->begin();
3196 set_layouts();
3197 m_errorMonitor->ExpectSuccess();
3198 copy_general(image_a, image_b, full_region);
3199 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3200 // Just protect against WAR, only need a sync barrier.
3201 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3202 nullptr, 0, nullptr);
3203 copy_general(image_c, image_a, full_region);
3204 m_errorMonitor->VerifyNotFound();
3205
3206 // Wait shouldn't prevent this WAW though, as it's only a synchronization barrier
3207 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
3208 copy_general(image_c, image_b, full_region);
3209 m_errorMonitor->VerifyFound();
3210 m_commandBuffer->end();
3211
3212 // Prevent WAR and WAW
3213 m_commandBuffer->reset();
3214 m_commandBuffer->begin();
3215 m_errorMonitor->ExpectSuccess();
3216 set_layouts();
3217 copy_general(image_a, image_b, full_region);
3218 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07003219 auto mem_barrier_waw = LvlInitStruct<VkMemoryBarrier>();
John Zulauf025ee442020-12-15 11:44:19 -07003220 mem_barrier_waw.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3221 mem_barrier_waw.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3222 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 1,
3223 &mem_barrier_waw, 0, nullptr, 0, nullptr);
3224 // The WAW should be safe (on a memory barrier)
3225 copy_general(image_c, image_b, full_region);
3226 // The WAR should also be safe (on a sync barrier)
3227 copy_general(image_c, image_a, full_region);
3228 m_errorMonitor->VerifyNotFound();
3229 m_commandBuffer->end();
3230
3231 // Barrier range check for WAW
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07003232 auto image_barrier_region0_waw = LvlInitStruct<VkImageMemoryBarrier>();
John Zulauf025ee442020-12-15 11:44:19 -07003233 image_barrier_region0_waw.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3234 image_barrier_region0_waw.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3235 image_barrier_region0_waw.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
3236 image_barrier_region0_waw.newLayout = VK_IMAGE_LAYOUT_GENERAL;
3237 image_barrier_region0_waw.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
3238 image_barrier_region0_waw.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
3239 image_barrier_region0_waw.image = image_b.handle();
3240 image_barrier_region0_waw.subresourceRange = layers_0_subresource_range;
3241
3242 // Region 0 safe, back WAW
3243 m_commandBuffer->reset();
3244 m_commandBuffer->begin();
3245 set_layouts();
3246 m_errorMonitor->ExpectSuccess();
3247 copy_general(image_a, image_b, full_region);
3248 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3249 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3250 nullptr, 1, &image_barrier_region0_waw);
3251 copy_general(image_a, image_b, region_0_to_0);
3252 m_errorMonitor->VerifyNotFound();
3253 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
3254 copy_general(image_a, image_b, region_1_to_1);
3255 m_errorMonitor->VerifyFound();
3256 m_commandBuffer->end();
3257}
John Zulauf4b5e4632020-12-15 11:48:59 -07003258
3259TEST_F(VkSyncValTest, SyncEventsCommandHazards) {
3260 TEST_DESCRIPTION("Check Set/Reset/Wait command hazard checking");
3261 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
3262 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
3263
3264 VkEventObj event;
3265 event.init(*m_device, VkEventObj::create_info(0));
3266
3267 const VkEvent event_handle = event.handle();
3268
3269 m_commandBuffer->begin();
3270 m_errorMonitor->ExpectSuccess();
3271 m_commandBuffer->ResetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3272 m_errorMonitor->VerifyNotFound();
3273
John Zulauf4edde622021-02-15 08:54:50 -07003274 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdResetEvent-event-03834");
John Zulauf4b5e4632020-12-15 11:48:59 -07003275 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdWaitEvents-srcStageMask-01158");
3276 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3277 nullptr, 0, nullptr);
3278 m_errorMonitor->VerifyFound();
3279 m_errorMonitor->ExpectSuccess();
3280 m_commandBuffer->end();
3281
3282 m_commandBuffer->begin();
3283 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3284 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, nullptr,
3285 0, nullptr, 0, nullptr);
3286 m_errorMonitor->VerifyNotFound();
3287 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-vkCmdResetEvent-missingbarrier-wait");
3288 m_commandBuffer->ResetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3289 m_errorMonitor->VerifyFound();
3290 m_errorMonitor->ExpectSuccess();
3291 m_commandBuffer->end();
3292
3293 m_commandBuffer->begin();
3294 m_commandBuffer->ResetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3295 m_errorMonitor->VerifyNotFound();
3296 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-vkCmdSetEvent-missingbarrier-reset");
3297 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3298 m_errorMonitor->VerifyFound();
3299
3300 m_errorMonitor->ExpectSuccess();
3301 m_commandBuffer->PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0U, 0, nullptr, 0,
3302 nullptr, 0, nullptr);
3303 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3304 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3305 nullptr, 0, nullptr);
3306 m_commandBuffer->ResetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3307 m_commandBuffer->PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0U, 0, nullptr, 0,
3308 nullptr, 0, nullptr);
3309 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3310 m_errorMonitor->VerifyNotFound();
3311
3312 // Need a barrier between set and a reset
3313 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-vkCmdResetEvent-missingbarrier-set");
3314 m_commandBuffer->ResetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3315 m_errorMonitor->VerifyFound();
3316 m_errorMonitor->ExpectSuccess();
3317 m_commandBuffer->end();
3318
3319 m_commandBuffer->begin();
3320 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3321 m_errorMonitor->VerifyNotFound();
3322 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-vkCmdSetEvent-missingbarrier-set");
3323 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3324 m_errorMonitor->VerifyFound();
3325
3326 m_commandBuffer->end();
3327}