blob: 6d8cb9343b6931006826d656ffb0b372e88be551 [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());
Mike Schuchardt7cc57842021-09-15 10:49:59 -0700558 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE_1_EXTENSION_NAME);
Jeremy Gebben170781d2020-11-19 16:21:21 -0700559 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) {
Mike Schuchardt7cc57842021-09-15 10:49:59 -0700563 m_device_extension_names.push_back(VK_KHR_MAINTENANCE_1_EXTENSION_NAME);
Jeremy Gebben170781d2020-11-19 16:21:21 -0700564 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());
Mike Schuchardt7cc57842021-09-15 10:49:59 -0700777 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE_1_EXTENSION_NAME);
Jeremy Gebben170781d2020-11-19 16:21:21 -0700778 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) {
Mike Schuchardt7cc57842021-09-15 10:49:59 -0700782 m_device_extension_names.push_back(VK_KHR_MAINTENANCE_1_EXTENSION_NAME);
Jeremy Gebben170781d2020-11-19 16:21:21 -0700783 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());
John Zulaufbb373682021-10-05 17:21:40 -06001107 const VkSubpassDependency external_subpass_dependency = {VK_SUBPASS_EXTERNAL,
1108 0,
1109 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
1110 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
1111 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1112 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1113 VK_DEPENDENCY_BY_REGION_BIT};
1114 m_additionalSubpassDependencies.push_back(external_subpass_dependency);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001115 ASSERT_NO_FATAL_FAILURE(InitRenderTarget(2));
1116
1117 // Render Target Information
1118 auto width = static_cast<uint32_t>(m_width);
1119 auto height = static_cast<uint32_t>(m_height);
1120 auto *rt_0 = m_renderTargets[0].get();
1121 auto *rt_1 = m_renderTargets[1].get();
1122
1123 // Other buffers with which to interact
1124 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1125 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
1126 VkImageObj image_a(m_device), image_b(m_device);
1127 const auto image_ci = VkImageObj::ImageCreateInfo2D(width, height, 1, 1, format, usage, VK_IMAGE_TILING_OPTIMAL);
1128 image_a.Init(image_ci);
1129 image_b.Init(image_ci);
1130
1131 VkOffset3D zero_offset{0, 0, 0};
1132 VkExtent3D full_extent{width, height, 1}; // <-- image type is 2D
1133 VkImageSubresourceLayers layer_color{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
1134 VkImageCopy region_to_copy = {layer_color, zero_offset, layer_color, zero_offset, full_extent};
1135
1136 auto cb = m_commandBuffer->handle();
1137
1138 m_errorMonitor->ExpectSuccess();
1139 m_commandBuffer->begin();
1140 image_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1141 image_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1142 rt_0->SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1143 rt_1->SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1144
1145 rt_0->SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1146 vk::CmdCopyImage(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, rt_0->handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_to_copy);
1147 m_errorMonitor->VerifyNotFound();
1148
1149 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1150 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); // This fails so the driver call is skip and no end is valid
1151 m_errorMonitor->VerifyFound();
1152
1153 m_errorMonitor->ExpectSuccess();
1154 // Use the barrier to clean up the WAW, and try again. (and show that validation is accounting for the barrier effect too.)
1155 VkImageSubresourceRange rt_full_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07001156 auto image_barrier = LvlInitStruct<VkImageMemoryBarrier>();
Jeremy Gebben170781d2020-11-19 16:21:21 -07001157 image_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
John Zulaufbb373682021-10-05 17:21:40 -06001158 image_barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
Jeremy Gebben170781d2020-11-19 16:21:21 -07001159 image_barrier.image = rt_0->handle();
1160 image_barrier.subresourceRange = rt_full_subresource_range;
1161 image_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
1162 image_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
John Zulaufbb373682021-10-05 17:21:40 -06001163 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0,
1164 nullptr, 1, &image_barrier);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001165 vk::CmdCopyImage(cb, rt_1->handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region_to_copy);
1166 m_errorMonitor->VerifyNotFound();
1167
1168 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1169 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); // This fails so the driver call is skip and no end is valid
1170 m_errorMonitor->VerifyFound();
1171
1172 m_errorMonitor->ExpectSuccess();
1173 // A global execution barrier that the implict external dependency can chain with should work...
1174 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, 0,
1175 nullptr);
1176
1177 // With the barrier above, the layout transition has a chained execution sync operation, and the default
1178 // implict VkSubpassDependency safes the load op clear vs. the layout transition...
1179 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1180 m_commandBuffer->EndRenderPass();
1181 m_errorMonitor->VerifyNotFound();
1182}
1183
1184TEST_F(VkSyncValTest, SyncCmdDispatchDrawHazards) {
1185 // TODO: Add code to enable sync validation
1186 SetTargetApiVersion(VK_API_VERSION_1_2);
1187
1188 // Enable VK_KHR_draw_indirect_count for KHR variants
1189 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
1190 VkPhysicalDeviceVulkan12Features features12 = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, nullptr};
1191 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME)) {
1192 m_device_extension_names.push_back(VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME);
1193 if (DeviceValidationVersion() >= VK_API_VERSION_1_2) {
1194 features12.drawIndirectCount = VK_TRUE;
1195 }
1196 }
1197 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features12, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
1198 bool has_khr_indirect = DeviceExtensionEnabled(VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME);
1199 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1200
1201 VkImageUsageFlags image_usage_combine = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
1202 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1203 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
1204 VkImageObj image_c_a(m_device), image_c_b(m_device);
1205 const auto image_c_ci = VkImageObj::ImageCreateInfo2D(16, 16, 1, 1, format, image_usage_combine, VK_IMAGE_TILING_OPTIMAL);
1206 image_c_a.Init(image_c_ci);
1207 image_c_b.Init(image_c_ci);
1208
1209 VkImageView imageview_c = image_c_a.targetView(format);
1210 VkImageUsageFlags image_usage_storage =
1211 VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1212 VkImageObj image_s_a(m_device), image_s_b(m_device);
1213 const auto image_s_ci = VkImageObj::ImageCreateInfo2D(16, 16, 1, 1, format, image_usage_storage, VK_IMAGE_TILING_OPTIMAL);
1214 image_s_a.Init(image_s_ci);
1215 image_s_b.Init(image_s_ci);
1216 image_s_a.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1217 image_s_b.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1218
1219 VkImageView imageview_s = image_s_a.targetView(format);
1220
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001221 vk_testing::Sampler sampler_s, sampler_c;
Jeremy Gebben170781d2020-11-19 16:21:21 -07001222 VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001223 sampler_s.init(*m_device, sampler_ci);
1224 sampler_c.init(*m_device, sampler_ci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001225
1226 VkBufferObj buffer_a, buffer_b;
1227 VkMemoryPropertyFlags mem_prop = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
1228 VkBufferUsageFlags buffer_usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT |
1229 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1230 buffer_a.init(*m_device, buffer_a.create_info(2048, buffer_usage, nullptr), mem_prop);
1231 buffer_b.init(*m_device, buffer_b.create_info(2048, buffer_usage, nullptr), mem_prop);
1232
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001233 vk_testing::BufferView bufferview;
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07001234 auto bvci = LvlInitStruct<VkBufferViewCreateInfo>();
Jeremy Gebben170781d2020-11-19 16:21:21 -07001235 bvci.buffer = buffer_a.handle();
1236 bvci.format = VK_FORMAT_R32_SFLOAT;
1237 bvci.offset = 0;
1238 bvci.range = VK_WHOLE_SIZE;
1239
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001240 bufferview.init(*m_device, bvci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001241
1242 OneOffDescriptorSet descriptor_set(m_device,
1243 {
1244 {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
1245 {1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr},
1246 {2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_ALL, nullptr},
1247 {3, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
1248 });
1249
sfricke-samsung36428462021-02-10 01:23:34 -08001250 descriptor_set.WriteDescriptorBufferInfo(0, buffer_a.handle(), 0, 2048);
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001251 descriptor_set.WriteDescriptorImageInfo(1, imageview_c, sampler_c.handle(), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
Jeremy Gebben170781d2020-11-19 16:21:21 -07001252 VK_IMAGE_LAYOUT_GENERAL);
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001253 descriptor_set.WriteDescriptorImageInfo(2, imageview_s, sampler_s.handle(), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_IMAGE_LAYOUT_GENERAL);
1254 descriptor_set.WriteDescriptorBufferView(3, bufferview.handle());
Jeremy Gebben170781d2020-11-19 16:21:21 -07001255 descriptor_set.UpdateDescriptorSets();
1256
1257 // Dispatch
sfricke-samsung1c0b96a2021-07-08 22:24:09 -07001258 std::string csSource = R"glsl(
1259 #version 450
1260 layout(set=0, binding=0) uniform foo { float x; } ub0;
1261 layout(set=0, binding=1) uniform sampler2D cis1;
1262 layout(set=0, binding=2, rgba8) uniform readonly image2D si2;
1263 layout(set=0, binding=3, r32f) uniform readonly imageBuffer stb3;
1264 void main(){
1265 vec4 vColor4;
1266 vColor4.x = ub0.x;
1267 vColor4 = texture(cis1, vec2(0));
1268 vColor4 = imageLoad(si2, ivec2(0));
1269 vColor4 = imageLoad(stb3, 0);
1270 }
1271 )glsl";
Jeremy Gebben170781d2020-11-19 16:21:21 -07001272
John Zulaufbe8562b2020-12-15 14:21:01 -07001273 VkEventObj event;
1274 event.init(*m_device, VkEventObj::create_info(0));
1275 VkEvent event_handle = event.handle();
1276
Jeremy Gebben170781d2020-11-19 16:21:21 -07001277 CreateComputePipelineHelper pipe(*this);
1278 pipe.InitInfo();
1279 pipe.cs_.reset(new VkShaderObj(m_device, csSource.c_str(), VK_SHADER_STAGE_COMPUTE_BIT, this));
1280 pipe.InitState();
1281 pipe.pipeline_layout_ = VkPipelineLayoutObj(m_device, {&descriptor_set.layout_});
1282 pipe.CreateComputePipeline();
1283
1284 m_commandBuffer->begin();
1285
1286 VkBufferCopy buffer_region = {0, 0, 2048};
1287 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_b.handle(), buffer_a.handle(), 1, &buffer_region);
1288
1289 VkImageSubresourceLayers layer{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
1290 VkOffset3D zero_offset{0, 0, 0};
1291 VkExtent3D full_extent{16, 16, 1};
1292 VkImageCopy image_region = {layer, zero_offset, layer, zero_offset, full_extent};
1293 vk::CmdCopyImage(m_commandBuffer->handle(), image_c_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_c_a.handle(),
1294 VK_IMAGE_LAYOUT_GENERAL, 1, &image_region);
1295 vk::CmdCopyImage(m_commandBuffer->handle(), image_s_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_s_a.handle(),
1296 VK_IMAGE_LAYOUT_GENERAL, 1, &image_region);
1297
1298 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_);
1299 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_layout_.handle(), 0, 1,
1300 &descriptor_set.set_, 0, nullptr);
1301
1302 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1303 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1304 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1305 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1306 vk::CmdDispatch(m_commandBuffer->handle(), 1, 1, 1);
1307 m_errorMonitor->VerifyFound();
1308
1309 m_commandBuffer->end();
1310 m_commandBuffer->reset();
1311 m_commandBuffer->begin();
1312
1313 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_);
1314 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_layout_.handle(), 0, 1,
1315 &descriptor_set.set_, 0, nullptr);
1316 vk::CmdDispatch(m_commandBuffer->handle(), 1, 1, 1);
1317
1318 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1319 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_b.handle(), buffer_a.handle(), 1, &buffer_region);
1320 m_errorMonitor->VerifyFound();
1321
1322 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1323 vk::CmdCopyImage(m_commandBuffer->handle(), image_c_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_c_a.handle(),
1324 VK_IMAGE_LAYOUT_GENERAL, 1, &image_region);
1325 m_errorMonitor->VerifyFound();
1326
1327 m_commandBuffer->end();
1328 m_commandBuffer->reset();
1329
1330 // DispatchIndirect
1331 m_errorMonitor->ExpectSuccess();
1332 VkBufferObj buffer_dispatchIndirect, buffer_dispatchIndirect2;
1333 buffer_usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1334 buffer_dispatchIndirect.init(
1335 *m_device, buffer_dispatchIndirect.create_info(sizeof(VkDispatchIndirectCommand), buffer_usage, nullptr), mem_prop);
1336 buffer_dispatchIndirect2.init(
1337 *m_device, buffer_dispatchIndirect2.create_info(sizeof(VkDispatchIndirectCommand), buffer_usage, nullptr), mem_prop);
1338 m_commandBuffer->begin();
1339 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_);
1340 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_layout_.handle(), 0, 1,
1341 &descriptor_set.set_, 0, nullptr);
1342 vk::CmdDispatchIndirect(m_commandBuffer->handle(), buffer_dispatchIndirect.handle(), 0);
1343 m_commandBuffer->end();
1344 m_errorMonitor->VerifyNotFound();
1345
1346 m_commandBuffer->reset();
1347 m_commandBuffer->begin();
1348
1349 buffer_region = {0, 0, sizeof(VkDispatchIndirectCommand)};
1350 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_dispatchIndirect2.handle(), buffer_dispatchIndirect.handle(), 1,
1351 &buffer_region);
1352 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_);
1353 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_layout_.handle(), 0, 1,
1354 &descriptor_set.set_, 0, nullptr);
1355 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1356 vk::CmdDispatchIndirect(m_commandBuffer->handle(), buffer_dispatchIndirect.handle(), 0);
1357 m_errorMonitor->VerifyFound();
1358 m_commandBuffer->end();
1359
1360 // Draw
1361 m_errorMonitor->ExpectSuccess();
1362 const float vbo_data[3] = {1.f, 0.f, 1.f};
1363 VkVertexInputAttributeDescription VertexInputAttributeDescription = {0, 0, VK_FORMAT_R32G32B32_SFLOAT, sizeof(vbo_data)};
1364 VkVertexInputBindingDescription VertexInputBindingDescription = {0, sizeof(vbo_data), VK_VERTEX_INPUT_RATE_VERTEX};
1365 VkBufferObj vbo, vbo2;
1366 buffer_usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1367 vbo.init(*m_device, vbo.create_info(sizeof(vbo_data), buffer_usage, nullptr), mem_prop);
1368 vbo2.init(*m_device, vbo2.create_info(sizeof(vbo_data), buffer_usage, nullptr), mem_prop);
1369
1370 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
1371 VkShaderObj fs(m_device, csSource.c_str(), VK_SHADER_STAGE_FRAGMENT_BIT, this);
1372
1373 CreatePipelineHelper g_pipe(*this);
1374 g_pipe.InitInfo();
1375 g_pipe.InitState();
1376 g_pipe.vi_ci_.pVertexBindingDescriptions = &VertexInputBindingDescription;
1377 g_pipe.vi_ci_.vertexBindingDescriptionCount = 1;
1378 g_pipe.vi_ci_.pVertexAttributeDescriptions = &VertexInputAttributeDescription;
1379 g_pipe.vi_ci_.vertexAttributeDescriptionCount = 1;
1380 g_pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
1381 g_pipe.pipeline_layout_ = VkPipelineLayoutObj(m_device, {&descriptor_set.layout_});
1382 ASSERT_VK_SUCCESS(g_pipe.CreateGraphicsPipeline());
1383
1384 m_commandBuffer->reset();
1385 m_commandBuffer->begin();
1386 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1387 VkDeviceSize offset = 0;
1388 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1389
1390 VkViewport viewport = {0, 0, 16, 16, 0, 1};
1391 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1392 VkRect2D scissor = {{0, 0}, {16, 16}};
1393 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1394
1395 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1396 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1397 &descriptor_set.set_, 0, nullptr);
1398 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1399 m_commandBuffer->EndRenderPass();
1400 m_commandBuffer->end();
1401 m_errorMonitor->VerifyNotFound();
1402
1403 m_commandBuffer->reset();
1404 m_commandBuffer->begin();
1405
1406 buffer_region = {0, 0, sizeof(vbo_data)};
1407 vk::CmdCopyBuffer(m_commandBuffer->handle(), vbo2.handle(), vbo.handle(), 1, &buffer_region);
1408
1409 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1410 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1411 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1412 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1413 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1414 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1415 &descriptor_set.set_, 0, nullptr);
1416
1417 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1418 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1419 m_errorMonitor->VerifyFound();
1420
1421 m_commandBuffer->EndRenderPass();
1422 m_commandBuffer->end();
1423
John Zulaufbe8562b2020-12-15 14:21:01 -07001424 // Repeat the draw test with a WaitEvent to protect it.
1425 m_errorMonitor->ExpectSuccess();
1426 m_commandBuffer->reset();
1427 m_commandBuffer->begin();
1428
1429 vk::CmdCopyBuffer(m_commandBuffer->handle(), vbo2.handle(), vbo.handle(), 1, &buffer_region);
1430
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07001431 auto vbo_barrier = LvlInitStruct<VkBufferMemoryBarrier>();
John Zulaufbe8562b2020-12-15 14:21:01 -07001432 vbo_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1433 vbo_barrier.dstAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
1434 vbo_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1435 vbo_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1436 vbo_barrier.buffer = vbo.handle();
1437 vbo_barrier.offset = buffer_region.dstOffset;
1438 vbo_barrier.size = buffer_region.size;
1439
1440 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
1441
1442 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1443 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1444 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1445 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1446 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1447 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1448 &descriptor_set.set_, 0, nullptr);
1449
1450 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0, nullptr, 1,
1451 &vbo_barrier, 0, nullptr);
1452 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1453
1454 m_commandBuffer->EndRenderPass();
1455 m_commandBuffer->end();
1456 m_errorMonitor->VerifyNotFound();
1457
Jeremy Gebben170781d2020-11-19 16:21:21 -07001458 // DrawIndexed
1459 m_errorMonitor->ExpectSuccess();
1460 const float ibo_data[3] = {0.f, 0.f, 0.f};
1461 VkBufferObj ibo, ibo2;
1462 buffer_usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1463 ibo.init(*m_device, ibo.create_info(sizeof(ibo_data), buffer_usage, nullptr), mem_prop);
1464 ibo2.init(*m_device, ibo2.create_info(sizeof(ibo_data), buffer_usage, nullptr), mem_prop);
1465
1466 m_commandBuffer->reset();
1467 m_commandBuffer->begin();
1468 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1469 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1470 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), ibo.handle(), 0, VK_INDEX_TYPE_UINT16);
1471 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1472 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1473
1474 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1475 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1476 &descriptor_set.set_, 0, nullptr);
1477 m_commandBuffer->DrawIndexed(3, 1, 0, 0, 0);
1478 m_commandBuffer->EndRenderPass();
1479 m_commandBuffer->end();
1480 m_errorMonitor->VerifyNotFound();
1481
1482 m_commandBuffer->reset();
1483 m_commandBuffer->begin();
1484
1485 buffer_region = {0, 0, sizeof(ibo_data)};
1486 vk::CmdCopyBuffer(m_commandBuffer->handle(), ibo2.handle(), ibo.handle(), 1, &buffer_region);
1487
1488 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1489 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1490 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), ibo.handle(), 0, VK_INDEX_TYPE_UINT16);
1491 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1492 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1493 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1494 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1495 &descriptor_set.set_, 0, nullptr);
1496
1497 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1498 m_commandBuffer->DrawIndexed(3, 1, 0, 0, 0);
1499 m_errorMonitor->VerifyFound();
1500
1501 m_commandBuffer->EndRenderPass();
1502 m_commandBuffer->end();
1503
1504 // DrawIndirect
1505 m_errorMonitor->ExpectSuccess();
1506 VkBufferObj buffer_drawIndirect, buffer_drawIndirect2;
1507 buffer_usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1508 buffer_drawIndirect.init(*m_device, buffer_drawIndirect.create_info(sizeof(VkDrawIndirectCommand), buffer_usage, nullptr),
1509 mem_prop);
1510 buffer_drawIndirect2.init(*m_device, buffer_drawIndirect2.create_info(sizeof(VkDrawIndirectCommand), buffer_usage, nullptr),
1511 mem_prop);
1512
1513 m_commandBuffer->reset();
1514 m_commandBuffer->begin();
1515 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1516 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1517 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1518 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1519
1520 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1521 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1522 &descriptor_set.set_, 0, nullptr);
1523 vk::CmdDrawIndirect(m_commandBuffer->handle(), buffer_drawIndirect.handle(), 0, 1, sizeof(VkDrawIndirectCommand));
1524 m_commandBuffer->EndRenderPass();
1525 m_commandBuffer->end();
1526 m_errorMonitor->VerifyNotFound();
1527
1528 m_commandBuffer->reset();
1529 m_commandBuffer->begin();
1530
1531 buffer_region = {0, 0, sizeof(VkDrawIndirectCommand)};
1532 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_drawIndirect2.handle(), buffer_drawIndirect.handle(), 1, &buffer_region);
1533
1534 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1535 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1536 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1537 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1538 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1539 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1540 &descriptor_set.set_, 0, nullptr);
1541
1542 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1543 vk::CmdDrawIndirect(m_commandBuffer->handle(), buffer_drawIndirect.handle(), 0, 1, sizeof(VkDrawIndirectCommand));
1544 m_errorMonitor->VerifyFound();
1545
1546 m_commandBuffer->EndRenderPass();
1547 m_commandBuffer->end();
1548
1549 // DrawIndexedIndirect
1550 m_errorMonitor->ExpectSuccess();
1551 VkBufferObj buffer_drawIndexedIndirect, buffer_drawIndexedIndirect2;
1552 buffer_usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1553 buffer_drawIndexedIndirect.init(
1554 *m_device, buffer_drawIndexedIndirect.create_info(sizeof(VkDrawIndexedIndirectCommand), buffer_usage, nullptr), mem_prop);
1555 buffer_drawIndexedIndirect2.init(
1556 *m_device, buffer_drawIndexedIndirect2.create_info(sizeof(VkDrawIndexedIndirectCommand), buffer_usage, nullptr), mem_prop);
1557
1558 m_commandBuffer->reset();
1559 m_commandBuffer->begin();
1560 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1561 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1562 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), ibo.handle(), 0, VK_INDEX_TYPE_UINT16);
1563 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1564 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1565
1566 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1567 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1568 &descriptor_set.set_, 0, nullptr);
1569 vk::CmdDrawIndexedIndirect(m_commandBuffer->handle(), buffer_drawIndirect.handle(), 0, 1, sizeof(VkDrawIndexedIndirectCommand));
1570 m_commandBuffer->EndRenderPass();
1571 m_commandBuffer->end();
1572 m_errorMonitor->VerifyNotFound();
1573
1574 m_commandBuffer->reset();
1575 m_commandBuffer->begin();
1576
1577 buffer_region = {0, 0, sizeof(VkDrawIndexedIndirectCommand)};
1578 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_drawIndexedIndirect2.handle(), buffer_drawIndexedIndirect.handle(), 1,
1579 &buffer_region);
1580
1581 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1582 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1583 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), ibo.handle(), 0, VK_INDEX_TYPE_UINT16);
1584 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1585 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1586 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1587 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1588 &descriptor_set.set_, 0, nullptr);
1589
1590 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1591 vk::CmdDrawIndexedIndirect(m_commandBuffer->handle(), buffer_drawIndexedIndirect.handle(), 0, 1,
1592 sizeof(VkDrawIndexedIndirectCommand));
1593 m_errorMonitor->VerifyFound();
1594
1595 m_commandBuffer->EndRenderPass();
1596 m_commandBuffer->end();
1597
1598 if (has_khr_indirect) {
1599 // DrawIndirectCount
1600 auto fpCmdDrawIndirectCountKHR =
1601 (PFN_vkCmdDrawIndirectCount)vk::GetDeviceProcAddr(m_device->device(), "vkCmdDrawIndirectCountKHR");
1602 if (!fpCmdDrawIndirectCountKHR) {
1603 printf("%s Test requires unsupported vkCmdDrawIndirectCountKHR feature. Skipped.\n", kSkipPrefix);
1604 } else {
1605 m_errorMonitor->ExpectSuccess();
1606 VkBufferObj buffer_count, buffer_count2;
1607 buffer_usage =
1608 VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1609 buffer_count.init(*m_device, buffer_count.create_info(sizeof(uint32_t), buffer_usage, nullptr), mem_prop);
1610 buffer_count2.init(*m_device, buffer_count2.create_info(sizeof(uint32_t), buffer_usage, nullptr), mem_prop);
1611
1612 m_commandBuffer->reset();
1613 m_commandBuffer->begin();
1614 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1615 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1616 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1617 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1618
1619 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1620 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(),
1621 0, 1, &descriptor_set.set_, 0, nullptr);
1622 fpCmdDrawIndirectCountKHR(m_commandBuffer->handle(), buffer_drawIndirect.handle(), 0, buffer_count.handle(), 0, 1,
1623 sizeof(VkDrawIndirectCommand));
1624 m_commandBuffer->EndRenderPass();
1625 m_commandBuffer->end();
1626 m_errorMonitor->VerifyNotFound();
1627
1628 m_commandBuffer->reset();
1629 m_commandBuffer->begin();
1630
1631 buffer_region = {0, 0, sizeof(uint32_t)};
1632 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_count2.handle(), buffer_count.handle(), 1, &buffer_region);
1633
1634 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1635 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1636 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1637 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1638 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1639 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(),
1640 0, 1, &descriptor_set.set_, 0, nullptr);
1641
1642 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1643 fpCmdDrawIndirectCountKHR(m_commandBuffer->handle(), buffer_drawIndirect.handle(), 0, buffer_count.handle(), 0, 1,
1644 sizeof(VkDrawIndirectCommand));
1645 m_errorMonitor->VerifyFound();
1646
1647 m_commandBuffer->EndRenderPass();
1648 m_commandBuffer->end();
1649 }
1650
1651 // DrawIndexedIndirectCount
1652 auto fpCmdDrawIndexIndirectCountKHR =
1653 (PFN_vkCmdDrawIndirectCount)vk::GetDeviceProcAddr(m_device->device(), "vkCmdDrawIndexedIndirectCountKHR");
1654 if (!fpCmdDrawIndexIndirectCountKHR) {
1655 printf("%s Test requires unsupported vkCmdDrawIndexedIndirectCountKHR feature. Skipped.\n", kSkipPrefix);
1656 } else {
1657 m_errorMonitor->ExpectSuccess();
1658 VkBufferObj buffer_count, buffer_count2;
1659 buffer_usage =
1660 VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1661 buffer_count.init(*m_device, buffer_count.create_info(sizeof(uint32_t), buffer_usage, nullptr), mem_prop);
1662 buffer_count2.init(*m_device, buffer_count2.create_info(sizeof(uint32_t), buffer_usage, nullptr), mem_prop);
1663
1664 m_commandBuffer->reset();
1665 m_commandBuffer->begin();
1666 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1667 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1668 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), ibo.handle(), 0, VK_INDEX_TYPE_UINT16);
1669 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1670 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1671
1672 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1673 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(),
1674 0, 1, &descriptor_set.set_, 0, nullptr);
1675 fpCmdDrawIndexIndirectCountKHR(m_commandBuffer->handle(), buffer_drawIndexedIndirect.handle(), 0, buffer_count.handle(),
1676 0, 1, sizeof(VkDrawIndexedIndirectCommand));
1677 m_commandBuffer->EndRenderPass();
1678 m_commandBuffer->end();
1679 m_errorMonitor->VerifyNotFound();
1680
1681 m_commandBuffer->reset();
1682 m_commandBuffer->begin();
1683
1684 buffer_region = {0, 0, sizeof(uint32_t)};
1685 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_count2.handle(), buffer_count.handle(), 1, &buffer_region);
1686
1687 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1688 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1689 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), ibo.handle(), 0, VK_INDEX_TYPE_UINT16);
1690 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1691 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1692 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1693 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(),
1694 0, 1, &descriptor_set.set_, 0, nullptr);
1695
1696 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1697 fpCmdDrawIndexIndirectCountKHR(m_commandBuffer->handle(), buffer_drawIndexedIndirect.handle(), 0, buffer_count.handle(),
1698 0, 1, sizeof(VkDrawIndexedIndirectCommand));
1699 m_errorMonitor->VerifyFound();
1700
1701 m_commandBuffer->EndRenderPass();
1702 m_commandBuffer->end();
1703 }
1704 } else {
1705 printf("%s Test requires unsupported vkCmdDrawIndirectCountKHR & vkDrawIndexedIndirectCountKHR feature. Skipped.\n",
1706 kSkipPrefix);
1707 }
1708}
1709
1710TEST_F(VkSyncValTest, SyncCmdClear) {
1711 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
1712 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
1713 // CmdClearColorImage
1714 m_errorMonitor->ExpectSuccess();
1715 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1716 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
1717 VkImageObj image_a(m_device), image_b(m_device);
1718 auto image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 1, format, usage, VK_IMAGE_TILING_OPTIMAL);
1719 image_a.Init(image_ci);
1720 image_b.Init(image_ci);
1721
1722 VkImageSubresourceLayers layers_all{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
1723 VkOffset3D zero_offset{0, 0, 0};
1724 VkExtent3D full_extent{128, 128, 1}; // <-- image type is 2D
1725 VkImageSubresourceRange full_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
1726
1727 VkImageCopy full_region = {layers_all, zero_offset, layers_all, zero_offset, full_extent};
1728
1729 m_commandBuffer->begin();
1730
1731 image_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1732 image_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1733
1734 auto cb = m_commandBuffer->handle();
1735 VkClearColorValue ccv = {};
1736 vk::CmdClearColorImage(m_commandBuffer->handle(), image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &full_subresource_range);
1737 m_commandBuffer->end();
1738 m_errorMonitor->VerifyNotFound();
1739
1740 m_commandBuffer->reset();
1741 m_commandBuffer->begin();
1742 vk::CmdCopyImage(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
1743
1744 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1745 vk::CmdClearColorImage(m_commandBuffer->handle(), image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &full_subresource_range);
1746 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1747 vk::CmdClearColorImage(m_commandBuffer->handle(), image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &full_subresource_range);
1748 m_errorMonitor->VerifyFound();
1749
1750 m_commandBuffer->end();
1751
1752 // CmdClearDepthStencilImage
1753 format = FindSupportedDepthStencilFormat(gpu());
1754 if (!format) {
1755 printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix);
1756 return;
1757 }
1758 m_errorMonitor->ExpectSuccess();
1759 VkImageObj image_ds_a(m_device), image_ds_b(m_device);
1760 image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 1, format, usage, VK_IMAGE_TILING_OPTIMAL);
1761 image_ds_a.Init(image_ci);
1762 image_ds_b.Init(image_ci);
1763
1764 const VkImageAspectFlags ds_aspect = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
1765 image_ds_a.SetLayout(ds_aspect, VK_IMAGE_LAYOUT_GENERAL);
1766 image_ds_b.SetLayout(ds_aspect, VK_IMAGE_LAYOUT_GENERAL);
1767
1768 m_commandBuffer->begin();
1769 const VkClearDepthStencilValue clear_value = {};
1770 VkImageSubresourceRange ds_range = {ds_aspect, 0, 1, 0, 1};
1771
1772 vk::CmdClearDepthStencilImage(cb, image_ds_a.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1, &ds_range);
1773 m_commandBuffer->end();
1774 m_errorMonitor->VerifyNotFound();
1775
1776 VkImageSubresourceLayers ds_layers_all{ds_aspect, 0, 0, 1};
1777 VkImageCopy ds_full_region = {ds_layers_all, zero_offset, ds_layers_all, zero_offset, full_extent};
1778
1779 m_commandBuffer->reset();
1780 m_commandBuffer->begin();
1781 vk::CmdCopyImage(cb, image_ds_a.handle(), VK_IMAGE_LAYOUT_GENERAL, image_ds_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1782 &ds_full_region);
1783
1784 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1785 vk::CmdClearDepthStencilImage(m_commandBuffer->handle(), image_ds_a.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1,
1786 &ds_range);
1787 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1788 vk::CmdClearDepthStencilImage(m_commandBuffer->handle(), image_ds_b.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1,
1789 &ds_range);
1790 m_errorMonitor->VerifyFound();
1791
1792 m_commandBuffer->end();
1793}
1794
1795TEST_F(VkSyncValTest, SyncCmdQuery) {
1796 // CmdCopyQueryPoolResults
1797 m_errorMonitor->ExpectSuccess();
1798 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
1799 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
1800 if (IsPlatform(kNexusPlayer)) {
1801 printf("%s This test should not run on Nexus Player\n", kSkipPrefix);
1802 return;
1803 }
1804 if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) {
1805 printf("%s Queue family needs to have multiple queues to run this test.\n", kSkipPrefix);
1806 return;
1807 }
1808 uint32_t queue_count;
1809 vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_count, NULL);
Jeremy Gebbend2573fc2021-05-12 17:17:38 -06001810 std::vector<VkQueueFamilyProperties> queue_props(queue_count);
1811 vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_count, queue_props.data());
Jeremy Gebben170781d2020-11-19 16:21:21 -07001812 if (queue_props[m_device->graphics_queue_node_index_].timestampValidBits == 0) {
1813 printf("%s Device graphic queue has timestampValidBits of 0, skipping.\n", kSkipPrefix);
1814 return;
1815 }
1816
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001817 vk_testing::QueryPool query_pool;
Jeremy Gebben170781d2020-11-19 16:21:21 -07001818 VkQueryPoolCreateInfo query_pool_create_info{};
1819 query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
1820 query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
1821 query_pool_create_info.queryCount = 1;
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001822 query_pool.init(*m_device, query_pool_create_info);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001823
1824 VkBufferObj buffer_a, buffer_b;
1825 VkMemoryPropertyFlags mem_prop = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
1826 buffer_a.init_as_src_and_dst(*m_device, 256, mem_prop);
1827 buffer_b.init_as_src_and_dst(*m_device, 256, mem_prop);
1828
1829 VkBufferCopy region = {0, 0, 256};
1830
1831 auto cb = m_commandBuffer->handle();
1832 m_commandBuffer->begin();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001833 vk::CmdResetQueryPool(cb, query_pool.handle(), 0, 1);
1834 vk::CmdWriteTimestamp(cb, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool.handle(), 0);
1835 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 -07001836 m_commandBuffer->end();
1837 m_errorMonitor->VerifyNotFound();
1838
1839 m_commandBuffer->reset();
1840 m_commandBuffer->begin();
1841 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &region);
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001842 vk::CmdResetQueryPool(cb, query_pool.handle(), 0, 1);
1843 vk::CmdWriteTimestamp(cb, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool.handle(), 0);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001844 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001845 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 -07001846 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001847 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 -07001848 m_commandBuffer->end();
1849 m_errorMonitor->VerifyFound();
1850
1851 // TODO:Track VkQueryPool
1852 // TODO:CmdWriteTimestamp
Jeremy Gebben170781d2020-11-19 16:21:21 -07001853}
1854
1855TEST_F(VkSyncValTest, SyncCmdDrawDepthStencil) {
1856 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
1857 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
1858 m_errorMonitor->ExpectSuccess();
1859
1860 const auto format_ds = FindSupportedDepthStencilFormat(gpu());
1861 if (!format_ds) {
1862 printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix);
1863 return;
1864 }
1865 const auto format_dp = FindSupportedDepthOnlyFormat(gpu());
1866 if (!format_dp) {
1867 printf("%s No only Depth format found. Skipped.\n", kSkipPrefix);
1868 return;
1869 }
1870 const auto format_st = FindSupportedStencilOnlyFormat(gpu());
1871 if (!format_st) {
1872 printf("%s No only Stencil format found. Skipped.\n", kSkipPrefix);
1873 return;
1874 }
1875
1876 VkDepthStencilObj image_ds(m_device), image_dp(m_device), image_st(m_device);
1877 image_ds.Init(m_device, 16, 16, format_ds);
1878 image_dp.Init(m_device, 16, 16, format_dp);
1879 image_st.Init(m_device, 16, 16, format_st);
1880
1881 VkRenderpassObj rp_ds(m_device, format_ds, true), rp_dp(m_device, format_dp, true), rp_st(m_device, format_st, true);
1882
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001883 vk_testing::Framebuffer fb_ds, fb_dp, fb_st;
Jeremy Gebben170781d2020-11-19 16:21:21 -07001884 VkFramebufferCreateInfo fbci = {
1885 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 -06001886 fb_ds.init(*m_device, fbci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001887 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 -06001888 fb_dp.init(*m_device, fbci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001889 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 -06001890 fb_st.init(*m_device, fbci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07001891
1892 VkStencilOpState stencil = {};
1893 stencil.failOp = VK_STENCIL_OP_KEEP;
1894 stencil.passOp = VK_STENCIL_OP_KEEP;
1895 stencil.depthFailOp = VK_STENCIL_OP_KEEP;
1896 stencil.compareOp = VK_COMPARE_OP_NEVER;
1897
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07001898 auto ds_ci = LvlInitStruct<VkPipelineDepthStencilStateCreateInfo>();
Jeremy Gebben170781d2020-11-19 16:21:21 -07001899 ds_ci.depthTestEnable = VK_TRUE;
1900 ds_ci.depthWriteEnable = VK_TRUE;
1901 ds_ci.depthCompareOp = VK_COMPARE_OP_NEVER;
1902 ds_ci.stencilTestEnable = VK_TRUE;
1903 ds_ci.front = stencil;
1904 ds_ci.back = stencil;
1905
1906 CreatePipelineHelper g_pipe_ds(*this), g_pipe_dp(*this), g_pipe_st(*this);
1907 g_pipe_ds.InitInfo();
1908 g_pipe_ds.gp_ci_.renderPass = rp_ds.handle();
1909 g_pipe_ds.gp_ci_.pDepthStencilState = &ds_ci;
1910 g_pipe_ds.InitState();
1911 ASSERT_VK_SUCCESS(g_pipe_ds.CreateGraphicsPipeline());
1912 g_pipe_dp.InitInfo();
1913 g_pipe_dp.gp_ci_.renderPass = rp_dp.handle();
1914 ds_ci.stencilTestEnable = VK_FALSE;
1915 g_pipe_dp.gp_ci_.pDepthStencilState = &ds_ci;
1916 g_pipe_dp.InitState();
1917 ASSERT_VK_SUCCESS(g_pipe_dp.CreateGraphicsPipeline());
1918 g_pipe_st.InitInfo();
1919 g_pipe_st.gp_ci_.renderPass = rp_st.handle();
1920 ds_ci.depthTestEnable = VK_FALSE;
1921 ds_ci.stencilTestEnable = VK_TRUE;
1922 g_pipe_st.gp_ci_.pDepthStencilState = &ds_ci;
1923 g_pipe_st.InitState();
1924 ASSERT_VK_SUCCESS(g_pipe_st.CreateGraphicsPipeline());
1925
1926 m_commandBuffer->begin();
1927 m_renderPassBeginInfo.renderArea = {{0, 0}, {16, 16}};
1928 m_renderPassBeginInfo.pClearValues = nullptr;
1929 m_renderPassBeginInfo.clearValueCount = 0;
1930
1931 m_renderPassBeginInfo.renderPass = rp_ds.handle();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001932 m_renderPassBeginInfo.framebuffer = fb_ds.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07001933 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1934 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_ds.pipeline_);
1935 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1936 m_commandBuffer->EndRenderPass();
1937
1938 m_renderPassBeginInfo.renderPass = rp_dp.handle();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001939 m_renderPassBeginInfo.framebuffer = fb_dp.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07001940 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1941 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_dp.pipeline_);
1942 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1943 m_commandBuffer->EndRenderPass();
1944
1945 m_renderPassBeginInfo.renderPass = rp_st.handle();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001946 m_renderPassBeginInfo.framebuffer = fb_st.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07001947 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1948 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_st.pipeline_);
1949 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1950 m_commandBuffer->EndRenderPass();
1951
1952 m_commandBuffer->end();
1953 m_errorMonitor->VerifyNotFound();
1954
1955 m_commandBuffer->reset();
1956 m_commandBuffer->begin();
1957
1958 VkImageCopy copyRegion;
1959 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
1960 copyRegion.srcSubresource.mipLevel = 0;
1961 copyRegion.srcSubresource.baseArrayLayer = 0;
1962 copyRegion.srcSubresource.layerCount = 1;
1963 copyRegion.srcOffset = {0, 0, 0};
1964 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
1965 copyRegion.dstSubresource.mipLevel = 0;
1966 copyRegion.dstSubresource.baseArrayLayer = 0;
1967 copyRegion.dstSubresource.layerCount = 1;
1968 copyRegion.dstOffset = {0, 0, 0};
1969 copyRegion.extent = {16, 16, 1};
1970
1971 m_commandBuffer->CopyImage(image_ds.handle(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, image_dp.handle(),
1972 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 1, &copyRegion);
1973
1974 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
1975 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
1976 m_commandBuffer->CopyImage(image_ds.handle(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, image_st.handle(),
1977 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 1, &copyRegion);
1978 m_renderPassBeginInfo.renderPass = rp_ds.handle();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001979 m_renderPassBeginInfo.framebuffer = fb_ds.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07001980 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1981 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1982 m_errorMonitor->VerifyFound();
1983 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1984 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_ds.pipeline_);
1985 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1986 m_commandBuffer->EndRenderPass();
1987
1988 m_renderPassBeginInfo.renderPass = rp_dp.handle();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001989 m_renderPassBeginInfo.framebuffer = fb_dp.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07001990 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1991 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1992 m_errorMonitor->VerifyFound();
1993 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1994 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_dp.pipeline_);
1995 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1996 m_commandBuffer->EndRenderPass();
1997
1998 m_renderPassBeginInfo.renderPass = rp_st.handle();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06001999 m_renderPassBeginInfo.framebuffer = fb_st.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002000 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
2001 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2002 m_errorMonitor->VerifyFound();
2003 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2004 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_st.pipeline_);
2005 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
2006 m_commandBuffer->EndRenderPass();
2007
2008 m_commandBuffer->end();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002009}
2010
John Zulaufd57a36b2021-08-16 10:34:44 -06002011
Jeremy Gebben170781d2020-11-19 16:21:21 -07002012TEST_F(VkSyncValTest, RenderPassLoadHazardVsInitialLayout) {
2013 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
John Zulaufd57a36b2021-08-16 10:34:44 -06002014 bool do_none_load_op_test = false;
2015 if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_LOAD_STORE_OP_NONE_EXTENSION_NAME)) {
2016 m_device_extension_names.push_back(VK_EXT_LOAD_STORE_OP_NONE_EXTENSION_NAME);
2017 do_none_load_op_test = true;
2018 }
2019
Jeremy Gebben170781d2020-11-19 16:21:21 -07002020 ASSERT_NO_FATAL_FAILURE(InitState());
2021 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2022
2023 VkImageUsageFlags usage_color = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
2024 VkImageUsageFlags usage_input = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
2025 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
2026 VkImageObj image_color(m_device), image_input(m_device);
2027 auto image_ci = VkImageObj::ImageCreateInfo2D(32, 32, 1, 1, format, usage_color, VK_IMAGE_TILING_OPTIMAL);
2028 image_color.Init(image_ci);
2029 image_ci.usage = usage_input;
2030 image_input.Init(image_ci);
2031 VkImageView attachments[] = {image_color.targetView(format), image_input.targetView(format)};
2032
John Zulaufd57a36b2021-08-16 10:34:44 -06002033 VkAttachmentDescription attachmentDescriptions[] = {
Jeremy Gebben170781d2020-11-19 16:21:21 -07002034 // Result attachment
2035 {(VkAttachmentDescriptionFlags)0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR,
2036 VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
2037 VK_IMAGE_LAYOUT_UNDEFINED, // Here causes DesiredError that SYNC-HAZARD-NONE in BeginRenderPass.
2038 // It should be VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
2039 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
2040 // Input attachment
2041 {(VkAttachmentDescriptionFlags)0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD,
2042 VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
2043 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL}};
2044
2045 const VkAttachmentReference resultAttachmentRef = {0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
2046 const VkAttachmentReference inputAttachmentRef = {1u, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};
2047
2048 const VkSubpassDescription subpassDescription = {(VkSubpassDescriptionFlags)0,
2049 VK_PIPELINE_BIND_POINT_GRAPHICS,
2050 1u,
2051 &inputAttachmentRef,
2052 1u,
2053 &resultAttachmentRef,
2054 0,
2055 0,
2056 0u,
2057 0};
2058
2059 const VkSubpassDependency subpassDependency = {VK_SUBPASS_EXTERNAL,
2060 0,
2061 VK_PIPELINE_STAGE_TRANSFER_BIT,
2062 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
2063 VK_ACCESS_TRANSFER_WRITE_BIT,
2064 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | VK_ACCESS_SHADER_READ_BIT,
2065 VK_DEPENDENCY_BY_REGION_BIT};
2066
2067 const VkRenderPassCreateInfo renderPassInfo = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
2068 0,
2069 (VkRenderPassCreateFlags)0,
2070 2u,
2071 attachmentDescriptions,
2072 1u,
2073 &subpassDescription,
2074 1u,
2075 &subpassDependency};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002076 vk_testing::RenderPass rp;
2077 rp.init(*m_device, renderPassInfo);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002078
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002079 vk_testing::Framebuffer fb;
2080 VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp.handle(), 2, attachments, 32, 32, 1};
2081 fb.init(*m_device, fbci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002082
2083 image_input.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
2084
2085 m_commandBuffer->begin();
2086
2087 m_renderPassBeginInfo.renderArea = {{0, 0}, {32, 32}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002088 m_renderPassBeginInfo.renderPass = rp.handle();
2089 m_renderPassBeginInfo.framebuffer = fb.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002090
2091 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
2092 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
2093 // Even though we have no accesses prior, the layout transition *is* an access, so load can be validated vs. layout transition
2094 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2095 m_errorMonitor->VerifyFound();
John Zulaufd57a36b2021-08-16 10:34:44 -06002096
2097 vk_testing::RenderPass rp_no_load_store;
2098 if (do_none_load_op_test) {
2099 m_errorMonitor->ExpectSuccess();
2100 attachmentDescriptions[0].loadOp = VK_ATTACHMENT_LOAD_OP_NONE_EXT;
2101 attachmentDescriptions[0].storeOp = VK_ATTACHMENT_STORE_OP_NONE_EXT;
2102 attachmentDescriptions[1].loadOp = VK_ATTACHMENT_LOAD_OP_NONE_EXT;
2103 attachmentDescriptions[1].storeOp = VK_ATTACHMENT_STORE_OP_NONE_EXT;
2104 rp_no_load_store.init(*m_device, renderPassInfo);
2105 m_renderPassBeginInfo.renderPass = rp_no_load_store.handle();
2106 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2107 m_commandBuffer->EndRenderPass();
2108 m_errorMonitor->VerifyNotFound();
2109 } else {
2110 printf("%s VK_EXT_load_store_op_none not supported, skipping sub-test\n", kSkipPrefix);
2111 }
Jeremy Gebben170781d2020-11-19 16:21:21 -07002112}
2113
2114TEST_F(VkSyncValTest, SyncRenderPassWithWrongDepthStencilInitialLayout) {
2115 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
2116 ASSERT_NO_FATAL_FAILURE(InitState());
2117 if (IsPlatform(kNexusPlayer)) {
2118 printf("%s This test should not run on Nexus Player\n", kSkipPrefix);
2119 return;
2120 }
2121
2122 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2123
2124 VkFormat color_format = VK_FORMAT_R8G8B8A8_UNORM;
2125 VkFormat ds_format = FindSupportedDepthStencilFormat(gpu());
2126 if (!ds_format) {
2127 printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix);
2128 return;
2129 }
2130 VkImageUsageFlags usage_color = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
2131 VkImageUsageFlags usage_ds = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
2132 VkImageObj image_color(m_device), image_color2(m_device);
2133 auto image_ci = VkImageObj::ImageCreateInfo2D(32, 32, 1, 1, color_format, usage_color, VK_IMAGE_TILING_OPTIMAL);
2134 image_color.Init(image_ci);
2135 image_color2.Init(image_ci);
2136 VkDepthStencilObj image_ds(m_device);
2137 image_ds.Init(m_device, 32, 32, ds_format, usage_ds);
2138
2139 const VkAttachmentDescription colorAttachmentDescription = {(VkAttachmentDescriptionFlags)0,
2140 color_format,
2141 VK_SAMPLE_COUNT_1_BIT,
2142 VK_ATTACHMENT_LOAD_OP_CLEAR,
2143 VK_ATTACHMENT_STORE_OP_STORE,
2144 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2145 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2146 VK_IMAGE_LAYOUT_UNDEFINED,
2147 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
2148
2149 const VkAttachmentDescription depthStencilAttachmentDescription = {
2150 (VkAttachmentDescriptionFlags)0, ds_format, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR,
2151 VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE,
2152 VK_IMAGE_LAYOUT_UNDEFINED, // Here causes DesiredError that SYNC-HAZARD-WRITE_AFTER_WRITE in BeginRenderPass.
2153 // It should be VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
2154 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
2155
2156 std::vector<VkAttachmentDescription> attachmentDescriptions;
2157 attachmentDescriptions.push_back(colorAttachmentDescription);
2158 attachmentDescriptions.push_back(depthStencilAttachmentDescription);
2159
2160 const VkAttachmentReference colorAttachmentRef = {0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
2161
2162 const VkAttachmentReference depthStencilAttachmentRef = {1u, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
2163
2164 const VkSubpassDescription subpassDescription = {(VkSubpassDescriptionFlags)0,
2165 VK_PIPELINE_BIND_POINT_GRAPHICS,
2166 0u,
2167 0,
2168 1u,
2169 &colorAttachmentRef,
2170 0,
2171 &depthStencilAttachmentRef,
2172 0u,
2173 0};
2174
2175 const VkRenderPassCreateInfo renderPassInfo = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
2176 0,
2177 (VkRenderPassCreateFlags)0,
2178 (uint32_t)attachmentDescriptions.size(),
2179 &attachmentDescriptions[0],
2180 1u,
2181 &subpassDescription,
2182 0u,
2183 0};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002184 vk_testing::RenderPass rp;
2185 rp.init(*m_device, renderPassInfo);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002186
2187 VkImageView fb_attachments[] = {image_color.targetView(color_format),
2188 image_ds.targetView(ds_format, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)};
2189 const VkFramebufferCreateInfo fbci = {
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002190 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, 0, 0u, rp.handle(), 2u, fb_attachments, 32, 32, 1u,
Jeremy Gebben170781d2020-11-19 16:21:21 -07002191 };
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002192 vk_testing::Framebuffer fb;
2193 fb.init(*m_device, fbci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002194 fb_attachments[0] = image_color2.targetView(color_format);
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002195 vk_testing::Framebuffer fb1;
2196 fb1.init(*m_device, fbci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002197
2198 CreatePipelineHelper g_pipe(*this);
2199 g_pipe.InitInfo();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002200 g_pipe.gp_ci_.renderPass = rp.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002201
2202 VkStencilOpState stencil = {};
2203 stencil.failOp = VK_STENCIL_OP_KEEP;
2204 stencil.passOp = VK_STENCIL_OP_KEEP;
2205 stencil.depthFailOp = VK_STENCIL_OP_KEEP;
2206 stencil.compareOp = VK_COMPARE_OP_NEVER;
2207
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07002208 auto ds_ci = LvlInitStruct<VkPipelineDepthStencilStateCreateInfo>();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002209 ds_ci.depthTestEnable = VK_TRUE;
2210 ds_ci.depthWriteEnable = VK_TRUE;
2211 ds_ci.depthCompareOp = VK_COMPARE_OP_NEVER;
2212 ds_ci.stencilTestEnable = VK_TRUE;
2213 ds_ci.front = stencil;
2214 ds_ci.back = stencil;
2215
2216 g_pipe.gp_ci_.pDepthStencilState = &ds_ci;
2217 g_pipe.InitState();
2218 ASSERT_VK_SUCCESS(g_pipe.CreateGraphicsPipeline());
2219
2220 m_commandBuffer->begin();
Tony-LunarG73f37032021-06-07 11:47:03 -06002221 VkClearValue clear = {};
2222 std::array<VkClearValue, 2> clear_values = { {clear, clear} };
2223 m_renderPassBeginInfo.pClearValues = clear_values.data();
2224 m_renderPassBeginInfo.clearValueCount = clear_values.size();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002225 m_renderPassBeginInfo.renderArea = {{0, 0}, {32, 32}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002226 m_renderPassBeginInfo.renderPass = rp.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002227
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002228 m_renderPassBeginInfo.framebuffer = fb.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002229 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2230 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
2231 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
2232 m_commandBuffer->EndRenderPass();
2233
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002234 m_renderPassBeginInfo.framebuffer = fb1.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002235
2236 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
2237 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2238 m_errorMonitor->VerifyFound();
2239}
2240
2241TEST_F(VkSyncValTest, SyncLayoutTransition) {
2242 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
2243 ASSERT_NO_FATAL_FAILURE(InitState());
2244 if (IsPlatform(kNexusPlayer)) {
2245 printf("%s This test should not run on Nexus Player\n", kSkipPrefix);
2246 return;
2247 }
2248
2249 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2250
2251 VkImageUsageFlags usage_color = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
2252 VkImageUsageFlags usage_input =
2253 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
2254 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
2255 VkImageObj image_color(m_device), image_input(m_device);
2256 auto image_ci = VkImageObj::ImageCreateInfo2D(64, 64, 1, 1, format, usage_input, VK_IMAGE_TILING_OPTIMAL);
2257 image_input.InitNoLayout(image_ci);
2258 image_ci.usage = usage_color;
2259 image_color.InitNoLayout(image_ci);
2260 VkImageView view_input = image_input.targetView(format);
2261 VkImageView view_color = image_color.targetView(format);
2262 VkImageView attachments[] = {view_color, view_input};
2263
2264 const VkAttachmentDescription fbAttachment = {
2265 0u,
2266 format,
2267 VK_SAMPLE_COUNT_1_BIT,
2268 VK_ATTACHMENT_LOAD_OP_CLEAR,
2269 VK_ATTACHMENT_STORE_OP_STORE,
2270 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2271 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2272 VK_IMAGE_LAYOUT_UNDEFINED,
2273 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
2274 };
2275
2276 std::vector<VkAttachmentDescription> attachmentDescs;
2277 attachmentDescs.push_back(fbAttachment);
2278
2279 // Add it as a frame buffer attachment.
2280 const VkAttachmentDescription inputAttachment = {
2281 0u,
2282 format,
2283 VK_SAMPLE_COUNT_1_BIT,
2284 VK_ATTACHMENT_LOAD_OP_LOAD,
2285 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2286 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2287 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2288 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
2289 VK_IMAGE_LAYOUT_GENERAL,
2290 };
2291 attachmentDescs.push_back(inputAttachment);
2292
2293 std::vector<VkAttachmentReference> inputAttachments;
2294 const VkAttachmentReference inputRef = {
2295 1u,
2296 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
2297 };
2298 inputAttachments.push_back(inputRef);
2299
2300 const VkAttachmentReference colorRef = {
2301 0u,
2302 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
2303 };
2304 const std::vector<VkAttachmentReference> colorAttachments(1u, colorRef);
2305
2306 const VkSubpassDescription subpass = {
2307 0u,
2308 VK_PIPELINE_BIND_POINT_GRAPHICS,
2309 static_cast<uint32_t>(inputAttachments.size()),
2310 inputAttachments.data(),
2311 static_cast<uint32_t>(colorAttachments.size()),
2312 colorAttachments.data(),
2313 0u,
2314 nullptr,
2315 0u,
2316 nullptr,
2317 };
2318 const std::vector<VkSubpassDescription> subpasses(1u, subpass);
2319
2320 const VkRenderPassCreateInfo renderPassInfo = {
2321 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
2322 nullptr,
2323 0u,
2324 static_cast<uint32_t>(attachmentDescs.size()),
2325 attachmentDescs.data(),
2326 static_cast<uint32_t>(subpasses.size()),
2327 subpasses.data(),
2328 0u,
2329 nullptr,
2330 };
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002331 vk_testing::RenderPass rp;
2332 rp.init(*m_device, renderPassInfo);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002333
2334 const VkFramebufferCreateInfo fbci = {
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002335 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, 0, 0u, rp.handle(), 2u, attachments, 64, 64, 1u,
Jeremy Gebben170781d2020-11-19 16:21:21 -07002336 };
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002337 vk_testing::Framebuffer fb;
2338 fb.init(*m_device, fbci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002339
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002340 vk_testing::Sampler sampler;
Jeremy Gebben170781d2020-11-19 16:21:21 -07002341 VkSamplerCreateInfo sampler_info = SafeSaneSamplerCreateInfo();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002342 sampler.init(*m_device, sampler_info);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002343
sfricke-samsung1c0b96a2021-07-08 22:24:09 -07002344 char const *fsSource = R"glsl(
2345 #version 450
2346 layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;
2347 void main() {
2348 vec4 color = subpassLoad(x);
2349 }
2350 )glsl";
Jeremy Gebben170781d2020-11-19 16:21:21 -07002351
2352 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
2353 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
2354
2355 CreatePipelineHelper g_pipe(*this);
2356 g_pipe.InitInfo();
2357 g_pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
2358 g_pipe.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002359 g_pipe.gp_ci_.renderPass = rp.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002360 g_pipe.InitState();
2361 ASSERT_VK_SUCCESS(g_pipe.CreateGraphicsPipeline());
2362
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002363 g_pipe.descriptor_set_->WriteDescriptorImageInfo(0, view_input, sampler.handle(), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002364 g_pipe.descriptor_set_->UpdateDescriptorSets();
2365
2366 m_commandBuffer->begin();
2367 auto cb = m_commandBuffer->handle();
2368 VkClearColorValue ccv = {};
2369 VkImageSubresourceRange full_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
2370
2371 const VkImageMemoryBarrier preClearBarrier = {
2372 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, 0, 0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
2373 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, 0, image_input.handle(), full_subresource_range,
2374 };
2375 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u,
2376 &preClearBarrier);
2377
2378 vk::CmdClearColorImage(m_commandBuffer->handle(), image_input.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &ccv, 1,
2379 &full_subresource_range);
2380
2381 const VkImageMemoryBarrier postClearBarrier = {
2382 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
2383 0,
2384 VK_ACCESS_TRANSFER_WRITE_BIT,
2385 VK_ACCESS_SHADER_READ_BIT,
2386 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
2387 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
2388 0,
2389 0,
2390 image_input.handle(),
2391 full_subresource_range,
2392 };
2393 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u, nullptr, 0u, nullptr,
2394 1u, &postClearBarrier);
2395
2396 m_renderPassBeginInfo.renderArea = {{0, 0}, {64, 64}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002397 m_renderPassBeginInfo.renderPass = rp.handle();
2398 m_renderPassBeginInfo.framebuffer = fb.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002399
2400 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2401 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
2402 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
2403 &g_pipe.descriptor_set_->set_, 0, nullptr);
2404
2405 // Positive test for ordering rules between load and input attachment usage
2406 m_errorMonitor->ExpectSuccess();
2407 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
2408
2409 // Positive test for store ordering vs. input attachment and dependency *to* external for layout transition
2410 m_commandBuffer->EndRenderPass();
2411 m_errorMonitor->VerifyNotFound();
2412
2413 // Catch a conflict with the input attachment final layout transition
2414 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
2415 vk::CmdClearColorImage(m_commandBuffer->handle(), image_input.handle(), VK_IMAGE_LAYOUT_GENERAL, &ccv, 1,
2416 &full_subresource_range);
2417 m_errorMonitor->VerifyFound();
2418}
2419
2420TEST_F(VkSyncValTest, SyncSubpassMultiDep) {
2421 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
2422 ASSERT_NO_FATAL_FAILURE(InitState());
2423 if (IsPlatform(kNexusPlayer)) {
2424 printf("%s This test should not run on Nexus Player\n", kSkipPrefix);
2425 return;
2426 }
2427
2428 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2429
2430 VkImageUsageFlags usage_color = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
2431 VkImageUsageFlags usage_input =
2432 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
2433 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
2434 VkImageObj image_color(m_device), image_input(m_device);
2435 auto image_ci = VkImageObj::ImageCreateInfo2D(64, 64, 1, 1, format, usage_input, VK_IMAGE_TILING_OPTIMAL);
2436 image_input.InitNoLayout(image_ci);
2437 image_ci.usage = usage_color;
2438 image_color.InitNoLayout(image_ci);
2439 VkImageView view_input = image_input.targetView(format);
2440 VkImageView view_color = image_color.targetView(format);
2441 VkImageView attachments[] = {view_color, view_input};
2442 VkImageSubresourceRange full_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
2443 VkImageSubresourceLayers mip_0_layer_0{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
2444 VkOffset3D image_zero{0, 0, 0};
2445 VkExtent3D image_size{64, 64, 1};
2446 VkImageCopy full_region{mip_0_layer_0, image_zero, mip_0_layer_0, image_zero, image_size};
2447
2448 const VkAttachmentDescription fbAttachment = {
2449 0u,
2450 format,
2451 VK_SAMPLE_COUNT_1_BIT,
2452 VK_ATTACHMENT_LOAD_OP_CLEAR,
2453 VK_ATTACHMENT_STORE_OP_STORE,
2454 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2455 VK_ATTACHMENT_STORE_OP_STORE,
2456 VK_IMAGE_LAYOUT_GENERAL,
2457 VK_IMAGE_LAYOUT_GENERAL,
2458 };
2459
2460 std::vector<VkAttachmentDescription> attachmentDescs;
2461 attachmentDescs.push_back(fbAttachment);
2462
2463 // Add it as a frame buffer attachment.
2464 const VkAttachmentDescription inputAttachment = {
2465 0u,
2466 format,
2467 VK_SAMPLE_COUNT_1_BIT,
2468 VK_ATTACHMENT_LOAD_OP_LOAD,
2469 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2470 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2471 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2472 VK_IMAGE_LAYOUT_GENERAL,
2473 VK_IMAGE_LAYOUT_GENERAL,
2474 };
2475 attachmentDescs.push_back(inputAttachment);
2476
2477 std::vector<VkAttachmentReference> inputAttachments;
2478 const VkAttachmentReference inputRef = {
2479 1u,
2480 VK_IMAGE_LAYOUT_GENERAL,
2481 };
2482 inputAttachments.push_back(inputRef);
2483
2484 const VkAttachmentReference colorRef = {
2485 0u,
2486 VK_IMAGE_LAYOUT_GENERAL,
2487 };
2488 const std::vector<VkAttachmentReference> colorAttachments(1u, colorRef);
2489
2490 const VkSubpassDescription subpass = {
2491 0u,
2492 VK_PIPELINE_BIND_POINT_GRAPHICS,
2493 static_cast<uint32_t>(inputAttachments.size()),
2494 inputAttachments.data(),
2495 static_cast<uint32_t>(colorAttachments.size()),
2496 colorAttachments.data(),
2497 0u,
2498 nullptr,
2499 0u,
2500 nullptr,
2501 };
2502 const std::vector<VkSubpassDescription> subpasses(1u, subpass);
2503
2504 std::vector<VkSubpassDependency> subpass_dep_postive;
2505 subpass_dep_postive.push_back({VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_TRANSFER_BIT,
2506 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2507 VK_DEPENDENCY_VIEW_LOCAL_BIT});
2508 subpass_dep_postive.push_back({VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_TRANSFER_BIT,
2509 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_TRANSFER_WRITE_BIT,
2510 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, VK_DEPENDENCY_VIEW_LOCAL_BIT});
2511 subpass_dep_postive.push_back({0, VK_SUBPASS_EXTERNAL, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2512 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2513 VK_ACCESS_TRANSFER_READ_BIT, VK_DEPENDENCY_VIEW_LOCAL_BIT});
2514 subpass_dep_postive.push_back({0, VK_SUBPASS_EXTERNAL, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2515 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2516 VK_ACCESS_TRANSFER_WRITE_BIT, VK_DEPENDENCY_VIEW_LOCAL_BIT});
2517
2518 VkRenderPassCreateInfo renderPassInfo = {
2519 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
2520 nullptr,
2521 0u,
2522 static_cast<uint32_t>(attachmentDescs.size()),
2523 attachmentDescs.data(),
2524 static_cast<uint32_t>(subpasses.size()),
2525 subpasses.data(),
2526 static_cast<uint32_t>(subpass_dep_postive.size()),
2527 subpass_dep_postive.data(),
2528 };
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002529 vk_testing::RenderPass rp_positive;
2530 rp_positive.init(*m_device, renderPassInfo);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002531
2532 std::vector<VkSubpassDependency> subpass_dep_negative;
2533 subpass_dep_negative.push_back({VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_TRANSFER_BIT,
2534 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2535 VK_DEPENDENCY_VIEW_LOCAL_BIT});
2536 // Show that the two barriers do *not* chain by breaking the positive barrier into two bits.
2537 subpass_dep_negative.push_back({VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_TRANSFER_BIT,
2538 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, 0,
2539 VK_DEPENDENCY_VIEW_LOCAL_BIT});
2540 subpass_dep_negative.push_back({VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2541 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
2542 VK_DEPENDENCY_VIEW_LOCAL_BIT});
2543
2544 renderPassInfo.dependencyCount = static_cast<uint32_t>(subpass_dep_negative.size());
2545 renderPassInfo.pDependencies = subpass_dep_negative.data();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002546 vk_testing::RenderPass rp_negative;
2547 rp_negative.init(*m_device, renderPassInfo);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002548
2549 // rp_postive and rp_negative should be compatible for the same fb object
2550 const VkFramebufferCreateInfo fbci = {
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002551 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, 0, 0u, rp_positive.handle(), 2u, attachments, 64, 64, 1u,
Jeremy Gebben170781d2020-11-19 16:21:21 -07002552 };
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002553 vk_testing::Framebuffer fb;
2554 fb.init(*m_device, fbci);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002555
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002556 vk_testing::Sampler sampler;
Jeremy Gebben170781d2020-11-19 16:21:21 -07002557 VkSamplerCreateInfo sampler_info = SafeSaneSamplerCreateInfo();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002558 sampler.init(*m_device, sampler_info);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002559
sfricke-samsung1c0b96a2021-07-08 22:24:09 -07002560 char const *fsSource = R"glsl(
2561 #version 450
2562 layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;
2563 void main() {
2564 vec4 color = subpassLoad(x);
2565 }
2566 )glsl";
Jeremy Gebben170781d2020-11-19 16:21:21 -07002567
2568 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
2569 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
2570
2571 CreatePipelineHelper g_pipe(*this);
2572 g_pipe.InitInfo();
2573 g_pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
2574 g_pipe.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002575 g_pipe.gp_ci_.renderPass = rp_positive.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002576 g_pipe.InitState();
2577 ASSERT_VK_SUCCESS(g_pipe.CreateGraphicsPipeline());
2578
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002579 g_pipe.descriptor_set_->WriteDescriptorImageInfo(0, view_input, sampler.handle(), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
Jeremy Gebben170781d2020-11-19 16:21:21 -07002580 g_pipe.descriptor_set_->UpdateDescriptorSets();
2581
2582 m_commandBuffer->begin();
2583 auto cb = m_commandBuffer->handle();
2584 VkClearColorValue ccv = {};
2585
2586 const VkImageMemoryBarrier xferDestBarrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
2587 nullptr,
2588 VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT,
2589 VK_ACCESS_TRANSFER_WRITE_BIT,
2590 VK_IMAGE_LAYOUT_GENERAL,
2591 VK_IMAGE_LAYOUT_GENERAL,
2592 VK_QUEUE_FAMILY_IGNORED,
2593 VK_QUEUE_FAMILY_IGNORED,
2594 VK_NULL_HANDLE,
2595 full_subresource_range};
2596 const VkImageMemoryBarrier xferDestToSrcBarrier = {
2597 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
2598 nullptr,
2599 VK_ACCESS_TRANSFER_WRITE_BIT,
2600 VK_ACCESS_TRANSFER_READ_BIT,
2601 VK_IMAGE_LAYOUT_GENERAL,
2602 VK_IMAGE_LAYOUT_GENERAL,
2603 VK_QUEUE_FAMILY_IGNORED,
2604 VK_QUEUE_FAMILY_IGNORED,
2605 VK_NULL_HANDLE,
2606 full_subresource_range,
2607 };
2608
2609 VkImageMemoryBarrier preClearBarrier = xferDestBarrier;
2610 preClearBarrier.image = image_color.handle();
2611
2612 VkImageMemoryBarrier preCopyBarriers[2] = {xferDestToSrcBarrier, xferDestBarrier};
2613 preCopyBarriers[0].image = image_color.handle();
2614 preCopyBarriers[1].image = image_input.handle();
2615 // Positive test for ordering rules between load and input attachment usage
2616 m_errorMonitor->ExpectSuccess();
2617
2618 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u,
2619 &preClearBarrier);
2620
2621 vk::CmdClearColorImage(m_commandBuffer->handle(), image_color.handle(), VK_IMAGE_LAYOUT_GENERAL, &ccv, 1,
2622 &full_subresource_range);
2623
2624 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 2u,
2625 preCopyBarriers);
2626
2627 vk::CmdCopyImage(m_commandBuffer->handle(), image_color.handle(), VK_IMAGE_LAYOUT_GENERAL, image_input.handle(),
2628 VK_IMAGE_LAYOUT_GENERAL, 1u, &full_region);
2629
2630 // No post copy image barrier, we are testing the subpass dependencies
2631
2632 m_renderPassBeginInfo.renderArea = {{0, 0}, {64, 64}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002633 m_renderPassBeginInfo.renderPass = rp_positive.handle();
2634 m_renderPassBeginInfo.framebuffer = fb.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002635
2636 // Postive renderpass multidependency test
2637 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2638 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
2639 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
2640 &g_pipe.descriptor_set_->set_, 0, nullptr);
2641
2642 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
2643
2644 // Positive test for store ordering vs. input attachment and dependency *to* external for layout transition
2645 m_commandBuffer->EndRenderPass();
2646 // m_errorMonitor->VerifyNotFound();
2647
2648 vk::CmdCopyImage(m_commandBuffer->handle(), image_color.handle(), VK_IMAGE_LAYOUT_GENERAL, image_input.handle(),
2649 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &full_region);
2650 m_errorMonitor->VerifyNotFound();
2651
2652 m_renderPassBeginInfo.renderArea = {{0, 0}, {64, 64}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002653 m_renderPassBeginInfo.renderPass = rp_negative.handle();
2654 m_renderPassBeginInfo.framebuffer = fb.handle();
Jeremy Gebben170781d2020-11-19 16:21:21 -07002655
2656 // Postive renderpass multidependency test, will fail IFF the dependencies are acting indepently.
2657 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "SYNC-HAZARD-READ_AFTER_WRITE");
2658 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2659 m_errorMonitor->VerifyFound();
2660}
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002661
2662TEST_F(VkSyncValTest, RenderPassAsyncHazard) {
2663 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
2664 ASSERT_NO_FATAL_FAILURE(InitState());
2665
Nathaniel Cesariof9cd1a82021-07-24 08:48:55 -06002666 if (IsPlatform(kPixel3) || IsPlatform(kPixel3aXL)) {
2667 printf("%s Temporarily disabling on Pixel 3 and Pixel 3a XL due to driver crash\n", kSkipPrefix);
2668 return;
2669 }
2670
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002671 // overall set up:
2672 // subpass 0:
2673 // write image 0
2674 // subpass 1:
2675 // read image 0
2676 // write image 1
2677 // subpass 2:
2678 // read image 0
2679 // write image 2
2680 // subpass 3:
2681 // read image 0
2682 // write image 3
2683 //
2684 // subpasses 1 & 2 can run in parallel but both should depend on 0
2685 // subpass 3 must run after 1 & 2 because otherwise the store operation will
2686 // race with the reads in the other subpasses.
2687
2688 constexpr VkFormat kFormat = VK_FORMAT_R8G8B8A8_UNORM;
2689 constexpr uint32_t kWidth = 32, kHeight = 32;
2690 constexpr uint32_t kNumImages = 4;
2691
2692 VkImageCreateInfo src_img_info = {};
2693 src_img_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2694 src_img_info.pNext = NULL;
2695 src_img_info.flags = 0;
2696 src_img_info.imageType = VK_IMAGE_TYPE_2D;
2697 src_img_info.format = kFormat;
2698 src_img_info.extent = {kWidth, kHeight, 1};
2699 src_img_info.mipLevels = 1;
2700 src_img_info.arrayLayers = 1;
2701 src_img_info.samples = VK_SAMPLE_COUNT_2_BIT;
2702 src_img_info.tiling = VK_IMAGE_TILING_OPTIMAL;
2703 src_img_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
2704 src_img_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2705 src_img_info.queueFamilyIndexCount = 0;
2706 src_img_info.pQueueFamilyIndices = nullptr;
2707 src_img_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2708
2709 VkImageCreateInfo dst_img_info = {};
2710 dst_img_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2711 dst_img_info.pNext = nullptr;
2712 dst_img_info.flags = 0;
2713 dst_img_info.imageType = VK_IMAGE_TYPE_2D;
2714 dst_img_info.format = kFormat;
2715 dst_img_info.extent = {kWidth, kHeight, 1};
2716 dst_img_info.mipLevels = 1;
2717 dst_img_info.arrayLayers = 1;
2718 dst_img_info.samples = VK_SAMPLE_COUNT_1_BIT;
2719 dst_img_info.tiling = VK_IMAGE_TILING_OPTIMAL;
2720 dst_img_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
2721 dst_img_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2722 dst_img_info.queueFamilyIndexCount = 0;
2723 dst_img_info.pQueueFamilyIndices = nullptr;
2724 dst_img_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2725
2726 std::vector<std::unique_ptr<VkImageObj>> images;
2727 for (uint32_t i = 0; i < kNumImages; i++) {
2728 images.emplace_back(new VkImageObj(m_device));
2729 }
2730 images[0]->Init(src_img_info);
2731 for (uint32_t i = 1; i < images.size(); i++) {
2732 images[i]->Init(dst_img_info);
2733 }
2734
2735 std::array<VkImageView, kNumImages> attachments{};
2736 std::array<VkAttachmentDescription, kNumImages> attachment_descriptions{};
2737 std::array<VkAttachmentReference, kNumImages> color_refs{};
2738 std::array<VkImageMemoryBarrier, kNumImages> img_barriers{};
2739
2740 for (uint32_t i = 0; i < attachments.size(); i++) {
2741 attachments[i] = images[i]->targetView(kFormat);
2742 attachment_descriptions[i] = {};
2743 attachment_descriptions[i].flags = 0;
2744 attachment_descriptions[i].format = kFormat;
2745 attachment_descriptions[i].samples = VK_SAMPLE_COUNT_1_BIT;
2746 attachment_descriptions[i].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
2747 attachment_descriptions[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
2748 attachment_descriptions[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
2749 attachment_descriptions[i].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
2750 attachment_descriptions[i].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
2751 attachment_descriptions[i].finalLayout =
2752 (i == 0) ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
2753
2754 color_refs[i] = {i, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
2755
2756 img_barriers[i].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
2757 img_barriers[i].srcAccessMask = 0;
2758 img_barriers[i].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
2759 img_barriers[i].oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2760 img_barriers[i].newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
2761 img_barriers[i].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
2762 img_barriers[i].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
2763 img_barriers[i].image = images[i]->handle();
2764 img_barriers[i].subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS};
2765 }
2766
2767 const VkAttachmentReference input_ref{0u, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};
2768
2769 std::array<std::array<uint32_t, 2>, kNumImages - 1> preserve_subpass{{{2, 3}, {1, 3}, {1, 2}}};
2770
2771 std::array<VkSubpassDescription, kNumImages> subpasses{};
2772
2773 subpasses[0].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
2774 subpasses[0].inputAttachmentCount = 0;
2775 subpasses[0].pInputAttachments = nullptr;
2776 subpasses[0].colorAttachmentCount = 1;
2777 subpasses[0].pColorAttachments = &color_refs[0];
2778
2779 for (uint32_t i = 1; i < subpasses.size(); i++) {
2780 subpasses[i].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
2781 subpasses[i].inputAttachmentCount = 1;
2782 subpasses[i].pInputAttachments = &input_ref;
2783 subpasses[i].colorAttachmentCount = 1;
2784 subpasses[i].pColorAttachments = &color_refs[1];
2785 subpasses[i].preserveAttachmentCount = preserve_subpass[i - 1].size();
2786 subpasses[i].pPreserveAttachments = preserve_subpass[i - 1].data();
2787 }
2788
2789 VkRenderPassCreateInfo renderpass_info = {};
2790 renderpass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
2791 renderpass_info.pNext = nullptr;
2792 renderpass_info.flags = 0;
2793 renderpass_info.attachmentCount = attachment_descriptions.size();
2794 renderpass_info.pAttachments = attachment_descriptions.data();
2795 renderpass_info.subpassCount = subpasses.size();
2796 renderpass_info.pSubpasses = subpasses.data();
2797 renderpass_info.dependencyCount = 0;
2798 renderpass_info.pDependencies = nullptr;
2799
2800 VkFramebufferCreateInfo fbci = {};
2801 fbci.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
2802 fbci.pNext = nullptr;
2803 fbci.flags = 0;
2804 fbci.attachmentCount = attachments.size();
2805 fbci.pAttachments = attachments.data();
2806 fbci.width = kWidth;
2807 fbci.height = kHeight;
2808 fbci.layers = 1;
2809
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002810 vk_testing::Sampler sampler;
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002811 VkSamplerCreateInfo sampler_info = SafeSaneSamplerCreateInfo();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002812 sampler.init(*m_device, sampler_info);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002813
sfricke-samsung1c0b96a2021-07-08 22:24:09 -07002814 char const *fsSource = R"glsl(
2815 #version 450
2816 layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;
2817 void main() {
2818 vec4 color = subpassLoad(x);
2819 }
2820 )glsl";
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002821
2822 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
2823 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
2824
2825 VkClearValue clear = {};
2826 clear.color = m_clear_color;
Tony-LunarG73f37032021-06-07 11:47:03 -06002827 std::array<VkClearValue, 4> clear_values = {{clear, clear, clear, clear}};
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002828
2829 // run the renderpass with no dependencies
2830 {
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002831 vk_testing::RenderPass rp;
2832 vk_testing::Framebuffer fb;
2833 rp.init(*m_device, renderpass_info);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002834
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002835 fbci.renderPass = rp.handle();
2836 fb.init(*m_device, fbci);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002837
2838 CreatePipelineHelper g_pipe_0(*this);
2839 g_pipe_0.InitInfo();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002840 g_pipe_0.gp_ci_.renderPass = rp.handle();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002841 g_pipe_0.InitState();
2842 ASSERT_VK_SUCCESS(g_pipe_0.CreateGraphicsPipeline());
2843
2844 CreatePipelineHelper g_pipe_12(*this);
2845 g_pipe_12.InitInfo();
2846 g_pipe_12.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
2847 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 -06002848 g_pipe_12.gp_ci_.renderPass = rp.handle();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002849 g_pipe_12.InitState();
2850 ASSERT_VK_SUCCESS(g_pipe_12.CreateGraphicsPipeline());
2851
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002852 g_pipe_12.descriptor_set_->WriteDescriptorImageInfo(0, attachments[0], sampler.handle(), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002853 g_pipe_12.descriptor_set_->UpdateDescriptorSets();
2854
2855 m_commandBuffer->begin();
2856
2857 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
2858 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0, nullptr, img_barriers.size(),
2859 img_barriers.data());
2860
2861 m_renderPassBeginInfo.renderArea = {{0, 0}, {16, 16}};
2862 m_renderPassBeginInfo.pClearValues = clear_values.data();
2863 m_renderPassBeginInfo.clearValueCount = clear_values.size();
2864
2865 m_renderPassBeginInfo.renderArea = {{0, 0}, {kWidth, kHeight}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002866 m_renderPassBeginInfo.renderPass = rp.handle();
2867 m_renderPassBeginInfo.framebuffer = fb.handle();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002868
2869 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
2870 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_);
2871 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_layout_.handle(), 0,
2872 1, &g_pipe_0.descriptor_set_->set_, 0, NULL);
2873
2874 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
2875
2876 for (uint32_t i = 1; i < subpasses.size(); i++) {
2877 vk::CmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
2878 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_12.pipeline_);
2879 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS,
2880 g_pipe_12.pipeline_layout_.handle(), 0, 1, &g_pipe_12.descriptor_set_->set_, 0, NULL);
2881
2882 // we're racing the writes from subpass 0 with our shader reads
2883 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ-RACING-WRITE");
2884 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
2885 m_errorMonitor->VerifyFound();
2886 }
2887
2888 // we should get an error from async checking in both subpasses 2 & 3
2889 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE-RACING-WRITE");
2890 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE-RACING-WRITE");
2891 vk::CmdEndRenderPass(m_commandBuffer->handle());
2892 m_errorMonitor->VerifyFound();
2893
2894 m_commandBuffer->end();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002895 }
2896
2897 // add dependencies from subpass 0 to the others, which are necessary but not sufficient
2898 std::vector<VkSubpassDependency> subpass_dependencies;
2899 for (uint32_t i = 1; i < subpasses.size(); i++) {
2900 VkSubpassDependency dep{0,
2901 i,
2902 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2903 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
2904 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2905 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
2906 0};
2907 subpass_dependencies.push_back(dep);
2908 }
2909 renderpass_info.dependencyCount = subpass_dependencies.size();
2910 renderpass_info.pDependencies = subpass_dependencies.data();
2911
2912 {
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002913 vk_testing::RenderPass rp;
2914 vk_testing::Framebuffer fb;
2915 rp.init(*m_device, renderpass_info);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002916
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002917 fbci.renderPass = rp.handle();
2918 fb.init(*m_device, fbci);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002919
2920 CreatePipelineHelper g_pipe_0(*this);
2921 g_pipe_0.InitInfo();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002922 g_pipe_0.gp_ci_.renderPass = rp.handle();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002923 g_pipe_0.InitState();
2924 ASSERT_VK_SUCCESS(g_pipe_0.CreateGraphicsPipeline());
2925
2926 CreatePipelineHelper g_pipe_12(*this);
2927 g_pipe_12.InitInfo();
2928 g_pipe_12.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
2929 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 -06002930 g_pipe_12.gp_ci_.renderPass = rp.handle();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002931 g_pipe_12.InitState();
2932 ASSERT_VK_SUCCESS(g_pipe_12.CreateGraphicsPipeline());
2933
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002934 g_pipe_12.descriptor_set_->WriteDescriptorImageInfo(0, attachments[0], sampler.handle(), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002935 g_pipe_12.descriptor_set_->UpdateDescriptorSets();
2936
2937 m_commandBuffer->begin();
2938
2939 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
2940 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0, nullptr, img_barriers.size(),
2941 img_barriers.data());
2942
2943 m_renderPassBeginInfo.renderArea = {{0, 0}, {16, 16}};
2944 m_renderPassBeginInfo.pClearValues = clear_values.data();
2945 m_renderPassBeginInfo.clearValueCount = clear_values.size();
2946
2947 m_renderPassBeginInfo.renderArea = {{0, 0}, {kWidth, kHeight}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002948 m_renderPassBeginInfo.renderPass = rp.handle();
2949 m_renderPassBeginInfo.framebuffer = fb.handle();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002950
2951 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
2952 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_);
2953 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_layout_.handle(), 0,
2954 1, &g_pipe_0.descriptor_set_->set_, 0, NULL);
2955
2956 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
2957
2958 m_errorMonitor->ExpectSuccess();
2959 for (uint32_t i = 1; i < subpasses.size(); i++) {
2960 vk::CmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
2961 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_12.pipeline_);
2962 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS,
2963 g_pipe_12.pipeline_layout_.handle(), 0, 1, &g_pipe_12.descriptor_set_->set_, 0, NULL);
2964 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
2965 }
2966 m_errorMonitor->VerifyNotFound();
2967 // expect this error because 2 subpasses could try to do the store operation
2968 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE-RACING-WRITE");
2969 // ... and this one because the store could happen during a shader read from another subpass
2970 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE-RACING-READ");
2971 vk::CmdEndRenderPass(m_commandBuffer->handle());
2972 m_errorMonitor->VerifyFound();
2973
2974 m_commandBuffer->end();
2975
2976 m_errorMonitor->VerifyFound();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002977 }
2978
2979 // try again with correct dependencies to make subpass 3 depend on 1 & 2
2980 for (uint32_t i = 1; i < (subpasses.size() - 1); i++) {
2981 VkSubpassDependency dep{i,
2982 static_cast<uint32_t>(subpasses.size() - 1),
2983 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2984 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
2985 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2986 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
2987 0};
2988 subpass_dependencies.push_back(dep);
2989 }
2990 renderpass_info.dependencyCount = subpass_dependencies.size();
2991 renderpass_info.pDependencies = subpass_dependencies.data();
2992 {
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002993 vk_testing::RenderPass rp;
2994 vk_testing::Framebuffer fb;
2995 rp.init(*m_device, renderpass_info);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002996
Jeremy Gebben18ac1052021-08-12 11:07:32 -06002997 fbci.renderPass = rp.handle();
2998 fb.init(*m_device, fbci);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002999
3000 CreatePipelineHelper g_pipe_0(*this);
3001 g_pipe_0.InitInfo();
Jeremy Gebben18ac1052021-08-12 11:07:32 -06003002 g_pipe_0.gp_ci_.renderPass = rp.handle();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003003 g_pipe_0.InitState();
3004 ASSERT_VK_SUCCESS(g_pipe_0.CreateGraphicsPipeline());
3005
3006 CreatePipelineHelper g_pipe_12(*this);
3007 g_pipe_12.InitInfo();
3008 g_pipe_12.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
3009 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 -06003010 g_pipe_12.gp_ci_.renderPass = rp.handle();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003011 g_pipe_12.InitState();
3012 ASSERT_VK_SUCCESS(g_pipe_12.CreateGraphicsPipeline());
3013
Jeremy Gebben18ac1052021-08-12 11:07:32 -06003014 g_pipe_12.descriptor_set_->WriteDescriptorImageInfo(0, attachments[0], sampler.handle(), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003015 g_pipe_12.descriptor_set_->UpdateDescriptorSets();
3016
3017 m_errorMonitor->ExpectSuccess();
3018 m_commandBuffer->begin();
3019 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
3020 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0, nullptr, img_barriers.size(),
3021 img_barriers.data());
3022
3023 m_renderPassBeginInfo.renderArea = {{0, 0}, {16, 16}};
3024 m_renderPassBeginInfo.pClearValues = clear_values.data();
3025 m_renderPassBeginInfo.clearValueCount = clear_values.size();
3026
3027 m_renderPassBeginInfo.renderArea = {{0, 0}, {kWidth, kHeight}};
Jeremy Gebben18ac1052021-08-12 11:07:32 -06003028 m_renderPassBeginInfo.renderPass = rp.handle();
3029 m_renderPassBeginInfo.framebuffer = fb.handle();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003030
3031 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
3032 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_);
3033 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_layout_.handle(), 0,
3034 1, &g_pipe_0.descriptor_set_->set_, 0, NULL);
3035
3036 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
3037
3038 for (uint32_t i = 1; i < subpasses.size(); i++) {
3039 vk::CmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
3040 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_12.pipeline_);
3041 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS,
3042 g_pipe_12.pipeline_layout_.handle(), 0, 1, &g_pipe_12.descriptor_set_->set_, 0, NULL);
3043 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
3044 }
3045
3046 vk::CmdEndRenderPass(m_commandBuffer->handle());
3047
3048 m_commandBuffer->end();
3049
3050 m_errorMonitor->VerifyNotFound();
Jeremy Gebben6feafd42020-11-30 09:11:38 -07003051 }
3052}
John Zulauf025ee442020-12-15 11:44:19 -07003053
3054TEST_F(VkSyncValTest, SyncEventsBufferCopy) {
3055 TEST_DESCRIPTION("Check Set/Wait protection for a variety of use cases using buffer copies");
3056 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
3057 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
3058
3059 VkBufferObj buffer_a;
3060 VkBufferObj buffer_b;
3061 VkBufferObj buffer_c;
3062 VkMemoryPropertyFlags mem_prop = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
3063 buffer_a.init_as_src_and_dst(*m_device, 256, mem_prop);
3064 buffer_b.init_as_src_and_dst(*m_device, 256, mem_prop);
3065 buffer_c.init_as_src_and_dst(*m_device, 256, mem_prop);
3066
3067 VkBufferCopy region = {0, 0, 256};
3068 VkBufferCopy front2front = {0, 0, 128};
3069 VkBufferCopy front2back = {0, 128, 128};
3070 VkBufferCopy back2back = {128, 128, 128};
3071
3072 VkEventObj event;
3073 event.init(*m_device, VkEventObj::create_info(0));
3074 VkEvent event_handle = event.handle();
3075
3076 auto cb = m_commandBuffer->handle();
3077 m_commandBuffer->begin();
3078
3079 // Copy after set for WAR (note we are writing to the back half of c but only reading from the front
3080 m_errorMonitor->ExpectSuccess();
3081 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &region);
3082 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3083 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_c.handle(), 1, &back2back);
3084 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3085 nullptr, 0, nullptr);
3086 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &front2front);
3087 m_errorMonitor->VerifyNotFound();
3088 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
3089 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &front2back);
3090 m_errorMonitor->VerifyFound();
3091 m_commandBuffer->end();
3092
3093 // WAR prevented
3094 m_commandBuffer->reset();
3095 m_commandBuffer->begin();
3096 m_errorMonitor->ExpectSuccess();
3097 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &region);
3098 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3099 // Just protect against WAR, only need a sync barrier.
3100 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3101 nullptr, 0, nullptr);
3102 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &region);
3103 m_errorMonitor->VerifyNotFound();
3104
3105 // Wait shouldn't prevent this WAW though, as it's only a synchronization barrier
3106 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
3107 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_b.handle(), 1, &region);
3108 m_errorMonitor->VerifyFound();
3109 m_commandBuffer->end();
3110
3111 // Prevent WAR and WAW
3112 m_commandBuffer->reset();
3113 m_commandBuffer->begin();
3114 m_errorMonitor->ExpectSuccess();
3115 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &region);
3116 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07003117 auto mem_barrier_waw = LvlInitStruct<VkMemoryBarrier>();
John Zulauf025ee442020-12-15 11:44:19 -07003118 mem_barrier_waw.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3119 mem_barrier_waw.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3120 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 1,
3121 &mem_barrier_waw, 0, nullptr, 0, nullptr);
3122 // The WAW should be safe (on a memory barrier)
3123 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_b.handle(), 1, &region);
3124 // The WAR should also be safe (on a sync barrier)
3125 vk::CmdCopyBuffer(cb, buffer_c.handle(), buffer_a.handle(), 1, &region);
3126 m_errorMonitor->VerifyNotFound();
3127 m_commandBuffer->end();
3128
3129 // Barrier range check for WAW
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07003130 auto buffer_barrier_front_waw = LvlInitStruct<VkBufferMemoryBarrier>();
John Zulauf025ee442020-12-15 11:44:19 -07003131 buffer_barrier_front_waw.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3132 buffer_barrier_front_waw.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3133 buffer_barrier_front_waw.buffer = buffer_b.handle();
3134 buffer_barrier_front_waw.offset = front2front.dstOffset;
3135 buffer_barrier_front_waw.size = front2front.size;
3136
3137 // Front safe, back WAW
3138 m_commandBuffer->reset();
3139 m_commandBuffer->begin();
3140 m_errorMonitor->ExpectSuccess();
3141 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &region);
3142 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3143 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 1,
3144 &buffer_barrier_front_waw, 0, nullptr);
3145 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &front2front);
3146 m_errorMonitor->VerifyNotFound();
3147 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
3148 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &back2back);
3149 m_errorMonitor->VerifyFound();
3150 m_commandBuffer->end();
3151}
3152
3153TEST_F(VkSyncValTest, SyncEventsCopyImageHazards) {
3154 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
3155 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
3156
3157 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3158 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
3159 VkImageObj image_a(m_device);
3160 auto image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 2, format, usage, VK_IMAGE_TILING_OPTIMAL);
3161 image_a.Init(image_ci);
3162 ASSERT_TRUE(image_a.initialized());
3163
3164 VkImageObj image_b(m_device);
3165 image_b.Init(image_ci);
3166 ASSERT_TRUE(image_b.initialized());
3167
3168 VkImageObj image_c(m_device);
3169 image_c.Init(image_ci);
3170 ASSERT_TRUE(image_c.initialized());
3171
3172 VkEventObj event;
3173 event.init(*m_device, VkEventObj::create_info(0));
3174 VkEvent event_handle = event.handle();
3175
3176 VkImageSubresourceLayers layers_all{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 2};
3177 VkImageSubresourceLayers layers_0{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
3178 VkImageSubresourceLayers layers_1{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1};
3179 VkImageSubresourceRange layers_0_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
3180 VkOffset3D zero_offset{0, 0, 0};
3181 VkOffset3D half_offset{64, 64, 0};
3182 VkExtent3D full_extent{128, 128, 1}; // <-- image type is 2D
3183 VkExtent3D half_extent{64, 64, 1}; // <-- image type is 2D
3184
3185 VkImageCopy full_region = {layers_all, zero_offset, layers_all, zero_offset, full_extent};
3186 VkImageCopy region_0_to_0 = {layers_0, zero_offset, layers_0, zero_offset, full_extent};
3187 VkImageCopy region_1_to_1 = {layers_1, zero_offset, layers_1, zero_offset, full_extent};
3188 VkImageCopy region_0_q0toq0 = {layers_0, zero_offset, layers_0, zero_offset, half_extent};
3189 VkImageCopy region_0_q0toq3 = {layers_0, zero_offset, layers_0, half_offset, half_extent};
3190 VkImageCopy region_0_q3toq3 = {layers_0, half_offset, layers_0, half_offset, half_extent};
3191
3192 auto cb = m_commandBuffer->handle();
3193 auto copy_general = [cb](const VkImageObj &from, const VkImageObj &to, const VkImageCopy &region) {
3194 vk::CmdCopyImage(cb, from.handle(), VK_IMAGE_LAYOUT_GENERAL, to.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
3195 };
3196
3197 auto set_layouts = [this, &image_a, &image_b, &image_c]() {
3198 image_c.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
3199 image_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
3200 image_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
3201 };
3202
John Zulaufdd462092020-12-18 12:00:35 -07003203 // Scope check. One access in, one access not
John Zulauf025ee442020-12-15 11:44:19 -07003204 m_commandBuffer->begin();
3205 set_layouts();
3206 m_errorMonitor->ExpectSuccess();
3207 copy_general(image_a, image_b, full_region);
3208 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3209 copy_general(image_a, image_c, region_0_q3toq3);
3210 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3211 nullptr, 0, nullptr);
3212 copy_general(image_c, image_a, region_0_q0toq0);
3213 m_errorMonitor->VerifyNotFound();
3214 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
3215 copy_general(image_c, image_a, region_0_q0toq3);
3216 m_errorMonitor->VerifyFound();
3217 m_commandBuffer->end();
3218
3219 // WAR prevented
3220 m_commandBuffer->reset();
3221 m_commandBuffer->begin();
3222 set_layouts();
3223 m_errorMonitor->ExpectSuccess();
3224 copy_general(image_a, image_b, full_region);
3225 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3226 // Just protect against WAR, only need a sync barrier.
3227 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3228 nullptr, 0, nullptr);
3229 copy_general(image_c, image_a, full_region);
3230 m_errorMonitor->VerifyNotFound();
3231
3232 // Wait shouldn't prevent this WAW though, as it's only a synchronization barrier
3233 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
3234 copy_general(image_c, image_b, full_region);
3235 m_errorMonitor->VerifyFound();
3236 m_commandBuffer->end();
3237
3238 // Prevent WAR and WAW
3239 m_commandBuffer->reset();
3240 m_commandBuffer->begin();
3241 m_errorMonitor->ExpectSuccess();
3242 set_layouts();
3243 copy_general(image_a, image_b, full_region);
3244 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07003245 auto mem_barrier_waw = LvlInitStruct<VkMemoryBarrier>();
John Zulauf025ee442020-12-15 11:44:19 -07003246 mem_barrier_waw.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3247 mem_barrier_waw.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3248 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 1,
3249 &mem_barrier_waw, 0, nullptr, 0, nullptr);
3250 // The WAW should be safe (on a memory barrier)
3251 copy_general(image_c, image_b, full_region);
3252 // The WAR should also be safe (on a sync barrier)
3253 copy_general(image_c, image_a, full_region);
3254 m_errorMonitor->VerifyNotFound();
3255 m_commandBuffer->end();
3256
3257 // Barrier range check for WAW
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07003258 auto image_barrier_region0_waw = LvlInitStruct<VkImageMemoryBarrier>();
John Zulauf025ee442020-12-15 11:44:19 -07003259 image_barrier_region0_waw.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3260 image_barrier_region0_waw.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3261 image_barrier_region0_waw.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
3262 image_barrier_region0_waw.newLayout = VK_IMAGE_LAYOUT_GENERAL;
3263 image_barrier_region0_waw.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
3264 image_barrier_region0_waw.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
3265 image_barrier_region0_waw.image = image_b.handle();
3266 image_barrier_region0_waw.subresourceRange = layers_0_subresource_range;
3267
3268 // Region 0 safe, back WAW
3269 m_commandBuffer->reset();
3270 m_commandBuffer->begin();
3271 set_layouts();
3272 m_errorMonitor->ExpectSuccess();
3273 copy_general(image_a, image_b, full_region);
3274 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3275 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3276 nullptr, 1, &image_barrier_region0_waw);
3277 copy_general(image_a, image_b, region_0_to_0);
3278 m_errorMonitor->VerifyNotFound();
3279 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
3280 copy_general(image_a, image_b, region_1_to_1);
3281 m_errorMonitor->VerifyFound();
3282 m_commandBuffer->end();
3283}
John Zulauf4b5e4632020-12-15 11:48:59 -07003284
3285TEST_F(VkSyncValTest, SyncEventsCommandHazards) {
3286 TEST_DESCRIPTION("Check Set/Reset/Wait command hazard checking");
3287 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
3288 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
3289
3290 VkEventObj event;
3291 event.init(*m_device, VkEventObj::create_info(0));
3292
3293 const VkEvent event_handle = event.handle();
3294
3295 m_commandBuffer->begin();
3296 m_errorMonitor->ExpectSuccess();
3297 m_commandBuffer->ResetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3298 m_errorMonitor->VerifyNotFound();
3299
John Zulauf4edde622021-02-15 08:54:50 -07003300 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdResetEvent-event-03834");
John Zulauf4b5e4632020-12-15 11:48:59 -07003301 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdWaitEvents-srcStageMask-01158");
3302 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3303 nullptr, 0, nullptr);
3304 m_errorMonitor->VerifyFound();
3305 m_errorMonitor->ExpectSuccess();
3306 m_commandBuffer->end();
3307
3308 m_commandBuffer->begin();
3309 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3310 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, nullptr,
3311 0, nullptr, 0, nullptr);
3312 m_errorMonitor->VerifyNotFound();
3313 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-vkCmdResetEvent-missingbarrier-wait");
3314 m_commandBuffer->ResetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3315 m_errorMonitor->VerifyFound();
3316 m_errorMonitor->ExpectSuccess();
3317 m_commandBuffer->end();
3318
3319 m_commandBuffer->begin();
3320 m_commandBuffer->ResetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3321 m_errorMonitor->VerifyNotFound();
3322 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-vkCmdSetEvent-missingbarrier-reset");
3323 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3324 m_errorMonitor->VerifyFound();
3325
3326 m_errorMonitor->ExpectSuccess();
3327 m_commandBuffer->PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0U, 0, nullptr, 0,
3328 nullptr, 0, nullptr);
3329 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3330 m_commandBuffer->WaitEvents(1, &event_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, 0,
3331 nullptr, 0, nullptr);
3332 m_commandBuffer->ResetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3333 m_commandBuffer->PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0U, 0, nullptr, 0,
3334 nullptr, 0, nullptr);
3335 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3336 m_errorMonitor->VerifyNotFound();
3337
3338 // Need a barrier between set and a reset
3339 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-vkCmdResetEvent-missingbarrier-set");
3340 m_commandBuffer->ResetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3341 m_errorMonitor->VerifyFound();
3342 m_errorMonitor->ExpectSuccess();
3343 m_commandBuffer->end();
3344
3345 m_commandBuffer->begin();
3346 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3347 m_errorMonitor->VerifyNotFound();
3348 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-vkCmdSetEvent-missingbarrier-set");
3349 m_commandBuffer->SetEvent(event, VK_PIPELINE_STAGE_TRANSFER_BIT);
3350 m_errorMonitor->VerifyFound();
3351
3352 m_commandBuffer->end();
3353}
ziga-lunarg3a16ff12021-07-30 12:09:55 +02003354
3355TEST_F(VkLayerTest, CmdWaitEvents2KHRUsedButSynchronizaion2Disabled) {
3356 TEST_DESCRIPTION("Using CmdWaitEvents2KHR when synchronization2 is not enabled");
3357
3358 ASSERT_NO_FATAL_FAILURE(InitFramework());
3359 if (!DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME)) {
3360 printf("%s Synchronization2 not supported, skipping test\n", kSkipPrefix);
3361 return;
3362 }
3363 if (!DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
3364 printf("%s %s not supported, skipping test\n", kSkipPrefix, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
3365 return;
3366 }
3367 m_device_extension_names.push_back(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME);
3368 m_device_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
3369 InitState();
3370
3371 auto fpCmdWaitEvents2KHR = (PFN_vkCmdWaitEvents2KHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdWaitEvents2KHR");
3372
3373 VkEventObj event;
3374 event.init(*m_device, VkEventObj::create_info(0));
3375 VkEvent event_handle = event.handle();
3376
3377 VkDependencyInfoKHR dependency_info = LvlInitStruct<VkDependencyInfoKHR>();
3378
3379 m_commandBuffer->begin();
3380 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdWaitEvents2KHR-synchronization2-03836");
3381 fpCmdWaitEvents2KHR(m_commandBuffer->handle(), 1, &event_handle, &dependency_info);
3382 m_errorMonitor->VerifyFound();
3383 m_commandBuffer->end();
3384}
ziga-lunarg15f450d2021-08-26 23:10:05 +02003385
3386TEST_F(VkLayerTest, Sync2FeatureDisabled) {
3387 TEST_DESCRIPTION("Call sync2 functions when the feature is disabled");
3388
3389 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
3390 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
3391 } else {
3392 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
3393 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
3394 return;
3395 }
3396 ASSERT_NO_FATAL_FAILURE(InitFramework());
3397 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME)) {
3398 m_device_extension_names.push_back(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME);
3399 } else {
3400 printf("%s Synchronization2 not supported, skipping test\n", kSkipPrefix);
3401 return;
3402 }
3403
3404 ASSERT_NO_FATAL_FAILURE(InitState());
3405
3406 VkPhysicalDeviceSynchronization2FeaturesKHR synchronization2 = LvlInitStruct<VkPhysicalDeviceSynchronization2FeaturesKHR>();
3407 synchronization2.synchronization2 = VK_FALSE; // Invalid
3408 auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&synchronization2);
3409 vk::GetPhysicalDeviceFeatures2(gpu(), &features2);
3410
3411 auto vkCmdPipelineBarrier2KHR =
3412 (PFN_vkCmdPipelineBarrier2KHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdPipelineBarrier2KHR");
3413 auto vkCmdResetEvent2KHR = (PFN_vkCmdResetEvent2KHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdResetEvent2KHR");
3414 auto vkCmdSetEvent2KHR = (PFN_vkCmdSetEvent2KHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetEvent2KHR");
3415 auto vkCmdWriteTimestamp2KHR =
3416 (PFN_vkCmdWriteTimestamp2KHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdWriteTimestamp2KHR");
3417
3418 bool timestamp = false;
3419
3420 uint32_t queue_count;
3421 vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_count, NULL);
3422 std::vector<VkQueueFamilyProperties> queue_props(queue_count);
3423 vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_count, queue_props.data());
3424 if (queue_props[m_device->graphics_queue_node_index_].timestampValidBits > 0) {
3425 timestamp = true;
3426 }
3427
3428 m_commandBuffer->begin();
3429
3430 VkDependencyInfoKHR dependency_info = LvlInitStruct<VkDependencyInfoKHR>();
3431
3432 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPipelineBarrier2KHR-synchronization2-03848");
3433 vkCmdPipelineBarrier2KHR(m_commandBuffer->handle(), &dependency_info);
3434 m_errorMonitor->VerifyFound();
3435
3436 VkEventCreateInfo eci = LvlInitStruct<VkEventCreateInfo>();
3437 vk_testing::Event event;
3438 event.init(*m_device, eci);
3439
3440 VkPipelineStageFlagBits2KHR stage = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR;
3441
3442 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResetEvent2KHR-synchronization2-03829");
3443 vkCmdResetEvent2KHR(m_commandBuffer->handle(), event.handle(), stage);
3444 m_errorMonitor->VerifyFound();
3445
3446 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetEvent2KHR-synchronization2-03824");
3447 vkCmdSetEvent2KHR(m_commandBuffer->handle(), event.handle(), &dependency_info);
3448 m_errorMonitor->VerifyFound();
3449
3450 if (timestamp) {
3451 VkQueryPoolCreateInfo qpci = LvlInitStruct<VkQueryPoolCreateInfo>();
3452 qpci.queryType = VK_QUERY_TYPE_TIMESTAMP;
3453 qpci.queryCount = 1;
3454
3455 vk_testing::QueryPool query_pool;
3456 query_pool.init(*m_device, qpci);
3457
3458 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdWriteTimestamp2KHR-synchronization2-03858");
3459 vkCmdWriteTimestamp2KHR(m_commandBuffer->handle(), stage, query_pool.handle(), 0);
3460 m_errorMonitor->VerifyFound();
3461 }
3462
3463 m_commandBuffer->end();
3464}