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