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