blob: 2946136f0ae1b6ab584d834cfdb9621d210b4c2c [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
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001213 vk_testing::Sampler sampler_s, sampler_c;
Jeremy Gebben170781d2020-11-19 16:21:21 -07001214 VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001215 sampler_s.init(*m_device, sampler_ci);
1216 sampler_c.init(*m_device, sampler_ci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001217
1218 VkBufferObj buffer_a, buffer_b;
1219 VkMemoryPropertyFlags mem_prop = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
1220 VkBufferUsageFlags buffer_usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT |
1221 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1222 buffer_a.init(*m_device, buffer_a.create_info(2048, buffer_usage, nullptr), mem_prop);
1223 buffer_b.init(*m_device, buffer_b.create_info(2048, buffer_usage, nullptr), mem_prop);
1224
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001225 vk_testing::BufferView bufferview;
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07001226 auto bvci = LvlInitStruct<VkBufferViewCreateInfo>();
Jeremy Gebben170781d2020-11-19 16:21:21 -07001227 bvci.buffer = buffer_a.handle();
1228 bvci.format = VK_FORMAT_R32_SFLOAT;
1229 bvci.offset = 0;
1230 bvci.range = VK_WHOLE_SIZE;
1231
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001232 bufferview.init(*m_device, bvci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001233
1234 OneOffDescriptorSet descriptor_set(m_device,
1235 {
1236 {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
1237 {1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr},
1238 {2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_ALL, nullptr},
1239 {3, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
1240 });
1241
sfricke-samsung36428462021-02-10 01:23:34 -08001242 descriptor_set.WriteDescriptorBufferInfo(0, buffer_a.handle(), 0, 2048);
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001243 descriptor_set.WriteDescriptorImageInfo(1, imageview_c, sampler_c.handle(), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
Jeremy Gebben170781d2020-11-19 16:21:21 -07001244 VK_IMAGE_LAYOUT_GENERAL);
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001245 descriptor_set.WriteDescriptorImageInfo(2, imageview_s, sampler_s.handle(), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_IMAGE_LAYOUT_GENERAL);
1246 descriptor_set.WriteDescriptorBufferView(3, bufferview.handle());
Jeremy Gebben170781d2020-11-19 16:21:21 -07001247 descriptor_set.UpdateDescriptorSets();
1248
1249 // Dispatch
sfricke-samsung1c0b96a2021-07-08 22:24:09 -07001250 std::string csSource = R"glsl(
1251 #version 450
1252 layout(set=0, binding=0) uniform foo { float x; } ub0;
1253 layout(set=0, binding=1) uniform sampler2D cis1;
1254 layout(set=0, binding=2, rgba8) uniform readonly image2D si2;
1255 layout(set=0, binding=3, r32f) uniform readonly imageBuffer stb3;
1256 void main(){
1257 vec4 vColor4;
1258 vColor4.x = ub0.x;
1259 vColor4 = texture(cis1, vec2(0));
1260 vColor4 = imageLoad(si2, ivec2(0));
1261 vColor4 = imageLoad(stb3, 0);
1262 }
1263 )glsl";
Jeremy Gebben170781d2020-11-19 16:21:21 -07001264
John Zulaufbe8562b2020-12-15 14:21:01 -07001265 VkEventObj event;
1266 event.init(*m_device, VkEventObj::create_info(0));
1267 VkEvent event_handle = event.handle();
1268
Jeremy Gebben170781d2020-11-19 16:21:21 -07001269 CreateComputePipelineHelper pipe(*this);
1270 pipe.InitInfo();
1271 pipe.cs_.reset(new VkShaderObj(m_device, csSource.c_str(), VK_SHADER_STAGE_COMPUTE_BIT, this));
1272 pipe.InitState();
1273 pipe.pipeline_layout_ = VkPipelineLayoutObj(m_device, {&descriptor_set.layout_});
1274 pipe.CreateComputePipeline();
1275
1276 m_commandBuffer->begin();
1277
1278 VkBufferCopy buffer_region = {0, 0, 2048};
1279 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_b.handle(), buffer_a.handle(), 1, &buffer_region);
1280
1281 VkImageSubresourceLayers layer{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
1282 VkOffset3D zero_offset{0, 0, 0};
1283 VkExtent3D full_extent{16, 16, 1};
1284 VkImageCopy image_region = {layer, zero_offset, layer, zero_offset, full_extent};
1285 vk::CmdCopyImage(m_commandBuffer->handle(), image_c_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_c_a.handle(),
1286 VK_IMAGE_LAYOUT_GENERAL, 1, &image_region);
1287 vk::CmdCopyImage(m_commandBuffer->handle(), image_s_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_s_a.handle(),
1288 VK_IMAGE_LAYOUT_GENERAL, 1, &image_region);
1289
1290 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_);
1291 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_layout_.handle(), 0, 1,
1292 &descriptor_set.set_, 0, nullptr);
1293
1294 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1295 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
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 vk::CmdDispatch(m_commandBuffer->handle(), 1, 1, 1);
1299 m_errorMonitor->VerifyFound();
1300
1301 m_commandBuffer->end();
1302 m_commandBuffer->reset();
1303 m_commandBuffer->begin();
1304
1305 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_);
1306 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_layout_.handle(), 0, 1,
1307 &descriptor_set.set_, 0, nullptr);
1308 vk::CmdDispatch(m_commandBuffer->handle(), 1, 1, 1);
1309
1310 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1311 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_b.handle(), buffer_a.handle(), 1, &buffer_region);
1312 m_errorMonitor->VerifyFound();
1313
1314 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1315 vk::CmdCopyImage(m_commandBuffer->handle(), image_c_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_c_a.handle(),
1316 VK_IMAGE_LAYOUT_GENERAL, 1, &image_region);
1317 m_errorMonitor->VerifyFound();
1318
1319 m_commandBuffer->end();
1320 m_commandBuffer->reset();
1321
1322 // DispatchIndirect
1323 m_errorMonitor->ExpectSuccess();
1324 VkBufferObj buffer_dispatchIndirect, buffer_dispatchIndirect2;
1325 buffer_usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1326 buffer_dispatchIndirect.init(
1327 *m_device, buffer_dispatchIndirect.create_info(sizeof(VkDispatchIndirectCommand), buffer_usage, nullptr), mem_prop);
1328 buffer_dispatchIndirect2.init(
1329 *m_device, buffer_dispatchIndirect2.create_info(sizeof(VkDispatchIndirectCommand), buffer_usage, nullptr), mem_prop);
1330 m_commandBuffer->begin();
1331 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_);
1332 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_layout_.handle(), 0, 1,
1333 &descriptor_set.set_, 0, nullptr);
1334 vk::CmdDispatchIndirect(m_commandBuffer->handle(), buffer_dispatchIndirect.handle(), 0);
1335 m_commandBuffer->end();
1336 m_errorMonitor->VerifyNotFound();
1337
1338 m_commandBuffer->reset();
1339 m_commandBuffer->begin();
1340
1341 buffer_region = {0, 0, sizeof(VkDispatchIndirectCommand)};
1342 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_dispatchIndirect2.handle(), buffer_dispatchIndirect.handle(), 1,
1343 &buffer_region);
1344 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_);
1345 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_layout_.handle(), 0, 1,
1346 &descriptor_set.set_, 0, nullptr);
1347 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1348 vk::CmdDispatchIndirect(m_commandBuffer->handle(), buffer_dispatchIndirect.handle(), 0);
1349 m_errorMonitor->VerifyFound();
1350 m_commandBuffer->end();
1351
1352 // Draw
1353 m_errorMonitor->ExpectSuccess();
1354 const float vbo_data[3] = {1.f, 0.f, 1.f};
1355 VkVertexInputAttributeDescription VertexInputAttributeDescription = {0, 0, VK_FORMAT_R32G32B32_SFLOAT, sizeof(vbo_data)};
1356 VkVertexInputBindingDescription VertexInputBindingDescription = {0, sizeof(vbo_data), VK_VERTEX_INPUT_RATE_VERTEX};
1357 VkBufferObj vbo, vbo2;
1358 buffer_usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1359 vbo.init(*m_device, vbo.create_info(sizeof(vbo_data), buffer_usage, nullptr), mem_prop);
1360 vbo2.init(*m_device, vbo2.create_info(sizeof(vbo_data), buffer_usage, nullptr), mem_prop);
1361
1362 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
1363 VkShaderObj fs(m_device, csSource.c_str(), VK_SHADER_STAGE_FRAGMENT_BIT, this);
1364
1365 CreatePipelineHelper g_pipe(*this);
1366 g_pipe.InitInfo();
1367 g_pipe.InitState();
1368 g_pipe.vi_ci_.pVertexBindingDescriptions = &VertexInputBindingDescription;
1369 g_pipe.vi_ci_.vertexBindingDescriptionCount = 1;
1370 g_pipe.vi_ci_.pVertexAttributeDescriptions = &VertexInputAttributeDescription;
1371 g_pipe.vi_ci_.vertexAttributeDescriptionCount = 1;
1372 g_pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
1373 g_pipe.pipeline_layout_ = VkPipelineLayoutObj(m_device, {&descriptor_set.layout_});
1374 ASSERT_VK_SUCCESS(g_pipe.CreateGraphicsPipeline());
1375
1376 m_commandBuffer->reset();
1377 m_commandBuffer->begin();
1378 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1379 VkDeviceSize offset = 0;
1380 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1381
1382 VkViewport viewport = {0, 0, 16, 16, 0, 1};
1383 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1384 VkRect2D scissor = {{0, 0}, {16, 16}};
1385 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1386
1387 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1388 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1389 &descriptor_set.set_, 0, nullptr);
1390 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1391 m_commandBuffer->EndRenderPass();
1392 m_commandBuffer->end();
1393 m_errorMonitor->VerifyNotFound();
1394
1395 m_commandBuffer->reset();
1396 m_commandBuffer->begin();
1397
1398 buffer_region = {0, 0, sizeof(vbo_data)};
1399 vk::CmdCopyBuffer(m_commandBuffer->handle(), vbo2.handle(), vbo.handle(), 1, &buffer_region);
1400
1401 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1402 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1403 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1404 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1405 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1406 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1407 &descriptor_set.set_, 0, nullptr);
1408
1409 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1410 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1411 m_errorMonitor->VerifyFound();
1412
1413 m_commandBuffer->EndRenderPass();
1414 m_commandBuffer->end();
1415
John Zulaufbe8562b2020-12-15 14:21:01 -07001416 // Repeat the draw test with a WaitEvent to protect it.
1417 m_errorMonitor->ExpectSuccess();
1418 m_commandBuffer->reset();
1419 m_commandBuffer->begin();
1420
1421 vk::CmdCopyBuffer(m_commandBuffer->handle(), vbo2.handle(), vbo.handle(), 1, &buffer_region);
1422
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07001423 auto vbo_barrier = LvlInitStruct<VkBufferMemoryBarrier>();
John Zulaufbe8562b2020-12-15 14:21:01 -07001424 vbo_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1425 vbo_barrier.dstAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
1426 vbo_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1427 vbo_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1428 vbo_barrier.buffer = vbo.handle();
1429 vbo_barrier.offset = buffer_region.dstOffset;
1430 vbo_barrier.size = buffer_region.size;
1431
1432 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
1433
1434 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1435 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1436 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1437 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1438 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1439 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1440 &descriptor_set.set_, 0, nullptr);
1441
1442 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0, nullptr, 1,
1443 &vbo_barrier, 0, nullptr);
1444 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1445
1446 m_commandBuffer->EndRenderPass();
1447 m_commandBuffer->end();
1448 m_errorMonitor->VerifyNotFound();
1449
Jeremy Gebben170781d2020-11-19 16:21:21 -07001450 // DrawIndexed
1451 m_errorMonitor->ExpectSuccess();
1452 const float ibo_data[3] = {0.f, 0.f, 0.f};
1453 VkBufferObj ibo, ibo2;
1454 buffer_usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1455 ibo.init(*m_device, ibo.create_info(sizeof(ibo_data), buffer_usage, nullptr), mem_prop);
1456 ibo2.init(*m_device, ibo2.create_info(sizeof(ibo_data), buffer_usage, nullptr), mem_prop);
1457
1458 m_commandBuffer->reset();
1459 m_commandBuffer->begin();
1460 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1461 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1462 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), ibo.handle(), 0, VK_INDEX_TYPE_UINT16);
1463 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1464 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1465
1466 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1467 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1468 &descriptor_set.set_, 0, nullptr);
1469 m_commandBuffer->DrawIndexed(3, 1, 0, 0, 0);
1470 m_commandBuffer->EndRenderPass();
1471 m_commandBuffer->end();
1472 m_errorMonitor->VerifyNotFound();
1473
1474 m_commandBuffer->reset();
1475 m_commandBuffer->begin();
1476
1477 buffer_region = {0, 0, sizeof(ibo_data)};
1478 vk::CmdCopyBuffer(m_commandBuffer->handle(), ibo2.handle(), ibo.handle(), 1, &buffer_region);
1479
1480 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1481 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1482 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), ibo.handle(), 0, VK_INDEX_TYPE_UINT16);
1483 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1484 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1485 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1486 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1487 &descriptor_set.set_, 0, nullptr);
1488
1489 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1490 m_commandBuffer->DrawIndexed(3, 1, 0, 0, 0);
1491 m_errorMonitor->VerifyFound();
1492
1493 m_commandBuffer->EndRenderPass();
1494 m_commandBuffer->end();
1495
1496 // DrawIndirect
1497 m_errorMonitor->ExpectSuccess();
1498 VkBufferObj buffer_drawIndirect, buffer_drawIndirect2;
1499 buffer_usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1500 buffer_drawIndirect.init(*m_device, buffer_drawIndirect.create_info(sizeof(VkDrawIndirectCommand), buffer_usage, nullptr),
1501 mem_prop);
1502 buffer_drawIndirect2.init(*m_device, buffer_drawIndirect2.create_info(sizeof(VkDrawIndirectCommand), buffer_usage, nullptr),
1503 mem_prop);
1504
1505 m_commandBuffer->reset();
1506 m_commandBuffer->begin();
1507 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1508 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1509 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1510 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1511
1512 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1513 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1514 &descriptor_set.set_, 0, nullptr);
1515 vk::CmdDrawIndirect(m_commandBuffer->handle(), buffer_drawIndirect.handle(), 0, 1, sizeof(VkDrawIndirectCommand));
1516 m_commandBuffer->EndRenderPass();
1517 m_commandBuffer->end();
1518 m_errorMonitor->VerifyNotFound();
1519
1520 m_commandBuffer->reset();
1521 m_commandBuffer->begin();
1522
1523 buffer_region = {0, 0, sizeof(VkDrawIndirectCommand)};
1524 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_drawIndirect2.handle(), buffer_drawIndirect.handle(), 1, &buffer_region);
1525
1526 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1527 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1528 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1529 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1530 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1531 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1532 &descriptor_set.set_, 0, nullptr);
1533
1534 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1535 vk::CmdDrawIndirect(m_commandBuffer->handle(), buffer_drawIndirect.handle(), 0, 1, sizeof(VkDrawIndirectCommand));
1536 m_errorMonitor->VerifyFound();
1537
1538 m_commandBuffer->EndRenderPass();
1539 m_commandBuffer->end();
1540
1541 // DrawIndexedIndirect
1542 m_errorMonitor->ExpectSuccess();
1543 VkBufferObj buffer_drawIndexedIndirect, buffer_drawIndexedIndirect2;
1544 buffer_usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1545 buffer_drawIndexedIndirect.init(
1546 *m_device, buffer_drawIndexedIndirect.create_info(sizeof(VkDrawIndexedIndirectCommand), buffer_usage, nullptr), mem_prop);
1547 buffer_drawIndexedIndirect2.init(
1548 *m_device, buffer_drawIndexedIndirect2.create_info(sizeof(VkDrawIndexedIndirectCommand), buffer_usage, nullptr), mem_prop);
1549
1550 m_commandBuffer->reset();
1551 m_commandBuffer->begin();
1552 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1553 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1554 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), ibo.handle(), 0, VK_INDEX_TYPE_UINT16);
1555 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1556 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1557
1558 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1559 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1560 &descriptor_set.set_, 0, nullptr);
1561 vk::CmdDrawIndexedIndirect(m_commandBuffer->handle(), buffer_drawIndirect.handle(), 0, 1, sizeof(VkDrawIndexedIndirectCommand));
1562 m_commandBuffer->EndRenderPass();
1563 m_commandBuffer->end();
1564 m_errorMonitor->VerifyNotFound();
1565
1566 m_commandBuffer->reset();
1567 m_commandBuffer->begin();
1568
1569 buffer_region = {0, 0, sizeof(VkDrawIndexedIndirectCommand)};
1570 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_drawIndexedIndirect2.handle(), buffer_drawIndexedIndirect.handle(), 1,
1571 &buffer_region);
1572
1573 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1574 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1575 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), ibo.handle(), 0, VK_INDEX_TYPE_UINT16);
1576 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1577 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1578 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1579 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1580 &descriptor_set.set_, 0, nullptr);
1581
1582 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1583 vk::CmdDrawIndexedIndirect(m_commandBuffer->handle(), buffer_drawIndexedIndirect.handle(), 0, 1,
1584 sizeof(VkDrawIndexedIndirectCommand));
1585 m_errorMonitor->VerifyFound();
1586
1587 m_commandBuffer->EndRenderPass();
1588 m_commandBuffer->end();
1589
1590 if (has_khr_indirect) {
1591 // DrawIndirectCount
1592 auto fpCmdDrawIndirectCountKHR =
1593 (PFN_vkCmdDrawIndirectCount)vk::GetDeviceProcAddr(m_device->device(), "vkCmdDrawIndirectCountKHR");
1594 if (!fpCmdDrawIndirectCountKHR) {
1595 printf("%s Test requires unsupported vkCmdDrawIndirectCountKHR feature. Skipped.\n", kSkipPrefix);
1596 } else {
1597 m_errorMonitor->ExpectSuccess();
1598 VkBufferObj buffer_count, buffer_count2;
1599 buffer_usage =
1600 VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1601 buffer_count.init(*m_device, buffer_count.create_info(sizeof(uint32_t), buffer_usage, nullptr), mem_prop);
1602 buffer_count2.init(*m_device, buffer_count2.create_info(sizeof(uint32_t), buffer_usage, nullptr), mem_prop);
1603
1604 m_commandBuffer->reset();
1605 m_commandBuffer->begin();
1606 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1607 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1608 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1609 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1610
1611 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1612 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(),
1613 0, 1, &descriptor_set.set_, 0, nullptr);
1614 fpCmdDrawIndirectCountKHR(m_commandBuffer->handle(), buffer_drawIndirect.handle(), 0, buffer_count.handle(), 0, 1,
1615 sizeof(VkDrawIndirectCommand));
1616 m_commandBuffer->EndRenderPass();
1617 m_commandBuffer->end();
1618 m_errorMonitor->VerifyNotFound();
1619
1620 m_commandBuffer->reset();
1621 m_commandBuffer->begin();
1622
1623 buffer_region = {0, 0, sizeof(uint32_t)};
1624 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_count2.handle(), buffer_count.handle(), 1, &buffer_region);
1625
1626 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1627 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1628 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1629 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1630 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1631 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(),
1632 0, 1, &descriptor_set.set_, 0, nullptr);
1633
1634 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1635 fpCmdDrawIndirectCountKHR(m_commandBuffer->handle(), buffer_drawIndirect.handle(), 0, buffer_count.handle(), 0, 1,
1636 sizeof(VkDrawIndirectCommand));
1637 m_errorMonitor->VerifyFound();
1638
1639 m_commandBuffer->EndRenderPass();
1640 m_commandBuffer->end();
1641 }
1642
1643 // DrawIndexedIndirectCount
1644 auto fpCmdDrawIndexIndirectCountKHR =
1645 (PFN_vkCmdDrawIndirectCount)vk::GetDeviceProcAddr(m_device->device(), "vkCmdDrawIndexedIndirectCountKHR");
1646 if (!fpCmdDrawIndexIndirectCountKHR) {
1647 printf("%s Test requires unsupported vkCmdDrawIndexedIndirectCountKHR feature. Skipped.\n", kSkipPrefix);
1648 } else {
1649 m_errorMonitor->ExpectSuccess();
1650 VkBufferObj buffer_count, buffer_count2;
1651 buffer_usage =
1652 VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1653 buffer_count.init(*m_device, buffer_count.create_info(sizeof(uint32_t), buffer_usage, nullptr), mem_prop);
1654 buffer_count2.init(*m_device, buffer_count2.create_info(sizeof(uint32_t), buffer_usage, nullptr), mem_prop);
1655
1656 m_commandBuffer->reset();
1657 m_commandBuffer->begin();
1658 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1659 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1660 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), ibo.handle(), 0, VK_INDEX_TYPE_UINT16);
1661 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1662 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1663
1664 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1665 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(),
1666 0, 1, &descriptor_set.set_, 0, nullptr);
1667 fpCmdDrawIndexIndirectCountKHR(m_commandBuffer->handle(), buffer_drawIndexedIndirect.handle(), 0, buffer_count.handle(),
1668 0, 1, sizeof(VkDrawIndexedIndirectCommand));
1669 m_commandBuffer->EndRenderPass();
1670 m_commandBuffer->end();
1671 m_errorMonitor->VerifyNotFound();
1672
1673 m_commandBuffer->reset();
1674 m_commandBuffer->begin();
1675
1676 buffer_region = {0, 0, sizeof(uint32_t)};
1677 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_count2.handle(), buffer_count.handle(), 1, &buffer_region);
1678
1679 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1680 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1681 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), ibo.handle(), 0, VK_INDEX_TYPE_UINT16);
1682 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1683 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1684 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1685 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(),
1686 0, 1, &descriptor_set.set_, 0, nullptr);
1687
1688 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1689 fpCmdDrawIndexIndirectCountKHR(m_commandBuffer->handle(), buffer_drawIndexedIndirect.handle(), 0, buffer_count.handle(),
1690 0, 1, sizeof(VkDrawIndexedIndirectCommand));
1691 m_errorMonitor->VerifyFound();
1692
1693 m_commandBuffer->EndRenderPass();
1694 m_commandBuffer->end();
1695 }
1696 } else {
1697 printf("%s Test requires unsupported vkCmdDrawIndirectCountKHR & vkDrawIndexedIndirectCountKHR feature. Skipped.\n",
1698 kSkipPrefix);
1699 }
1700}
1701
1702TEST_F(VkSyncValTest, SyncCmdClear) {
1703 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
1704 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
1705 // CmdClearColorImage
1706 m_errorMonitor->ExpectSuccess();
1707 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1708 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
1709 VkImageObj image_a(m_device), image_b(m_device);
1710 auto image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 1, format, usage, VK_IMAGE_TILING_OPTIMAL);
1711 image_a.Init(image_ci);
1712 image_b.Init(image_ci);
1713
1714 VkImageSubresourceLayers layers_all{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
1715 VkOffset3D zero_offset{0, 0, 0};
1716 VkExtent3D full_extent{128, 128, 1}; // <-- image type is 2D
1717 VkImageSubresourceRange full_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
1718
1719 VkImageCopy full_region = {layers_all, zero_offset, layers_all, zero_offset, full_extent};
1720
1721 m_commandBuffer->begin();
1722
1723 image_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1724 image_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1725
1726 auto cb = m_commandBuffer->handle();
1727 VkClearColorValue ccv = {};
1728 vk::CmdClearColorImage(m_commandBuffer->handle(), image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &full_subresource_range);
1729 m_commandBuffer->end();
1730 m_errorMonitor->VerifyNotFound();
1731
1732 m_commandBuffer->reset();
1733 m_commandBuffer->begin();
1734 vk::CmdCopyImage(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
1735
1736 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1737 vk::CmdClearColorImage(m_commandBuffer->handle(), image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &full_subresource_range);
1738 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1739 vk::CmdClearColorImage(m_commandBuffer->handle(), image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &full_subresource_range);
1740 m_errorMonitor->VerifyFound();
1741
1742 m_commandBuffer->end();
1743
1744 // CmdClearDepthStencilImage
1745 format = FindSupportedDepthStencilFormat(gpu());
1746 if (!format) {
1747 printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix);
1748 return;
1749 }
1750 m_errorMonitor->ExpectSuccess();
1751 VkImageObj image_ds_a(m_device), image_ds_b(m_device);
1752 image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 1, format, usage, VK_IMAGE_TILING_OPTIMAL);
1753 image_ds_a.Init(image_ci);
1754 image_ds_b.Init(image_ci);
1755
1756 const VkImageAspectFlags ds_aspect = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
1757 image_ds_a.SetLayout(ds_aspect, VK_IMAGE_LAYOUT_GENERAL);
1758 image_ds_b.SetLayout(ds_aspect, VK_IMAGE_LAYOUT_GENERAL);
1759
1760 m_commandBuffer->begin();
1761 const VkClearDepthStencilValue clear_value = {};
1762 VkImageSubresourceRange ds_range = {ds_aspect, 0, 1, 0, 1};
1763
1764 vk::CmdClearDepthStencilImage(cb, image_ds_a.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1, &ds_range);
1765 m_commandBuffer->end();
1766 m_errorMonitor->VerifyNotFound();
1767
1768 VkImageSubresourceLayers ds_layers_all{ds_aspect, 0, 0, 1};
1769 VkImageCopy ds_full_region = {ds_layers_all, zero_offset, ds_layers_all, zero_offset, full_extent};
1770
1771 m_commandBuffer->reset();
1772 m_commandBuffer->begin();
1773 vk::CmdCopyImage(cb, image_ds_a.handle(), VK_IMAGE_LAYOUT_GENERAL, image_ds_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1774 &ds_full_region);
1775
1776 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1777 vk::CmdClearDepthStencilImage(m_commandBuffer->handle(), image_ds_a.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1,
1778 &ds_range);
1779 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1780 vk::CmdClearDepthStencilImage(m_commandBuffer->handle(), image_ds_b.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1,
1781 &ds_range);
1782 m_errorMonitor->VerifyFound();
1783
1784 m_commandBuffer->end();
1785}
1786
1787TEST_F(VkSyncValTest, SyncCmdQuery) {
1788 // CmdCopyQueryPoolResults
1789 m_errorMonitor->ExpectSuccess();
1790 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
1791 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
1792 if (IsPlatform(kNexusPlayer)) {
1793 printf("%s This test should not run on Nexus Player\n", kSkipPrefix);
1794 return;
1795 }
1796 if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) {
1797 printf("%s Queue family needs to have multiple queues to run this test.\n", kSkipPrefix);
1798 return;
1799 }
1800 uint32_t queue_count;
1801 vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_count, NULL);
Jeremy Gebbend2573fc2021-05-12 17:17:38 -06001802 std::vector<VkQueueFamilyProperties> queue_props(queue_count);
1803 vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_count, queue_props.data());
Jeremy Gebben170781d2020-11-19 16:21:21 -07001804 if (queue_props[m_device->graphics_queue_node_index_].timestampValidBits == 0) {
1805 printf("%s Device graphic queue has timestampValidBits of 0, skipping.\n", kSkipPrefix);
1806 return;
1807 }
1808
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001809 vk_testing::QueryPool query_pool;
Jeremy Gebben170781d2020-11-19 16:21:21 -07001810 VkQueryPoolCreateInfo query_pool_create_info{};
1811 query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
1812 query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
1813 query_pool_create_info.queryCount = 1;
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001814 query_pool.init(*m_device, query_pool_create_info);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001815
1816 VkBufferObj buffer_a, buffer_b;
1817 VkMemoryPropertyFlags mem_prop = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
1818 buffer_a.init_as_src_and_dst(*m_device, 256, mem_prop);
1819 buffer_b.init_as_src_and_dst(*m_device, 256, mem_prop);
1820
1821 VkBufferCopy region = {0, 0, 256};
1822
1823 auto cb = m_commandBuffer->handle();
1824 m_commandBuffer->begin();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001825 vk::CmdResetQueryPool(cb, query_pool.handle(), 0, 1);
1826 vk::CmdWriteTimestamp(cb, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool.handle(), 0);
1827 vk::CmdCopyQueryPoolResults(cb, query_pool.handle(), 0, 1, buffer_a.handle(), 0, 0, VK_QUERY_RESULT_WAIT_BIT);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001828 m_commandBuffer->end();
1829 m_errorMonitor->VerifyNotFound();
1830
1831 m_commandBuffer->reset();
1832 m_commandBuffer->begin();
1833 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &region);
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001834 vk::CmdResetQueryPool(cb, query_pool.handle(), 0, 1);
1835 vk::CmdWriteTimestamp(cb, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool.handle(), 0);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001836 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001837 vk::CmdCopyQueryPoolResults(cb, query_pool.handle(), 0, 1, buffer_a.handle(), 0, 256, VK_QUERY_RESULT_WAIT_BIT);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001838 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001839 vk::CmdCopyQueryPoolResults(cb, query_pool.handle(), 0, 1, buffer_b.handle(), 0, 256, VK_QUERY_RESULT_WAIT_BIT);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001840 m_commandBuffer->end();
1841 m_errorMonitor->VerifyFound();
1842
1843 // TODO:Track VkQueryPool
1844 // TODO:CmdWriteTimestamp
Jeremy Gebben170781d2020-11-19 16:21:21 -07001845}
1846
1847TEST_F(VkSyncValTest, SyncCmdDrawDepthStencil) {
1848 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
1849 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
1850 m_errorMonitor->ExpectSuccess();
1851
1852 const auto format_ds = FindSupportedDepthStencilFormat(gpu());
1853 if (!format_ds) {
1854 printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix);
1855 return;
1856 }
1857 const auto format_dp = FindSupportedDepthOnlyFormat(gpu());
1858 if (!format_dp) {
1859 printf("%s No only Depth format found. Skipped.\n", kSkipPrefix);
1860 return;
1861 }
1862 const auto format_st = FindSupportedStencilOnlyFormat(gpu());
1863 if (!format_st) {
1864 printf("%s No only Stencil format found. Skipped.\n", kSkipPrefix);
1865 return;
1866 }
1867
1868 VkDepthStencilObj image_ds(m_device), image_dp(m_device), image_st(m_device);
1869 image_ds.Init(m_device, 16, 16, format_ds);
1870 image_dp.Init(m_device, 16, 16, format_dp);
1871 image_st.Init(m_device, 16, 16, format_st);
1872
1873 VkRenderpassObj rp_ds(m_device, format_ds, true), rp_dp(m_device, format_dp, true), rp_st(m_device, format_st, true);
1874
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001875 vk_testing::Framebuffer fb_ds, fb_dp, fb_st;
Jeremy Gebben170781d2020-11-19 16:21:21 -07001876 VkFramebufferCreateInfo fbci = {
1877 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp_ds.handle(), 1, image_ds.BindInfo(), 16, 16, 1};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001878 fb_ds.init(*m_device, fbci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001879 fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp_dp.handle(), 1, image_dp.BindInfo(), 16, 16, 1};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001880 fb_dp.init(*m_device, fbci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001881 fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp_st.handle(), 1, image_st.BindInfo(), 16, 16, 1};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001882 fb_st.init(*m_device, fbci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001883
1884 VkStencilOpState stencil = {};
1885 stencil.failOp = VK_STENCIL_OP_KEEP;
1886 stencil.passOp = VK_STENCIL_OP_KEEP;
1887 stencil.depthFailOp = VK_STENCIL_OP_KEEP;
1888 stencil.compareOp = VK_COMPARE_OP_NEVER;
1889
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07001890 auto ds_ci = LvlInitStruct<VkPipelineDepthStencilStateCreateInfo>();
Jeremy Gebben170781d2020-11-19 16:21:21 -07001891 ds_ci.depthTestEnable = VK_TRUE;
1892 ds_ci.depthWriteEnable = VK_TRUE;
1893 ds_ci.depthCompareOp = VK_COMPARE_OP_NEVER;
1894 ds_ci.stencilTestEnable = VK_TRUE;
1895 ds_ci.front = stencil;
1896 ds_ci.back = stencil;
1897
1898 CreatePipelineHelper g_pipe_ds(*this), g_pipe_dp(*this), g_pipe_st(*this);
1899 g_pipe_ds.InitInfo();
1900 g_pipe_ds.gp_ci_.renderPass = rp_ds.handle();
1901 g_pipe_ds.gp_ci_.pDepthStencilState = &ds_ci;
1902 g_pipe_ds.InitState();
1903 ASSERT_VK_SUCCESS(g_pipe_ds.CreateGraphicsPipeline());
1904 g_pipe_dp.InitInfo();
1905 g_pipe_dp.gp_ci_.renderPass = rp_dp.handle();
1906 ds_ci.stencilTestEnable = VK_FALSE;
1907 g_pipe_dp.gp_ci_.pDepthStencilState = &ds_ci;
1908 g_pipe_dp.InitState();
1909 ASSERT_VK_SUCCESS(g_pipe_dp.CreateGraphicsPipeline());
1910 g_pipe_st.InitInfo();
1911 g_pipe_st.gp_ci_.renderPass = rp_st.handle();
1912 ds_ci.depthTestEnable = VK_FALSE;
1913 ds_ci.stencilTestEnable = VK_TRUE;
1914 g_pipe_st.gp_ci_.pDepthStencilState = &ds_ci;
1915 g_pipe_st.InitState();
1916 ASSERT_VK_SUCCESS(g_pipe_st.CreateGraphicsPipeline());
1917
1918 m_commandBuffer->begin();
1919 m_renderPassBeginInfo.renderArea = {{0, 0}, {16, 16}};
1920 m_renderPassBeginInfo.pClearValues = nullptr;
1921 m_renderPassBeginInfo.clearValueCount = 0;
1922
1923 m_renderPassBeginInfo.renderPass = rp_ds.handle();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001924 m_renderPassBeginInfo.framebuffer = fb_ds.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07001925 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1926 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_ds.pipeline_);
1927 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1928 m_commandBuffer->EndRenderPass();
1929
1930 m_renderPassBeginInfo.renderPass = rp_dp.handle();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001931 m_renderPassBeginInfo.framebuffer = fb_dp.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07001932 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1933 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_dp.pipeline_);
1934 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1935 m_commandBuffer->EndRenderPass();
1936
1937 m_renderPassBeginInfo.renderPass = rp_st.handle();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001938 m_renderPassBeginInfo.framebuffer = fb_st.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07001939 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1940 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_st.pipeline_);
1941 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1942 m_commandBuffer->EndRenderPass();
1943
1944 m_commandBuffer->end();
1945 m_errorMonitor->VerifyNotFound();
1946
1947 m_commandBuffer->reset();
1948 m_commandBuffer->begin();
1949
1950 VkImageCopy copyRegion;
1951 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
1952 copyRegion.srcSubresource.mipLevel = 0;
1953 copyRegion.srcSubresource.baseArrayLayer = 0;
1954 copyRegion.srcSubresource.layerCount = 1;
1955 copyRegion.srcOffset = {0, 0, 0};
1956 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
1957 copyRegion.dstSubresource.mipLevel = 0;
1958 copyRegion.dstSubresource.baseArrayLayer = 0;
1959 copyRegion.dstSubresource.layerCount = 1;
1960 copyRegion.dstOffset = {0, 0, 0};
1961 copyRegion.extent = {16, 16, 1};
1962
1963 m_commandBuffer->CopyImage(image_ds.handle(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, image_dp.handle(),
1964 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 1, &copyRegion);
1965
1966 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
1967 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
1968 m_commandBuffer->CopyImage(image_ds.handle(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, image_st.handle(),
1969 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 1, &copyRegion);
1970 m_renderPassBeginInfo.renderPass = rp_ds.handle();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001971 m_renderPassBeginInfo.framebuffer = fb_ds.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07001972 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1973 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1974 m_errorMonitor->VerifyFound();
1975 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1976 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_ds.pipeline_);
1977 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1978 m_commandBuffer->EndRenderPass();
1979
1980 m_renderPassBeginInfo.renderPass = rp_dp.handle();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001981 m_renderPassBeginInfo.framebuffer = fb_dp.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07001982 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1983 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1984 m_errorMonitor->VerifyFound();
1985 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1986 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_dp.pipeline_);
1987 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1988 m_commandBuffer->EndRenderPass();
1989
1990 m_renderPassBeginInfo.renderPass = rp_st.handle();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001991 m_renderPassBeginInfo.framebuffer = fb_st.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07001992 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1993 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1994 m_errorMonitor->VerifyFound();
1995 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1996 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_st.pipeline_);
1997 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1998 m_commandBuffer->EndRenderPass();
1999
2000 m_commandBuffer->end();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002001}
2002
John Zulaufd57a36b2021-08-16 10:34:44 -06002003
Jeremy Gebben170781d2020-11-19 16:21:21 -07002004TEST_F(VkSyncValTest, RenderPassLoadHazardVsInitialLayout) {
2005 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
John Zulaufd57a36b2021-08-16 10:34:44 -06002006 bool do_none_load_op_test = false;
2007 if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_LOAD_STORE_OP_NONE_EXTENSION_NAME)) {
2008 m_device_extension_names.push_back(VK_EXT_LOAD_STORE_OP_NONE_EXTENSION_NAME);
2009 do_none_load_op_test = true;
2010 }
2011
Jeremy Gebben170781d2020-11-19 16:21:21 -07002012 ASSERT_NO_FATAL_FAILURE(InitState());
2013 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2014
2015 VkImageUsageFlags usage_color = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
2016 VkImageUsageFlags usage_input = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
2017 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
2018 VkImageObj image_color(m_device), image_input(m_device);
2019 auto image_ci = VkImageObj::ImageCreateInfo2D(32, 32, 1, 1, format, usage_color, VK_IMAGE_TILING_OPTIMAL);
2020 image_color.Init(image_ci);
2021 image_ci.usage = usage_input;
2022 image_input.Init(image_ci);
2023 VkImageView attachments[] = {image_color.targetView(format), image_input.targetView(format)};
2024
John Zulaufd57a36b2021-08-16 10:34:44 -06002025 VkAttachmentDescription attachmentDescriptions[] = {
Jeremy Gebben170781d2020-11-19 16:21:21 -07002026 // Result attachment
2027 {(VkAttachmentDescriptionFlags)0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR,
2028 VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
2029 VK_IMAGE_LAYOUT_UNDEFINED, // Here causes DesiredError that SYNC-HAZARD-NONE in BeginRenderPass.
2030 // It should be VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
2031 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
2032 // Input attachment
2033 {(VkAttachmentDescriptionFlags)0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD,
2034 VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
2035 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL}};
2036
2037 const VkAttachmentReference resultAttachmentRef = {0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
2038 const VkAttachmentReference inputAttachmentRef = {1u, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};
2039
2040 const VkSubpassDescription subpassDescription = {(VkSubpassDescriptionFlags)0,
2041 VK_PIPELINE_BIND_POINT_GRAPHICS,
2042 1u,
2043 &inputAttachmentRef,
2044 1u,
2045 &resultAttachmentRef,
2046 0,
2047 0,
2048 0u,
2049 0};
2050
2051 const VkSubpassDependency subpassDependency = {VK_SUBPASS_EXTERNAL,
2052 0,
2053 VK_PIPELINE_STAGE_TRANSFER_BIT,
2054 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
2055 VK_ACCESS_TRANSFER_WRITE_BIT,
2056 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | VK_ACCESS_SHADER_READ_BIT,
2057 VK_DEPENDENCY_BY_REGION_BIT};
2058
2059 const VkRenderPassCreateInfo renderPassInfo = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
2060 0,
2061 (VkRenderPassCreateFlags)0,
2062 2u,
2063 attachmentDescriptions,
2064 1u,
2065 &subpassDescription,
2066 1u,
2067 &subpassDependency};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002068 vk_testing::RenderPass rp;
2069 rp.init(*m_device, renderPassInfo);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002070
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002071 vk_testing::Framebuffer fb;
2072 VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp.handle(), 2, attachments, 32, 32, 1};
2073 fb.init(*m_device, fbci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002074
2075 image_input.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
2076
2077 m_commandBuffer->begin();
2078
2079 m_renderPassBeginInfo.renderArea = {{0, 0}, {32, 32}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002080 m_renderPassBeginInfo.renderPass = rp.handle();
2081 m_renderPassBeginInfo.framebuffer = fb.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002082
2083 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
2084 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
2085 // Even though we have no accesses prior, the layout transition *is* an access, so load can be validated vs. layout transition
2086 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2087 m_errorMonitor->VerifyFound();
John Zulaufd57a36b2021-08-16 10:34:44 -06002088
2089 vk_testing::RenderPass rp_no_load_store;
2090 if (do_none_load_op_test) {
2091 m_errorMonitor->ExpectSuccess();
2092 attachmentDescriptions[0].loadOp = VK_ATTACHMENT_LOAD_OP_NONE_EXT;
2093 attachmentDescriptions[0].storeOp = VK_ATTACHMENT_STORE_OP_NONE_EXT;
2094 attachmentDescriptions[1].loadOp = VK_ATTACHMENT_LOAD_OP_NONE_EXT;
2095 attachmentDescriptions[1].storeOp = VK_ATTACHMENT_STORE_OP_NONE_EXT;
2096 rp_no_load_store.init(*m_device, renderPassInfo);
2097 m_renderPassBeginInfo.renderPass = rp_no_load_store.handle();
2098 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2099 m_commandBuffer->EndRenderPass();
2100 m_errorMonitor->VerifyNotFound();
2101 } else {
2102 printf("%s VK_EXT_load_store_op_none not supported, skipping sub-test\n", kSkipPrefix);
2103 }
Jeremy Gebben170781d2020-11-19 16:21:21 -07002104}
2105
2106TEST_F(VkSyncValTest, SyncRenderPassWithWrongDepthStencilInitialLayout) {
2107 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
2108 ASSERT_NO_FATAL_FAILURE(InitState());
2109 if (IsPlatform(kNexusPlayer)) {
2110 printf("%s This test should not run on Nexus Player\n", kSkipPrefix);
2111 return;
2112 }
2113
2114 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2115
2116 VkFormat color_format = VK_FORMAT_R8G8B8A8_UNORM;
2117 VkFormat ds_format = FindSupportedDepthStencilFormat(gpu());
2118 if (!ds_format) {
2119 printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix);
2120 return;
2121 }
2122 VkImageUsageFlags usage_color = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
2123 VkImageUsageFlags usage_ds = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
2124 VkImageObj image_color(m_device), image_color2(m_device);
2125 auto image_ci = VkImageObj::ImageCreateInfo2D(32, 32, 1, 1, color_format, usage_color, VK_IMAGE_TILING_OPTIMAL);
2126 image_color.Init(image_ci);
2127 image_color2.Init(image_ci);
2128 VkDepthStencilObj image_ds(m_device);
2129 image_ds.Init(m_device, 32, 32, ds_format, usage_ds);
2130
2131 const VkAttachmentDescription colorAttachmentDescription = {(VkAttachmentDescriptionFlags)0,
2132 color_format,
2133 VK_SAMPLE_COUNT_1_BIT,
2134 VK_ATTACHMENT_LOAD_OP_CLEAR,
2135 VK_ATTACHMENT_STORE_OP_STORE,
2136 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2137 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2138 VK_IMAGE_LAYOUT_UNDEFINED,
2139 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
2140
2141 const VkAttachmentDescription depthStencilAttachmentDescription = {
2142 (VkAttachmentDescriptionFlags)0, ds_format, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR,
2143 VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE,
2144 VK_IMAGE_LAYOUT_UNDEFINED, // Here causes DesiredError that SYNC-HAZARD-WRITE_AFTER_WRITE in BeginRenderPass.
2145 // It should be VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
2146 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
2147
2148 std::vector<VkAttachmentDescription> attachmentDescriptions;
2149 attachmentDescriptions.push_back(colorAttachmentDescription);
2150 attachmentDescriptions.push_back(depthStencilAttachmentDescription);
2151
2152 const VkAttachmentReference colorAttachmentRef = {0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
2153
2154 const VkAttachmentReference depthStencilAttachmentRef = {1u, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
2155
2156 const VkSubpassDescription subpassDescription = {(VkSubpassDescriptionFlags)0,
2157 VK_PIPELINE_BIND_POINT_GRAPHICS,
2158 0u,
2159 0,
2160 1u,
2161 &colorAttachmentRef,
2162 0,
2163 &depthStencilAttachmentRef,
2164 0u,
2165 0};
2166
2167 const VkRenderPassCreateInfo renderPassInfo = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
2168 0,
2169 (VkRenderPassCreateFlags)0,
2170 (uint32_t)attachmentDescriptions.size(),
2171 &attachmentDescriptions[0],
2172 1u,
2173 &subpassDescription,
2174 0u,
2175 0};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002176 vk_testing::RenderPass rp;
2177 rp.init(*m_device, renderPassInfo);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002178
2179 VkImageView fb_attachments[] = {image_color.targetView(color_format),
2180 image_ds.targetView(ds_format, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)};
2181 const VkFramebufferCreateInfo fbci = {
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002182 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, 0, 0u, rp.handle(), 2u, fb_attachments, 32, 32, 1u,
Jeremy Gebben170781d2020-11-19 16:21:21 -07002183 };
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002184 vk_testing::Framebuffer fb;
2185 fb.init(*m_device, fbci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002186 fb_attachments[0] = image_color2.targetView(color_format);
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002187 vk_testing::Framebuffer fb1;
2188 fb1.init(*m_device, fbci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002189
2190 CreatePipelineHelper g_pipe(*this);
2191 g_pipe.InitInfo();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002192 g_pipe.gp_ci_.renderPass = rp.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002193
2194 VkStencilOpState stencil = {};
2195 stencil.failOp = VK_STENCIL_OP_KEEP;
2196 stencil.passOp = VK_STENCIL_OP_KEEP;
2197 stencil.depthFailOp = VK_STENCIL_OP_KEEP;
2198 stencil.compareOp = VK_COMPARE_OP_NEVER;
2199
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07002200 auto ds_ci = LvlInitStruct<VkPipelineDepthStencilStateCreateInfo>();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002201 ds_ci.depthTestEnable = VK_TRUE;
2202 ds_ci.depthWriteEnable = VK_TRUE;
2203 ds_ci.depthCompareOp = VK_COMPARE_OP_NEVER;
2204 ds_ci.stencilTestEnable = VK_TRUE;
2205 ds_ci.front = stencil;
2206 ds_ci.back = stencil;
2207
2208 g_pipe.gp_ci_.pDepthStencilState = &ds_ci;
2209 g_pipe.InitState();
2210 ASSERT_VK_SUCCESS(g_pipe.CreateGraphicsPipeline());
2211
2212 m_commandBuffer->begin();
Tony-LunarG73f37032021-06-07 11:47:03 -06002213 VkClearValue clear = {};
2214 std::array<VkClearValue, 2> clear_values = { {clear, clear} };
2215 m_renderPassBeginInfo.pClearValues = clear_values.data();
2216 m_renderPassBeginInfo.clearValueCount = clear_values.size();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002217 m_renderPassBeginInfo.renderArea = {{0, 0}, {32, 32}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002218 m_renderPassBeginInfo.renderPass = rp.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002219
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002220 m_renderPassBeginInfo.framebuffer = fb.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002221 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2222 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
2223 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
2224 m_commandBuffer->EndRenderPass();
2225
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002226 m_renderPassBeginInfo.framebuffer = fb1.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002227
2228 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
2229 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2230 m_errorMonitor->VerifyFound();
2231}
2232
2233TEST_F(VkSyncValTest, SyncLayoutTransition) {
2234 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
2235 ASSERT_NO_FATAL_FAILURE(InitState());
2236 if (IsPlatform(kNexusPlayer)) {
2237 printf("%s This test should not run on Nexus Player\n", kSkipPrefix);
2238 return;
2239 }
2240
2241 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2242
2243 VkImageUsageFlags usage_color = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
2244 VkImageUsageFlags usage_input =
2245 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
2246 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
2247 VkImageObj image_color(m_device), image_input(m_device);
2248 auto image_ci = VkImageObj::ImageCreateInfo2D(64, 64, 1, 1, format, usage_input, VK_IMAGE_TILING_OPTIMAL);
2249 image_input.InitNoLayout(image_ci);
2250 image_ci.usage = usage_color;
2251 image_color.InitNoLayout(image_ci);
2252 VkImageView view_input = image_input.targetView(format);
2253 VkImageView view_color = image_color.targetView(format);
2254 VkImageView attachments[] = {view_color, view_input};
2255
2256 const VkAttachmentDescription fbAttachment = {
2257 0u,
2258 format,
2259 VK_SAMPLE_COUNT_1_BIT,
2260 VK_ATTACHMENT_LOAD_OP_CLEAR,
2261 VK_ATTACHMENT_STORE_OP_STORE,
2262 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2263 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2264 VK_IMAGE_LAYOUT_UNDEFINED,
2265 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
2266 };
2267
2268 std::vector<VkAttachmentDescription> attachmentDescs;
2269 attachmentDescs.push_back(fbAttachment);
2270
2271 // Add it as a frame buffer attachment.
2272 const VkAttachmentDescription inputAttachment = {
2273 0u,
2274 format,
2275 VK_SAMPLE_COUNT_1_BIT,
2276 VK_ATTACHMENT_LOAD_OP_LOAD,
2277 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2278 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2279 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2280 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
2281 VK_IMAGE_LAYOUT_GENERAL,
2282 };
2283 attachmentDescs.push_back(inputAttachment);
2284
2285 std::vector<VkAttachmentReference> inputAttachments;
2286 const VkAttachmentReference inputRef = {
2287 1u,
2288 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
2289 };
2290 inputAttachments.push_back(inputRef);
2291
2292 const VkAttachmentReference colorRef = {
2293 0u,
2294 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
2295 };
2296 const std::vector<VkAttachmentReference> colorAttachments(1u, colorRef);
2297
2298 const VkSubpassDescription subpass = {
2299 0u,
2300 VK_PIPELINE_BIND_POINT_GRAPHICS,
2301 static_cast<uint32_t>(inputAttachments.size()),
2302 inputAttachments.data(),
2303 static_cast<uint32_t>(colorAttachments.size()),
2304 colorAttachments.data(),
2305 0u,
2306 nullptr,
2307 0u,
2308 nullptr,
2309 };
2310 const std::vector<VkSubpassDescription> subpasses(1u, subpass);
2311
2312 const VkRenderPassCreateInfo renderPassInfo = {
2313 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
2314 nullptr,
2315 0u,
2316 static_cast<uint32_t>(attachmentDescs.size()),
2317 attachmentDescs.data(),
2318 static_cast<uint32_t>(subpasses.size()),
2319 subpasses.data(),
2320 0u,
2321 nullptr,
2322 };
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002323 vk_testing::RenderPass rp;
2324 rp.init(*m_device, renderPassInfo);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002325
2326 const VkFramebufferCreateInfo fbci = {
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002327 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, 0, 0u, rp.handle(), 2u, attachments, 64, 64, 1u,
Jeremy Gebben170781d2020-11-19 16:21:21 -07002328 };
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002329 vk_testing::Framebuffer fb;
2330 fb.init(*m_device, fbci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002331
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002332 vk_testing::Sampler sampler;
Jeremy Gebben170781d2020-11-19 16:21:21 -07002333 VkSamplerCreateInfo sampler_info = SafeSaneSamplerCreateInfo();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002334 sampler.init(*m_device, sampler_info);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002335
sfricke-samsung1c0b96a2021-07-08 22:24:09 -07002336 char const *fsSource = R"glsl(
2337 #version 450
2338 layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;
2339 void main() {
2340 vec4 color = subpassLoad(x);
2341 }
2342 )glsl";
Jeremy Gebben170781d2020-11-19 16:21:21 -07002343
2344 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
2345 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
2346
2347 CreatePipelineHelper g_pipe(*this);
2348 g_pipe.InitInfo();
2349 g_pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
2350 g_pipe.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002351 g_pipe.gp_ci_.renderPass = rp.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002352 g_pipe.InitState();
2353 ASSERT_VK_SUCCESS(g_pipe.CreateGraphicsPipeline());
2354
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002355 g_pipe.descriptor_set_->WriteDescriptorImageInfo(0, view_input, sampler.handle(), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002356 g_pipe.descriptor_set_->UpdateDescriptorSets();
2357
2358 m_commandBuffer->begin();
2359 auto cb = m_commandBuffer->handle();
2360 VkClearColorValue ccv = {};
2361 VkImageSubresourceRange full_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
2362
2363 const VkImageMemoryBarrier preClearBarrier = {
2364 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, 0, 0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
2365 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, 0, image_input.handle(), full_subresource_range,
2366 };
2367 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u,
2368 &preClearBarrier);
2369
2370 vk::CmdClearColorImage(m_commandBuffer->handle(), image_input.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &ccv, 1,
2371 &full_subresource_range);
2372
2373 const VkImageMemoryBarrier postClearBarrier = {
2374 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
2375 0,
2376 VK_ACCESS_TRANSFER_WRITE_BIT,
2377 VK_ACCESS_SHADER_READ_BIT,
2378 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
2379 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
2380 0,
2381 0,
2382 image_input.handle(),
2383 full_subresource_range,
2384 };
2385 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u, nullptr, 0u, nullptr,
2386 1u, &postClearBarrier);
2387
2388 m_renderPassBeginInfo.renderArea = {{0, 0}, {64, 64}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002389 m_renderPassBeginInfo.renderPass = rp.handle();
2390 m_renderPassBeginInfo.framebuffer = fb.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002391
2392 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2393 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
2394 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
2395 &g_pipe.descriptor_set_->set_, 0, nullptr);
2396
2397 // Positive test for ordering rules between load and input attachment usage
2398 m_errorMonitor->ExpectSuccess();
2399 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
2400
2401 // Positive test for store ordering vs. input attachment and dependency *to* external for layout transition
2402 m_commandBuffer->EndRenderPass();
2403 m_errorMonitor->VerifyNotFound();
2404
2405 // Catch a conflict with the input attachment final layout transition
2406 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
2407 vk::CmdClearColorImage(m_commandBuffer->handle(), image_input.handle(), VK_IMAGE_LAYOUT_GENERAL, &ccv, 1,
2408 &full_subresource_range);
2409 m_errorMonitor->VerifyFound();
2410}
2411
2412TEST_F(VkSyncValTest, SyncSubpassMultiDep) {
2413 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
2414 ASSERT_NO_FATAL_FAILURE(InitState());
2415 if (IsPlatform(kNexusPlayer)) {
2416 printf("%s This test should not run on Nexus Player\n", kSkipPrefix);
2417 return;
2418 }
2419
2420 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2421
2422 VkImageUsageFlags usage_color = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
2423 VkImageUsageFlags usage_input =
2424 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
2425 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
2426 VkImageObj image_color(m_device), image_input(m_device);
2427 auto image_ci = VkImageObj::ImageCreateInfo2D(64, 64, 1, 1, format, usage_input, VK_IMAGE_TILING_OPTIMAL);
2428 image_input.InitNoLayout(image_ci);
2429 image_ci.usage = usage_color;
2430 image_color.InitNoLayout(image_ci);
2431 VkImageView view_input = image_input.targetView(format);
2432 VkImageView view_color = image_color.targetView(format);
2433 VkImageView attachments[] = {view_color, view_input};
2434 VkImageSubresourceRange full_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
2435 VkImageSubresourceLayers mip_0_layer_0{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
2436 VkOffset3D image_zero{0, 0, 0};
2437 VkExtent3D image_size{64, 64, 1};
2438 VkImageCopy full_region{mip_0_layer_0, image_zero, mip_0_layer_0, image_zero, image_size};
2439
2440 const VkAttachmentDescription fbAttachment = {
2441 0u,
2442 format,
2443 VK_SAMPLE_COUNT_1_BIT,
2444 VK_ATTACHMENT_LOAD_OP_CLEAR,
2445 VK_ATTACHMENT_STORE_OP_STORE,
2446 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2447 VK_ATTACHMENT_STORE_OP_STORE,
2448 VK_IMAGE_LAYOUT_GENERAL,
2449 VK_IMAGE_LAYOUT_GENERAL,
2450 };
2451
2452 std::vector<VkAttachmentDescription> attachmentDescs;
2453 attachmentDescs.push_back(fbAttachment);
2454
2455 // Add it as a frame buffer attachment.
2456 const VkAttachmentDescription inputAttachment = {
2457 0u,
2458 format,
2459 VK_SAMPLE_COUNT_1_BIT,
2460 VK_ATTACHMENT_LOAD_OP_LOAD,
2461 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2462 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2463 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2464 VK_IMAGE_LAYOUT_GENERAL,
2465 VK_IMAGE_LAYOUT_GENERAL,
2466 };
2467 attachmentDescs.push_back(inputAttachment);
2468
2469 std::vector<VkAttachmentReference> inputAttachments;
2470 const VkAttachmentReference inputRef = {
2471 1u,
2472 VK_IMAGE_LAYOUT_GENERAL,
2473 };
2474 inputAttachments.push_back(inputRef);
2475
2476 const VkAttachmentReference colorRef = {
2477 0u,
2478 VK_IMAGE_LAYOUT_GENERAL,
2479 };
2480 const std::vector<VkAttachmentReference> colorAttachments(1u, colorRef);
2481
2482 const VkSubpassDescription subpass = {
2483 0u,
2484 VK_PIPELINE_BIND_POINT_GRAPHICS,
2485 static_cast<uint32_t>(inputAttachments.size()),
2486 inputAttachments.data(),
2487 static_cast<uint32_t>(colorAttachments.size()),
2488 colorAttachments.data(),
2489 0u,
2490 nullptr,
2491 0u,
2492 nullptr,
2493 };
2494 const std::vector<VkSubpassDescription> subpasses(1u, subpass);
2495
2496 std::vector<VkSubpassDependency> subpass_dep_postive;
2497 subpass_dep_postive.push_back({VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_TRANSFER_BIT,
2498 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2499 VK_DEPENDENCY_VIEW_LOCAL_BIT});
2500 subpass_dep_postive.push_back({VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_TRANSFER_BIT,
2501 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_TRANSFER_WRITE_BIT,
2502 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, VK_DEPENDENCY_VIEW_LOCAL_BIT});
2503 subpass_dep_postive.push_back({0, VK_SUBPASS_EXTERNAL, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2504 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2505 VK_ACCESS_TRANSFER_READ_BIT, VK_DEPENDENCY_VIEW_LOCAL_BIT});
2506 subpass_dep_postive.push_back({0, VK_SUBPASS_EXTERNAL, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2507 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2508 VK_ACCESS_TRANSFER_WRITE_BIT, VK_DEPENDENCY_VIEW_LOCAL_BIT});
2509
2510 VkRenderPassCreateInfo renderPassInfo = {
2511 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
2512 nullptr,
2513 0u,
2514 static_cast<uint32_t>(attachmentDescs.size()),
2515 attachmentDescs.data(),
2516 static_cast<uint32_t>(subpasses.size()),
2517 subpasses.data(),
2518 static_cast<uint32_t>(subpass_dep_postive.size()),
2519 subpass_dep_postive.data(),
2520 };
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002521 vk_testing::RenderPass rp_positive;
2522 rp_positive.init(*m_device, renderPassInfo);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002523
2524 std::vector<VkSubpassDependency> subpass_dep_negative;
2525 subpass_dep_negative.push_back({VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_TRANSFER_BIT,
2526 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2527 VK_DEPENDENCY_VIEW_LOCAL_BIT});
2528 // Show that the two barriers do *not* chain by breaking the positive barrier into two bits.
2529 subpass_dep_negative.push_back({VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_TRANSFER_BIT,
2530 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, 0,
2531 VK_DEPENDENCY_VIEW_LOCAL_BIT});
2532 subpass_dep_negative.push_back({VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2533 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
2534 VK_DEPENDENCY_VIEW_LOCAL_BIT});
2535
2536 renderPassInfo.dependencyCount = static_cast<uint32_t>(subpass_dep_negative.size());
2537 renderPassInfo.pDependencies = subpass_dep_negative.data();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002538 vk_testing::RenderPass rp_negative;
2539 rp_negative.init(*m_device, renderPassInfo);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002540
2541 // rp_postive and rp_negative should be compatible for the same fb object
2542 const VkFramebufferCreateInfo fbci = {
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002543 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, 0, 0u, rp_positive.handle(), 2u, attachments, 64, 64, 1u,
Jeremy Gebben170781d2020-11-19 16:21:21 -07002544 };
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002545 vk_testing::Framebuffer fb;
2546 fb.init(*m_device, fbci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002547
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002548 vk_testing::Sampler sampler;
Jeremy Gebben170781d2020-11-19 16:21:21 -07002549 VkSamplerCreateInfo sampler_info = SafeSaneSamplerCreateInfo();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002550 sampler.init(*m_device, sampler_info);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002551
sfricke-samsung1c0b96a2021-07-08 22:24:09 -07002552 char const *fsSource = R"glsl(
2553 #version 450
2554 layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;
2555 void main() {
2556 vec4 color = subpassLoad(x);
2557 }
2558 )glsl";
Jeremy Gebben170781d2020-11-19 16:21:21 -07002559
2560 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
2561 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
2562
2563 CreatePipelineHelper g_pipe(*this);
2564 g_pipe.InitInfo();
2565 g_pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
2566 g_pipe.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002567 g_pipe.gp_ci_.renderPass = rp_positive.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002568 g_pipe.InitState();
2569 ASSERT_VK_SUCCESS(g_pipe.CreateGraphicsPipeline());
2570
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002571 g_pipe.descriptor_set_->WriteDescriptorImageInfo(0, view_input, sampler.handle(), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002572 g_pipe.descriptor_set_->UpdateDescriptorSets();
2573
2574 m_commandBuffer->begin();
2575 auto cb = m_commandBuffer->handle();
2576 VkClearColorValue ccv = {};
2577
2578 const VkImageMemoryBarrier xferDestBarrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
2579 nullptr,
2580 VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT,
2581 VK_ACCESS_TRANSFER_WRITE_BIT,
2582 VK_IMAGE_LAYOUT_GENERAL,
2583 VK_IMAGE_LAYOUT_GENERAL,
2584 VK_QUEUE_FAMILY_IGNORED,
2585 VK_QUEUE_FAMILY_IGNORED,
2586 VK_NULL_HANDLE,
2587 full_subresource_range};
2588 const VkImageMemoryBarrier xferDestToSrcBarrier = {
2589 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
2590 nullptr,
2591 VK_ACCESS_TRANSFER_WRITE_BIT,
2592 VK_ACCESS_TRANSFER_READ_BIT,
2593 VK_IMAGE_LAYOUT_GENERAL,
2594 VK_IMAGE_LAYOUT_GENERAL,
2595 VK_QUEUE_FAMILY_IGNORED,
2596 VK_QUEUE_FAMILY_IGNORED,
2597 VK_NULL_HANDLE,
2598 full_subresource_range,
2599 };
2600
2601 VkImageMemoryBarrier preClearBarrier = xferDestBarrier;
2602 preClearBarrier.image = image_color.handle();
2603
2604 VkImageMemoryBarrier preCopyBarriers[2] = {xferDestToSrcBarrier, xferDestBarrier};
2605 preCopyBarriers[0].image = image_color.handle();
2606 preCopyBarriers[1].image = image_input.handle();
2607 // Positive test for ordering rules between load and input attachment usage
2608 m_errorMonitor->ExpectSuccess();
2609
2610 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u,
2611 &preClearBarrier);
2612
2613 vk::CmdClearColorImage(m_commandBuffer->handle(), image_color.handle(), VK_IMAGE_LAYOUT_GENERAL, &ccv, 1,
2614 &full_subresource_range);
2615
2616 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 2u,
2617 preCopyBarriers);
2618
2619 vk::CmdCopyImage(m_commandBuffer->handle(), image_color.handle(), VK_IMAGE_LAYOUT_GENERAL, image_input.handle(),
2620 VK_IMAGE_LAYOUT_GENERAL, 1u, &full_region);
2621
2622 // No post copy image barrier, we are testing the subpass dependencies
2623
2624 m_renderPassBeginInfo.renderArea = {{0, 0}, {64, 64}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002625 m_renderPassBeginInfo.renderPass = rp_positive.handle();
2626 m_renderPassBeginInfo.framebuffer = fb.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002627
2628 // Postive renderpass multidependency test
2629 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2630 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
2631 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
2632 &g_pipe.descriptor_set_->set_, 0, nullptr);
2633
2634 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
2635
2636 // Positive test for store ordering vs. input attachment and dependency *to* external for layout transition
2637 m_commandBuffer->EndRenderPass();
2638 // m_errorMonitor->VerifyNotFound();
2639
2640 vk::CmdCopyImage(m_commandBuffer->handle(), image_color.handle(), VK_IMAGE_LAYOUT_GENERAL, image_input.handle(),
2641 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &full_region);
2642 m_errorMonitor->VerifyNotFound();
2643
2644 m_renderPassBeginInfo.renderArea = {{0, 0}, {64, 64}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002645 m_renderPassBeginInfo.renderPass = rp_negative.handle();
2646 m_renderPassBeginInfo.framebuffer = fb.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002647
2648 // Postive renderpass multidependency test, will fail IFF the dependencies are acting indepently.
2649 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "SYNC-HAZARD-READ_AFTER_WRITE");
2650 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2651 m_errorMonitor->VerifyFound();
2652}
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002653
2654TEST_F(VkSyncValTest, RenderPassAsyncHazard) {
2655 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
2656 ASSERT_NO_FATAL_FAILURE(InitState());
2657
Nathaniel Cesariof9cd1a82021-07-24 08:48:55 -06002658 if (IsPlatform(kPixel3) || IsPlatform(kPixel3aXL)) {
2659 printf("%s Temporarily disabling on Pixel 3 and Pixel 3a XL due to driver crash\n", kSkipPrefix);
2660 return;
2661 }
2662
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002663 // overall set up:
2664 // subpass 0:
2665 // write image 0
2666 // subpass 1:
2667 // read image 0
2668 // write image 1
2669 // subpass 2:
2670 // read image 0
2671 // write image 2
2672 // subpass 3:
2673 // read image 0
2674 // write image 3
2675 //
2676 // subpasses 1 & 2 can run in parallel but both should depend on 0
2677 // subpass 3 must run after 1 & 2 because otherwise the store operation will
2678 // race with the reads in the other subpasses.
2679
2680 constexpr VkFormat kFormat = VK_FORMAT_R8G8B8A8_UNORM;
2681 constexpr uint32_t kWidth = 32, kHeight = 32;
2682 constexpr uint32_t kNumImages = 4;
2683
2684 VkImageCreateInfo src_img_info = {};
2685 src_img_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2686 src_img_info.pNext = NULL;
2687 src_img_info.flags = 0;
2688 src_img_info.imageType = VK_IMAGE_TYPE_2D;
2689 src_img_info.format = kFormat;
2690 src_img_info.extent = {kWidth, kHeight, 1};
2691 src_img_info.mipLevels = 1;
2692 src_img_info.arrayLayers = 1;
2693 src_img_info.samples = VK_SAMPLE_COUNT_2_BIT;
2694 src_img_info.tiling = VK_IMAGE_TILING_OPTIMAL;
2695 src_img_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
2696 src_img_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2697 src_img_info.queueFamilyIndexCount = 0;
2698 src_img_info.pQueueFamilyIndices = nullptr;
2699 src_img_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2700
2701 VkImageCreateInfo dst_img_info = {};
2702 dst_img_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2703 dst_img_info.pNext = nullptr;
2704 dst_img_info.flags = 0;
2705 dst_img_info.imageType = VK_IMAGE_TYPE_2D;
2706 dst_img_info.format = kFormat;
2707 dst_img_info.extent = {kWidth, kHeight, 1};
2708 dst_img_info.mipLevels = 1;
2709 dst_img_info.arrayLayers = 1;
2710 dst_img_info.samples = VK_SAMPLE_COUNT_1_BIT;
2711 dst_img_info.tiling = VK_IMAGE_TILING_OPTIMAL;
2712 dst_img_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
2713 dst_img_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2714 dst_img_info.queueFamilyIndexCount = 0;
2715 dst_img_info.pQueueFamilyIndices = nullptr;
2716 dst_img_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2717
2718 std::vector<std::unique_ptr<VkImageObj>> images;
2719 for (uint32_t i = 0; i < kNumImages; i++) {
2720 images.emplace_back(new VkImageObj(m_device));
2721 }
2722 images[0]->Init(src_img_info);
2723 for (uint32_t i = 1; i < images.size(); i++) {
2724 images[i]->Init(dst_img_info);
2725 }
2726
2727 std::array<VkImageView, kNumImages> attachments{};
2728 std::array<VkAttachmentDescription, kNumImages> attachment_descriptions{};
2729 std::array<VkAttachmentReference, kNumImages> color_refs{};
2730 std::array<VkImageMemoryBarrier, kNumImages> img_barriers{};
2731
2732 for (uint32_t i = 0; i < attachments.size(); i++) {
2733 attachments[i] = images[i]->targetView(kFormat);
2734 attachment_descriptions[i] = {};
2735 attachment_descriptions[i].flags = 0;
2736 attachment_descriptions[i].format = kFormat;
2737 attachment_descriptions[i].samples = VK_SAMPLE_COUNT_1_BIT;
2738 attachment_descriptions[i].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
2739 attachment_descriptions[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
2740 attachment_descriptions[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
2741 attachment_descriptions[i].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
2742 attachment_descriptions[i].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
2743 attachment_descriptions[i].finalLayout =
2744 (i == 0) ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
2745
2746 color_refs[i] = {i, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
2747
2748 img_barriers[i].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
2749 img_barriers[i].srcAccessMask = 0;
2750 img_barriers[i].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
2751 img_barriers[i].oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2752 img_barriers[i].newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
2753 img_barriers[i].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
2754 img_barriers[i].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
2755 img_barriers[i].image = images[i]->handle();
2756 img_barriers[i].subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS};
2757 }
2758
2759 const VkAttachmentReference input_ref{0u, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};
2760
2761 std::array<std::array<uint32_t, 2>, kNumImages - 1> preserve_subpass{{{2, 3}, {1, 3}, {1, 2}}};
2762
2763 std::array<VkSubpassDescription, kNumImages> subpasses{};
2764
2765 subpasses[0].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
2766 subpasses[0].inputAttachmentCount = 0;
2767 subpasses[0].pInputAttachments = nullptr;
2768 subpasses[0].colorAttachmentCount = 1;
2769 subpasses[0].pColorAttachments = &color_refs[0];
2770
2771 for (uint32_t i = 1; i < subpasses.size(); i++) {
2772 subpasses[i].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
2773 subpasses[i].inputAttachmentCount = 1;
2774 subpasses[i].pInputAttachments = &input_ref;
2775 subpasses[i].colorAttachmentCount = 1;
2776 subpasses[i].pColorAttachments = &color_refs[1];
2777 subpasses[i].preserveAttachmentCount = preserve_subpass[i - 1].size();
2778 subpasses[i].pPreserveAttachments = preserve_subpass[i - 1].data();
2779 }
2780
2781 VkRenderPassCreateInfo renderpass_info = {};
2782 renderpass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
2783 renderpass_info.pNext = nullptr;
2784 renderpass_info.flags = 0;
2785 renderpass_info.attachmentCount = attachment_descriptions.size();
2786 renderpass_info.pAttachments = attachment_descriptions.data();
2787 renderpass_info.subpassCount = subpasses.size();
2788 renderpass_info.pSubpasses = subpasses.data();
2789 renderpass_info.dependencyCount = 0;
2790 renderpass_info.pDependencies = nullptr;
2791
2792 VkFramebufferCreateInfo fbci = {};
2793 fbci.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
2794 fbci.pNext = nullptr;
2795 fbci.flags = 0;
2796 fbci.attachmentCount = attachments.size();
2797 fbci.pAttachments = attachments.data();
2798 fbci.width = kWidth;
2799 fbci.height = kHeight;
2800 fbci.layers = 1;
2801
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002802 vk_testing::Sampler sampler;
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002803 VkSamplerCreateInfo sampler_info = SafeSaneSamplerCreateInfo();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002804 sampler.init(*m_device, sampler_info);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002805
sfricke-samsung1c0b96a2021-07-08 22:24:09 -07002806 char const *fsSource = R"glsl(
2807 #version 450
2808 layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;
2809 void main() {
2810 vec4 color = subpassLoad(x);
2811 }
2812 )glsl";
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002813
2814 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
2815 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
2816
2817 VkClearValue clear = {};
2818 clear.color = m_clear_color;
Tony-LunarG73f37032021-06-07 11:47:03 -06002819 std::array<VkClearValue, 4> clear_values = {{clear, clear, clear, clear}};
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002820
2821 // run the renderpass with no dependencies
2822 {
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002823 vk_testing::RenderPass rp;
2824 vk_testing::Framebuffer fb;
2825 rp.init(*m_device, renderpass_info);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002826
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002827 fbci.renderPass = rp.handle();
2828 fb.init(*m_device, fbci);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002829
2830 CreatePipelineHelper g_pipe_0(*this);
2831 g_pipe_0.InitInfo();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002832 g_pipe_0.gp_ci_.renderPass = rp.handle();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002833 g_pipe_0.InitState();
2834 ASSERT_VK_SUCCESS(g_pipe_0.CreateGraphicsPipeline());
2835
2836 CreatePipelineHelper g_pipe_12(*this);
2837 g_pipe_12.InitInfo();
2838 g_pipe_12.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
2839 g_pipe_12.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002840 g_pipe_12.gp_ci_.renderPass = rp.handle();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002841 g_pipe_12.InitState();
2842 ASSERT_VK_SUCCESS(g_pipe_12.CreateGraphicsPipeline());
2843
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002844 g_pipe_12.descriptor_set_->WriteDescriptorImageInfo(0, attachments[0], sampler.handle(), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002845 g_pipe_12.descriptor_set_->UpdateDescriptorSets();
2846
2847 m_commandBuffer->begin();
2848
2849 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
2850 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0, nullptr, img_barriers.size(),
2851 img_barriers.data());
2852
2853 m_renderPassBeginInfo.renderArea = {{0, 0}, {16, 16}};
2854 m_renderPassBeginInfo.pClearValues = clear_values.data();
2855 m_renderPassBeginInfo.clearValueCount = clear_values.size();
2856
2857 m_renderPassBeginInfo.renderArea = {{0, 0}, {kWidth, kHeight}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002858 m_renderPassBeginInfo.renderPass = rp.handle();
2859 m_renderPassBeginInfo.framebuffer = fb.handle();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002860
2861 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
2862 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_);
2863 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_layout_.handle(), 0,
2864 1, &g_pipe_0.descriptor_set_->set_, 0, NULL);
2865
2866 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
2867
2868 for (uint32_t i = 1; i < subpasses.size(); i++) {
2869 vk::CmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
2870 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_12.pipeline_);
2871 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS,
2872 g_pipe_12.pipeline_layout_.handle(), 0, 1, &g_pipe_12.descriptor_set_->set_, 0, NULL);
2873
2874 // we're racing the writes from subpass 0 with our shader reads
2875 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ-RACING-WRITE");
2876 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
2877 m_errorMonitor->VerifyFound();
2878 }
2879
2880 // we should get an error from async checking in both subpasses 2 & 3
2881 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE-RACING-WRITE");
2882 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE-RACING-WRITE");
2883 vk::CmdEndRenderPass(m_commandBuffer->handle());
2884 m_errorMonitor->VerifyFound();
2885
2886 m_commandBuffer->end();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002887 }
2888
2889 // add dependencies from subpass 0 to the others, which are necessary but not sufficient
2890 std::vector<VkSubpassDependency> subpass_dependencies;
2891 for (uint32_t i = 1; i < subpasses.size(); i++) {
2892 VkSubpassDependency dep{0,
2893 i,
2894 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2895 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
2896 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2897 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
2898 0};
2899 subpass_dependencies.push_back(dep);
2900 }
2901 renderpass_info.dependencyCount = subpass_dependencies.size();
2902 renderpass_info.pDependencies = subpass_dependencies.data();
2903
2904 {
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002905 vk_testing::RenderPass rp;
2906 vk_testing::Framebuffer fb;
2907 rp.init(*m_device, renderpass_info);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002908
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002909 fbci.renderPass = rp.handle();
2910 fb.init(*m_device, fbci);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002911
2912 CreatePipelineHelper g_pipe_0(*this);
2913 g_pipe_0.InitInfo();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002914 g_pipe_0.gp_ci_.renderPass = rp.handle();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002915 g_pipe_0.InitState();
2916 ASSERT_VK_SUCCESS(g_pipe_0.CreateGraphicsPipeline());
2917
2918 CreatePipelineHelper g_pipe_12(*this);
2919 g_pipe_12.InitInfo();
2920 g_pipe_12.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
2921 g_pipe_12.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002922 g_pipe_12.gp_ci_.renderPass = rp.handle();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002923 g_pipe_12.InitState();
2924 ASSERT_VK_SUCCESS(g_pipe_12.CreateGraphicsPipeline());
2925
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002926 g_pipe_12.descriptor_set_->WriteDescriptorImageInfo(0, attachments[0], sampler.handle(), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002927 g_pipe_12.descriptor_set_->UpdateDescriptorSets();
2928
2929 m_commandBuffer->begin();
2930
2931 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
2932 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0, nullptr, img_barriers.size(),
2933 img_barriers.data());
2934
2935 m_renderPassBeginInfo.renderArea = {{0, 0}, {16, 16}};
2936 m_renderPassBeginInfo.pClearValues = clear_values.data();
2937 m_renderPassBeginInfo.clearValueCount = clear_values.size();
2938
2939 m_renderPassBeginInfo.renderArea = {{0, 0}, {kWidth, kHeight}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002940 m_renderPassBeginInfo.renderPass = rp.handle();
2941 m_renderPassBeginInfo.framebuffer = fb.handle();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002942
2943 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
2944 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_);
2945 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_layout_.handle(), 0,
2946 1, &g_pipe_0.descriptor_set_->set_, 0, NULL);
2947
2948 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
2949
2950 m_errorMonitor->ExpectSuccess();
2951 for (uint32_t i = 1; i < subpasses.size(); i++) {
2952 vk::CmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
2953 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_12.pipeline_);
2954 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS,
2955 g_pipe_12.pipeline_layout_.handle(), 0, 1, &g_pipe_12.descriptor_set_->set_, 0, NULL);
2956 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
2957 }
2958 m_errorMonitor->VerifyNotFound();
2959 // expect this error because 2 subpasses could try to do the store operation
2960 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE-RACING-WRITE");
2961 // ... and this one because the store could happen during a shader read from another subpass
2962 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE-RACING-READ");
2963 vk::CmdEndRenderPass(m_commandBuffer->handle());
2964 m_errorMonitor->VerifyFound();
2965
2966 m_commandBuffer->end();
2967
2968 m_errorMonitor->VerifyFound();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002969 }
2970
2971 // try again with correct dependencies to make subpass 3 depend on 1 & 2
2972 for (uint32_t i = 1; i < (subpasses.size() - 1); i++) {
2973 VkSubpassDependency dep{i,
2974 static_cast<uint32_t>(subpasses.size() - 1),
2975 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2976 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
2977 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2978 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
2979 0};
2980 subpass_dependencies.push_back(dep);
2981 }
2982 renderpass_info.dependencyCount = subpass_dependencies.size();
2983 renderpass_info.pDependencies = subpass_dependencies.data();
2984 {
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002985 vk_testing::RenderPass rp;
2986 vk_testing::Framebuffer fb;
2987 rp.init(*m_device, renderpass_info);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002988
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002989 fbci.renderPass = rp.handle();
2990 fb.init(*m_device, fbci);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002991
2992 CreatePipelineHelper g_pipe_0(*this);
2993 g_pipe_0.InitInfo();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002994 g_pipe_0.gp_ci_.renderPass = rp.handle();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002995 g_pipe_0.InitState();
2996 ASSERT_VK_SUCCESS(g_pipe_0.CreateGraphicsPipeline());
2997
2998 CreatePipelineHelper g_pipe_12(*this);
2999 g_pipe_12.InitInfo();
3000 g_pipe_12.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
3001 g_pipe_12.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06003002 g_pipe_12.gp_ci_.renderPass = rp.handle();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003003 g_pipe_12.InitState();
3004 ASSERT_VK_SUCCESS(g_pipe_12.CreateGraphicsPipeline());
3005
Jeremy Gebben18ac1052021-08-12 11:07:32 -06003006 g_pipe_12.descriptor_set_->WriteDescriptorImageInfo(0, attachments[0], sampler.handle(), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003007 g_pipe_12.descriptor_set_->UpdateDescriptorSets();
3008
3009 m_errorMonitor->ExpectSuccess();
3010 m_commandBuffer->begin();
3011 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
3012 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0, nullptr, img_barriers.size(),
3013 img_barriers.data());
3014
3015 m_renderPassBeginInfo.renderArea = {{0, 0}, {16, 16}};
3016 m_renderPassBeginInfo.pClearValues = clear_values.data();
3017 m_renderPassBeginInfo.clearValueCount = clear_values.size();
3018
3019 m_renderPassBeginInfo.renderArea = {{0, 0}, {kWidth, kHeight}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06003020 m_renderPassBeginInfo.renderPass = rp.handle();
3021 m_renderPassBeginInfo.framebuffer = fb.handle();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003022
3023 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
3024 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_);
3025 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_layout_.handle(), 0,
3026 1, &g_pipe_0.descriptor_set_->set_, 0, NULL);
3027
3028 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
3029
3030 for (uint32_t i = 1; i < subpasses.size(); i++) {
3031 vk::CmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
3032 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_12.pipeline_);
3033 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS,
3034 g_pipe_12.pipeline_layout_.handle(), 0, 1, &g_pipe_12.descriptor_set_->set_, 0, NULL);
3035 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
3036 }
3037
3038 vk::CmdEndRenderPass(m_commandBuffer->handle());
3039
3040 m_commandBuffer->end();
3041
3042 m_errorMonitor->VerifyNotFound();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003043 }
3044}
John Zulauf025ee442020-12-15 11:44:19 -07003045
3046TEST_F(VkSyncValTest, SyncEventsBufferCopy) {
3047 TEST_DESCRIPTION("Check Set/Wait protection for a variety of use cases using buffer copies");
3048 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
3049 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
3050
3051 VkBufferObj buffer_a;
3052 VkBufferObj buffer_b;
3053 VkBufferObj buffer_c;
3054 VkMemoryPropertyFlags mem_prop = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
3055 buffer_a.init_as_src_and_dst(*m_device, 256, mem_prop);
3056 buffer_b.init_as_src_and_dst(*m_device, 256, mem_prop);
3057 buffer_c.init_as_src_and_dst(*m_device, 256, mem_prop);
3058
3059 VkBufferCopy region = {0, 0, 256};
3060 VkBufferCopy front2front = {0, 0, 128};
3061 VkBufferCopy front2back = {0, 128, 128};
3062 VkBufferCopy back2back = {128, 128, 128};
3063
3064 VkEventObj event;
3065 event.init(*m_device, VkEventObj::create_info(0));
3066 VkEvent event_handle = event.handle();
3067
3068 auto cb = m_commandBuffer->handle();
3069 m_commandBuffer->begin();
3070
3071 // Copy after set for WAR (note we are writing to the back half of c but only reading from the front
3072 m_errorMonitor->ExpectSuccess();
3073 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &region);
3074 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3075 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_c.handle(), 1, &back2back);
3076 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3077 nullptr, 0, nullptr);
3078 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &front2front);
3079 m_errorMonitor->VerifyNotFound();
3080 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
3081 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &front2back);
3082 m_errorMonitor->VerifyFound();
3083 m_commandBuffer->end();
3084
3085 // WAR prevented
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);
3091 // Just protect against WAR, only need a sync barrier.
3092 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3093 nullptr, 0, nullptr);
3094 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &region);
3095 m_errorMonitor->VerifyNotFound();
3096
3097 // Wait shouldn't prevent this WAW though, as it's only a synchronization barrier
3098 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
3099 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_b.handle(), 1, &region);
3100 m_errorMonitor->VerifyFound();
3101 m_commandBuffer->end();
3102
3103 // Prevent WAR and WAW
3104 m_commandBuffer->reset();
3105 m_commandBuffer->begin();
3106 m_errorMonitor->ExpectSuccess();
3107 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &region);
3108 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07003109 auto mem_barrier_waw = LvlInitStruct<VkMemoryBarrier>();
John Zulauf025ee442020-12-15 11:44:19 -07003110 mem_barrier_waw.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3111 mem_barrier_waw.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3112 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 1,
3113 &mem_barrier_waw, 0, nullptr, 0, nullptr);
3114 // The WAW should be safe (on a memory barrier)
3115 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_b.handle(), 1, &region);
3116 // The WAR should also be safe (on a sync barrier)
3117 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &region);
3118 m_errorMonitor->VerifyNotFound();
3119 m_commandBuffer->end();
3120
3121 // Barrier range check for WAW
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07003122 auto buffer_barrier_front_waw = LvlInitStruct<VkBufferMemoryBarrier>();
John Zulauf025ee442020-12-15 11:44:19 -07003123 buffer_barrier_front_waw.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3124 buffer_barrier_front_waw.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3125 buffer_barrier_front_waw.buffer = buffer_b.handle();
3126 buffer_barrier_front_waw.offset = front2front.dstOffset;
3127 buffer_barrier_front_waw.size = front2front.size;
3128
3129 // Front safe, back WAW
3130 m_commandBuffer->reset();
3131 m_commandBuffer->begin();
3132 m_errorMonitor->ExpectSuccess();
3133 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &region);
3134 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3135 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 1,
3136 &buffer_barrier_front_waw, 0, nullptr);
3137 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &front2front);
3138 m_errorMonitor->VerifyNotFound();
3139 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
3140 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &back2back);
3141 m_errorMonitor->VerifyFound();
3142 m_commandBuffer->end();
3143}
3144
3145TEST_F(VkSyncValTest, SyncEventsCopyImageHazards) {
3146 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
3147 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
3148
3149 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3150 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
3151 VkImageObj image_a(m_device);
3152 auto image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 2, format, usage, VK_IMAGE_TILING_OPTIMAL);
3153 image_a.Init(image_ci);
3154 ASSERT_TRUE(image_a.initialized());
3155
3156 VkImageObj image_b(m_device);
3157 image_b.Init(image_ci);
3158 ASSERT_TRUE(image_b.initialized());
3159
3160 VkImageObj image_c(m_device);
3161 image_c.Init(image_ci);
3162 ASSERT_TRUE(image_c.initialized());
3163
3164 VkEventObj event;
3165 event.init(*m_device, VkEventObj::create_info(0));
3166 VkEvent event_handle = event.handle();
3167
3168 VkImageSubresourceLayers layers_all{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 2};
3169 VkImageSubresourceLayers layers_0{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
3170 VkImageSubresourceLayers layers_1{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1};
3171 VkImageSubresourceRange layers_0_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
3172 VkOffset3D zero_offset{0, 0, 0};
3173 VkOffset3D half_offset{64, 64, 0};
3174 VkExtent3D full_extent{128, 128, 1}; // <-- image type is 2D
3175 VkExtent3D half_extent{64, 64, 1}; // <-- image type is 2D
3176
3177 VkImageCopy full_region = {layers_all, zero_offset, layers_all, zero_offset, full_extent};
3178 VkImageCopy region_0_to_0 = {layers_0, zero_offset, layers_0, zero_offset, full_extent};
3179 VkImageCopy region_1_to_1 = {layers_1, zero_offset, layers_1, zero_offset, full_extent};
3180 VkImageCopy region_0_q0toq0 = {layers_0, zero_offset, layers_0, zero_offset, half_extent};
3181 VkImageCopy region_0_q0toq3 = {layers_0, zero_offset, layers_0, half_offset, half_extent};
3182 VkImageCopy region_0_q3toq3 = {layers_0, half_offset, layers_0, half_offset, half_extent};
3183
3184 auto cb = m_commandBuffer->handle();
3185 auto copy_general = [cb](const VkImageObj &from, const VkImageObj &to, const VkImageCopy &region) {
3186 vk::CmdCopyImage(cb, from.handle(), VK_IMAGE_LAYOUT_GENERAL, to.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
3187 };
3188
3189 auto set_layouts = [this, &image_a, &image_b, &image_c]() {
3190 image_c.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
3191 image_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
3192 image_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
3193 };
3194
John Zulaufdd462092020-12-18 12:00:35 -07003195 // Scope check. One access in, one access not
John Zulauf025ee442020-12-15 11:44:19 -07003196 m_commandBuffer->begin();
3197 set_layouts();
3198 m_errorMonitor->ExpectSuccess();
3199 copy_general(image_a, image_b, full_region);
3200 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3201 copy_general(image_a, image_c, region_0_q3toq3);
3202 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3203 nullptr, 0, nullptr);
3204 copy_general(image_c, image_a, region_0_q0toq0);
3205 m_errorMonitor->VerifyNotFound();
3206 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
3207 copy_general(image_c, image_a, region_0_q0toq3);
3208 m_errorMonitor->VerifyFound();
3209 m_commandBuffer->end();
3210
3211 // WAR prevented
3212 m_commandBuffer->reset();
3213 m_commandBuffer->begin();
3214 set_layouts();
3215 m_errorMonitor->ExpectSuccess();
3216 copy_general(image_a, image_b, full_region);
3217 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3218 // Just protect against WAR, only need a sync barrier.
3219 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3220 nullptr, 0, nullptr);
3221 copy_general(image_c, image_a, full_region);
3222 m_errorMonitor->VerifyNotFound();
3223
3224 // Wait shouldn't prevent this WAW though, as it's only a synchronization barrier
3225 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
3226 copy_general(image_c, image_b, full_region);
3227 m_errorMonitor->VerifyFound();
3228 m_commandBuffer->end();
3229
3230 // Prevent WAR and WAW
3231 m_commandBuffer->reset();
3232 m_commandBuffer->begin();
3233 m_errorMonitor->ExpectSuccess();
3234 set_layouts();
3235 copy_general(image_a, image_b, full_region);
3236 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07003237 auto mem_barrier_waw = LvlInitStruct<VkMemoryBarrier>();
John Zulauf025ee442020-12-15 11:44:19 -07003238 mem_barrier_waw.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3239 mem_barrier_waw.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3240 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 1,
3241 &mem_barrier_waw, 0, nullptr, 0, nullptr);
3242 // The WAW should be safe (on a memory barrier)
3243 copy_general(image_c, image_b, full_region);
3244 // The WAR should also be safe (on a sync barrier)
3245 copy_general(image_c, image_a, full_region);
3246 m_errorMonitor->VerifyNotFound();
3247 m_commandBuffer->end();
3248
3249 // Barrier range check for WAW
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07003250 auto image_barrier_region0_waw = LvlInitStruct<VkImageMemoryBarrier>();
John Zulauf025ee442020-12-15 11:44:19 -07003251 image_barrier_region0_waw.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3252 image_barrier_region0_waw.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3253 image_barrier_region0_waw.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
3254 image_barrier_region0_waw.newLayout = VK_IMAGE_LAYOUT_GENERAL;
3255 image_barrier_region0_waw.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
3256 image_barrier_region0_waw.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
3257 image_barrier_region0_waw.image = image_b.handle();
3258 image_barrier_region0_waw.subresourceRange = layers_0_subresource_range;
3259
3260 // Region 0 safe, back WAW
3261 m_commandBuffer->reset();
3262 m_commandBuffer->begin();
3263 set_layouts();
3264 m_errorMonitor->ExpectSuccess();
3265 copy_general(image_a, image_b, full_region);
3266 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3267 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3268 nullptr, 1, &image_barrier_region0_waw);
3269 copy_general(image_a, image_b, region_0_to_0);
3270 m_errorMonitor->VerifyNotFound();
3271 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
3272 copy_general(image_a, image_b, region_1_to_1);
3273 m_errorMonitor->VerifyFound();
3274 m_commandBuffer->end();
3275}
John Zulauf4b5e4632020-12-15 11:48:59 -07003276
3277TEST_F(VkSyncValTest, SyncEventsCommandHazards) {
3278 TEST_DESCRIPTION("Check Set/Reset/Wait command hazard checking");
3279 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
3280 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
3281
3282 VkEventObj event;
3283 event.init(*m_device, VkEventObj::create_info(0));
3284
3285 const VkEvent event_handle = event.handle();
3286
3287 m_commandBuffer->begin();
3288 m_errorMonitor->ExpectSuccess();
3289 m_commandBuffer->ResetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3290 m_errorMonitor->VerifyNotFound();
3291
John Zulauf4edde622021-02-15 08:54:50 -07003292 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdResetEvent-event-03834");
John Zulauf4b5e4632020-12-15 11:48:59 -07003293 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdWaitEvents-srcStageMask-01158");
3294 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3295 nullptr, 0, nullptr);
3296 m_errorMonitor->VerifyFound();
3297 m_errorMonitor->ExpectSuccess();
3298 m_commandBuffer->end();
3299
3300 m_commandBuffer->begin();
3301 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3302 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, nullptr,
3303 0, nullptr, 0, nullptr);
3304 m_errorMonitor->VerifyNotFound();
3305 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-vkCmdResetEvent-missingbarrier-wait");
3306 m_commandBuffer->ResetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3307 m_errorMonitor->VerifyFound();
3308 m_errorMonitor->ExpectSuccess();
3309 m_commandBuffer->end();
3310
3311 m_commandBuffer->begin();
3312 m_commandBuffer->ResetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3313 m_errorMonitor->VerifyNotFound();
3314 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-vkCmdSetEvent-missingbarrier-reset");
3315 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3316 m_errorMonitor->VerifyFound();
3317
3318 m_errorMonitor->ExpectSuccess();
3319 m_commandBuffer->PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0U, 0, nullptr, 0,
3320 nullptr, 0, nullptr);
3321 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3322 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3323 nullptr, 0, nullptr);
3324 m_commandBuffer->ResetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3325 m_commandBuffer->PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0U, 0, nullptr, 0,
3326 nullptr, 0, nullptr);
3327 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3328 m_errorMonitor->VerifyNotFound();
3329
3330 // Need a barrier between set and a reset
3331 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-vkCmdResetEvent-missingbarrier-set");
3332 m_commandBuffer->ResetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3333 m_errorMonitor->VerifyFound();
3334 m_errorMonitor->ExpectSuccess();
3335 m_commandBuffer->end();
3336
3337 m_commandBuffer->begin();
3338 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3339 m_errorMonitor->VerifyNotFound();
3340 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-vkCmdSetEvent-missingbarrier-set");
3341 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3342 m_errorMonitor->VerifyFound();
3343
3344 m_commandBuffer->end();
3345}
ziga-lunarg3a16ff12021-07-30 12:09:55 +02003346
3347TEST_F(VkLayerTest, CmdWaitEvents2KHRUsedButSynchronizaion2Disabled) {
3348 TEST_DESCRIPTION("Using CmdWaitEvents2KHR when synchronization2 is not enabled");
3349
3350 ASSERT_NO_FATAL_FAILURE(InitFramework());
3351 if (!DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME)) {
3352 printf("%s Synchronization2 not supported, skipping test\n", kSkipPrefix);
3353 return;
3354 }
3355 if (!DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
3356 printf("%s %s not supported, skipping test\n", kSkipPrefix, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
3357 return;
3358 }
3359 m_device_extension_names.push_back(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME);
3360 m_device_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
3361 InitState();
3362
3363 auto fpCmdWaitEvents2KHR = (PFN_vkCmdWaitEvents2KHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdWaitEvents2KHR");
3364
3365 VkEventObj event;
3366 event.init(*m_device, VkEventObj::create_info(0));
3367 VkEvent event_handle = event.handle();
3368
3369 VkDependencyInfoKHR dependency_info = LvlInitStruct<VkDependencyInfoKHR>();
3370
3371 m_commandBuffer->begin();
3372 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdWaitEvents2KHR-synchronization2-03836");
3373 fpCmdWaitEvents2KHR(m_commandBuffer->handle(), 1, &event_handle, &dependency_info);
3374 m_errorMonitor->VerifyFound();
3375 m_commandBuffer->end();
3376}