blob: a9035f89584aba181fdbf60ba43e71fdc3b06176 [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.)
62 auto buffer_barrier = lvl_init_struct<VkBufferMemoryBarrier>();
63 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.)
88 auto mem_barrier = lvl_init_struct<VkMemoryBarrier>();
89 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.)
218 auto image_barrier = lvl_init_struct<VkImageMemoryBarrier>();
219 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.)
245 auto mem_barrier = lvl_init_struct<VkMemoryBarrier>();
246 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.)
402 auto image_barrier = lvl_init_struct<VkImageMemoryBarrier>();
403 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.)
433 auto mem_barrier = lvl_init_struct<VkMemoryBarrier>();
434 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.)
508 auto image_barrier = lvl_init_struct<VkImageMemoryBarrier>();
509 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.)
617 auto image_barrier = lvl_init_struct<VkImageMemoryBarrier>();
618 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.)
648 auto mem_barrier = lvl_init_struct<VkMemoryBarrier>();
649 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
751 auto buffer_barrier = lvl_init_struct<VkBufferMemoryBarrier>();
752 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};
921 auto image_barrier = lvl_init_struct<VkImageMemoryBarrier>();
922 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;
1001 auto bvci = lvl_init_struct<VkBufferViewCreateInfo>();
1002 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
1040 CreateComputePipelineHelper pipe(*this);
1041 pipe.InitInfo();
1042 pipe.cs_.reset(new VkShaderObj(m_device, csSource.c_str(), VK_SHADER_STAGE_COMPUTE_BIT, this));
1043 pipe.InitState();
1044 pipe.pipeline_layout_ = VkPipelineLayoutObj(m_device, {&descriptor_set.layout_});
1045 pipe.CreateComputePipeline();
1046
1047 m_commandBuffer->begin();
1048
1049 VkBufferCopy buffer_region = {0, 0, 2048};
1050 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_b.handle(), buffer_a.handle(), 1, &buffer_region);
1051
1052 VkImageSubresourceLayers layer{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
1053 VkOffset3D zero_offset{0, 0, 0};
1054 VkExtent3D full_extent{16, 16, 1};
1055 VkImageCopy image_region = {layer, zero_offset, layer, zero_offset, full_extent};
1056 vk::CmdCopyImage(m_commandBuffer->handle(), image_c_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_c_a.handle(),
1057 VK_IMAGE_LAYOUT_GENERAL, 1, &image_region);
1058 vk::CmdCopyImage(m_commandBuffer->handle(), image_s_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_s_a.handle(),
1059 VK_IMAGE_LAYOUT_GENERAL, 1, &image_region);
1060
1061 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_);
1062 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_layout_.handle(), 0, 1,
1063 &descriptor_set.set_, 0, nullptr);
1064
1065 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1066 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1067 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1068 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1069 vk::CmdDispatch(m_commandBuffer->handle(), 1, 1, 1);
1070 m_errorMonitor->VerifyFound();
1071
1072 m_commandBuffer->end();
1073 m_commandBuffer->reset();
1074 m_commandBuffer->begin();
1075
1076 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_);
1077 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_layout_.handle(), 0, 1,
1078 &descriptor_set.set_, 0, nullptr);
1079 vk::CmdDispatch(m_commandBuffer->handle(), 1, 1, 1);
1080
1081 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1082 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_b.handle(), buffer_a.handle(), 1, &buffer_region);
1083 m_errorMonitor->VerifyFound();
1084
1085 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1086 vk::CmdCopyImage(m_commandBuffer->handle(), image_c_b.handle(), VK_IMAGE_LAYOUT_GENERAL, image_c_a.handle(),
1087 VK_IMAGE_LAYOUT_GENERAL, 1, &image_region);
1088 m_errorMonitor->VerifyFound();
1089
1090 m_commandBuffer->end();
1091 m_commandBuffer->reset();
1092
1093 // DispatchIndirect
1094 m_errorMonitor->ExpectSuccess();
1095 VkBufferObj buffer_dispatchIndirect, buffer_dispatchIndirect2;
1096 buffer_usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1097 buffer_dispatchIndirect.init(
1098 *m_device, buffer_dispatchIndirect.create_info(sizeof(VkDispatchIndirectCommand), buffer_usage, nullptr), mem_prop);
1099 buffer_dispatchIndirect2.init(
1100 *m_device, buffer_dispatchIndirect2.create_info(sizeof(VkDispatchIndirectCommand), buffer_usage, nullptr), mem_prop);
1101 m_commandBuffer->begin();
1102 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_);
1103 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_layout_.handle(), 0, 1,
1104 &descriptor_set.set_, 0, nullptr);
1105 vk::CmdDispatchIndirect(m_commandBuffer->handle(), buffer_dispatchIndirect.handle(), 0);
1106 m_commandBuffer->end();
1107 m_errorMonitor->VerifyNotFound();
1108
1109 m_commandBuffer->reset();
1110 m_commandBuffer->begin();
1111
1112 buffer_region = {0, 0, sizeof(VkDispatchIndirectCommand)};
1113 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_dispatchIndirect2.handle(), buffer_dispatchIndirect.handle(), 1,
1114 &buffer_region);
1115 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_);
1116 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_layout_.handle(), 0, 1,
1117 &descriptor_set.set_, 0, nullptr);
1118 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1119 vk::CmdDispatchIndirect(m_commandBuffer->handle(), buffer_dispatchIndirect.handle(), 0);
1120 m_errorMonitor->VerifyFound();
1121 m_commandBuffer->end();
1122
1123 // Draw
1124 m_errorMonitor->ExpectSuccess();
1125 const float vbo_data[3] = {1.f, 0.f, 1.f};
1126 VkVertexInputAttributeDescription VertexInputAttributeDescription = {0, 0, VK_FORMAT_R32G32B32_SFLOAT, sizeof(vbo_data)};
1127 VkVertexInputBindingDescription VertexInputBindingDescription = {0, sizeof(vbo_data), VK_VERTEX_INPUT_RATE_VERTEX};
1128 VkBufferObj vbo, vbo2;
1129 buffer_usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1130 vbo.init(*m_device, vbo.create_info(sizeof(vbo_data), buffer_usage, nullptr), mem_prop);
1131 vbo2.init(*m_device, vbo2.create_info(sizeof(vbo_data), buffer_usage, nullptr), mem_prop);
1132
1133 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
1134 VkShaderObj fs(m_device, csSource.c_str(), VK_SHADER_STAGE_FRAGMENT_BIT, this);
1135
1136 CreatePipelineHelper g_pipe(*this);
1137 g_pipe.InitInfo();
1138 g_pipe.InitState();
1139 g_pipe.vi_ci_.pVertexBindingDescriptions = &VertexInputBindingDescription;
1140 g_pipe.vi_ci_.vertexBindingDescriptionCount = 1;
1141 g_pipe.vi_ci_.pVertexAttributeDescriptions = &VertexInputAttributeDescription;
1142 g_pipe.vi_ci_.vertexAttributeDescriptionCount = 1;
1143 g_pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
1144 g_pipe.pipeline_layout_ = VkPipelineLayoutObj(m_device, {&descriptor_set.layout_});
1145 ASSERT_VK_SUCCESS(g_pipe.CreateGraphicsPipeline());
1146
1147 m_commandBuffer->reset();
1148 m_commandBuffer->begin();
1149 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1150 VkDeviceSize offset = 0;
1151 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1152
1153 VkViewport viewport = {0, 0, 16, 16, 0, 1};
1154 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1155 VkRect2D scissor = {{0, 0}, {16, 16}};
1156 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1157
1158 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1159 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1160 &descriptor_set.set_, 0, nullptr);
1161 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1162 m_commandBuffer->EndRenderPass();
1163 m_commandBuffer->end();
1164 m_errorMonitor->VerifyNotFound();
1165
1166 m_commandBuffer->reset();
1167 m_commandBuffer->begin();
1168
1169 buffer_region = {0, 0, sizeof(vbo_data)};
1170 vk::CmdCopyBuffer(m_commandBuffer->handle(), vbo2.handle(), vbo.handle(), 1, &buffer_region);
1171
1172 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1173 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1174 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1175 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1176 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1177 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1178 &descriptor_set.set_, 0, nullptr);
1179
1180 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1181 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1182 m_errorMonitor->VerifyFound();
1183
1184 m_commandBuffer->EndRenderPass();
1185 m_commandBuffer->end();
1186
1187 // DrawIndexed
1188 m_errorMonitor->ExpectSuccess();
1189 const float ibo_data[3] = {0.f, 0.f, 0.f};
1190 VkBufferObj ibo, ibo2;
1191 buffer_usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1192 ibo.init(*m_device, ibo.create_info(sizeof(ibo_data), buffer_usage, nullptr), mem_prop);
1193 ibo2.init(*m_device, ibo2.create_info(sizeof(ibo_data), buffer_usage, nullptr), mem_prop);
1194
1195 m_commandBuffer->reset();
1196 m_commandBuffer->begin();
1197 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1198 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1199 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), ibo.handle(), 0, VK_INDEX_TYPE_UINT16);
1200 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1201 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1202
1203 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1204 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1205 &descriptor_set.set_, 0, nullptr);
1206 m_commandBuffer->DrawIndexed(3, 1, 0, 0, 0);
1207 m_commandBuffer->EndRenderPass();
1208 m_commandBuffer->end();
1209 m_errorMonitor->VerifyNotFound();
1210
1211 m_commandBuffer->reset();
1212 m_commandBuffer->begin();
1213
1214 buffer_region = {0, 0, sizeof(ibo_data)};
1215 vk::CmdCopyBuffer(m_commandBuffer->handle(), ibo2.handle(), ibo.handle(), 1, &buffer_region);
1216
1217 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1218 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1219 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), ibo.handle(), 0, VK_INDEX_TYPE_UINT16);
1220 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1221 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1222 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1223 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1224 &descriptor_set.set_, 0, nullptr);
1225
1226 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1227 m_commandBuffer->DrawIndexed(3, 1, 0, 0, 0);
1228 m_errorMonitor->VerifyFound();
1229
1230 m_commandBuffer->EndRenderPass();
1231 m_commandBuffer->end();
1232
1233 // DrawIndirect
1234 m_errorMonitor->ExpectSuccess();
1235 VkBufferObj buffer_drawIndirect, buffer_drawIndirect2;
1236 buffer_usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1237 buffer_drawIndirect.init(*m_device, buffer_drawIndirect.create_info(sizeof(VkDrawIndirectCommand), buffer_usage, nullptr),
1238 mem_prop);
1239 buffer_drawIndirect2.init(*m_device, buffer_drawIndirect2.create_info(sizeof(VkDrawIndirectCommand), buffer_usage, nullptr),
1240 mem_prop);
1241
1242 m_commandBuffer->reset();
1243 m_commandBuffer->begin();
1244 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1245 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1246 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1247 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1248
1249 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1250 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1251 &descriptor_set.set_, 0, nullptr);
1252 vk::CmdDrawIndirect(m_commandBuffer->handle(), buffer_drawIndirect.handle(), 0, 1, sizeof(VkDrawIndirectCommand));
1253 m_commandBuffer->EndRenderPass();
1254 m_commandBuffer->end();
1255 m_errorMonitor->VerifyNotFound();
1256
1257 m_commandBuffer->reset();
1258 m_commandBuffer->begin();
1259
1260 buffer_region = {0, 0, sizeof(VkDrawIndirectCommand)};
1261 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_drawIndirect2.handle(), buffer_drawIndirect.handle(), 1, &buffer_region);
1262
1263 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1264 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1265 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1266 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1267 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1268 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1269 &descriptor_set.set_, 0, nullptr);
1270
1271 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1272 vk::CmdDrawIndirect(m_commandBuffer->handle(), buffer_drawIndirect.handle(), 0, 1, sizeof(VkDrawIndirectCommand));
1273 m_errorMonitor->VerifyFound();
1274
1275 m_commandBuffer->EndRenderPass();
1276 m_commandBuffer->end();
1277
1278 // DrawIndexedIndirect
1279 m_errorMonitor->ExpectSuccess();
1280 VkBufferObj buffer_drawIndexedIndirect, buffer_drawIndexedIndirect2;
1281 buffer_usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1282 buffer_drawIndexedIndirect.init(
1283 *m_device, buffer_drawIndexedIndirect.create_info(sizeof(VkDrawIndexedIndirectCommand), buffer_usage, nullptr), mem_prop);
1284 buffer_drawIndexedIndirect2.init(
1285 *m_device, buffer_drawIndexedIndirect2.create_info(sizeof(VkDrawIndexedIndirectCommand), buffer_usage, nullptr), mem_prop);
1286
1287 m_commandBuffer->reset();
1288 m_commandBuffer->begin();
1289 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1290 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1291 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), ibo.handle(), 0, VK_INDEX_TYPE_UINT16);
1292 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1293 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1294
1295 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1296 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1297 &descriptor_set.set_, 0, nullptr);
1298 vk::CmdDrawIndexedIndirect(m_commandBuffer->handle(), buffer_drawIndirect.handle(), 0, 1, sizeof(VkDrawIndexedIndirectCommand));
1299 m_commandBuffer->EndRenderPass();
1300 m_commandBuffer->end();
1301 m_errorMonitor->VerifyNotFound();
1302
1303 m_commandBuffer->reset();
1304 m_commandBuffer->begin();
1305
1306 buffer_region = {0, 0, sizeof(VkDrawIndexedIndirectCommand)};
1307 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_drawIndexedIndirect2.handle(), buffer_drawIndexedIndirect.handle(), 1,
1308 &buffer_region);
1309
1310 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1311 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1312 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), ibo.handle(), 0, VK_INDEX_TYPE_UINT16);
1313 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1314 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1315 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1316 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
1317 &descriptor_set.set_, 0, nullptr);
1318
1319 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1320 vk::CmdDrawIndexedIndirect(m_commandBuffer->handle(), buffer_drawIndexedIndirect.handle(), 0, 1,
1321 sizeof(VkDrawIndexedIndirectCommand));
1322 m_errorMonitor->VerifyFound();
1323
1324 m_commandBuffer->EndRenderPass();
1325 m_commandBuffer->end();
1326
1327 if (has_khr_indirect) {
1328 // DrawIndirectCount
1329 auto fpCmdDrawIndirectCountKHR =
1330 (PFN_vkCmdDrawIndirectCount)vk::GetDeviceProcAddr(m_device->device(), "vkCmdDrawIndirectCountKHR");
1331 if (!fpCmdDrawIndirectCountKHR) {
1332 printf("%s Test requires unsupported vkCmdDrawIndirectCountKHR feature. Skipped.\n", kSkipPrefix);
1333 } else {
1334 m_errorMonitor->ExpectSuccess();
1335 VkBufferObj buffer_count, buffer_count2;
1336 buffer_usage =
1337 VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1338 buffer_count.init(*m_device, buffer_count.create_info(sizeof(uint32_t), buffer_usage, nullptr), mem_prop);
1339 buffer_count2.init(*m_device, buffer_count2.create_info(sizeof(uint32_t), buffer_usage, nullptr), mem_prop);
1340
1341 m_commandBuffer->reset();
1342 m_commandBuffer->begin();
1343 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1344 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1345 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1346 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1347
1348 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1349 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(),
1350 0, 1, &descriptor_set.set_, 0, nullptr);
1351 fpCmdDrawIndirectCountKHR(m_commandBuffer->handle(), buffer_drawIndirect.handle(), 0, buffer_count.handle(), 0, 1,
1352 sizeof(VkDrawIndirectCommand));
1353 m_commandBuffer->EndRenderPass();
1354 m_commandBuffer->end();
1355 m_errorMonitor->VerifyNotFound();
1356
1357 m_commandBuffer->reset();
1358 m_commandBuffer->begin();
1359
1360 buffer_region = {0, 0, sizeof(uint32_t)};
1361 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_count2.handle(), buffer_count.handle(), 1, &buffer_region);
1362
1363 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1364 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1365 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1366 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1367 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1368 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(),
1369 0, 1, &descriptor_set.set_, 0, nullptr);
1370
1371 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1372 fpCmdDrawIndirectCountKHR(m_commandBuffer->handle(), buffer_drawIndirect.handle(), 0, buffer_count.handle(), 0, 1,
1373 sizeof(VkDrawIndirectCommand));
1374 m_errorMonitor->VerifyFound();
1375
1376 m_commandBuffer->EndRenderPass();
1377 m_commandBuffer->end();
1378 }
1379
1380 // DrawIndexedIndirectCount
1381 auto fpCmdDrawIndexIndirectCountKHR =
1382 (PFN_vkCmdDrawIndirectCount)vk::GetDeviceProcAddr(m_device->device(), "vkCmdDrawIndexedIndirectCountKHR");
1383 if (!fpCmdDrawIndexIndirectCountKHR) {
1384 printf("%s Test requires unsupported vkCmdDrawIndexedIndirectCountKHR feature. Skipped.\n", kSkipPrefix);
1385 } else {
1386 m_errorMonitor->ExpectSuccess();
1387 VkBufferObj buffer_count, buffer_count2;
1388 buffer_usage =
1389 VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1390 buffer_count.init(*m_device, buffer_count.create_info(sizeof(uint32_t), buffer_usage, nullptr), mem_prop);
1391 buffer_count2.init(*m_device, buffer_count2.create_info(sizeof(uint32_t), buffer_usage, nullptr), mem_prop);
1392
1393 m_commandBuffer->reset();
1394 m_commandBuffer->begin();
1395 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1396 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1397 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), ibo.handle(), 0, VK_INDEX_TYPE_UINT16);
1398 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1399 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1400
1401 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1402 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(),
1403 0, 1, &descriptor_set.set_, 0, nullptr);
1404 fpCmdDrawIndexIndirectCountKHR(m_commandBuffer->handle(), buffer_drawIndexedIndirect.handle(), 0, buffer_count.handle(),
1405 0, 1, sizeof(VkDrawIndexedIndirectCommand));
1406 m_commandBuffer->EndRenderPass();
1407 m_commandBuffer->end();
1408 m_errorMonitor->VerifyNotFound();
1409
1410 m_commandBuffer->reset();
1411 m_commandBuffer->begin();
1412
1413 buffer_region = {0, 0, sizeof(uint32_t)};
1414 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_count2.handle(), buffer_count.handle(), 1, &buffer_region);
1415
1416 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1417 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
1418 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), ibo.handle(), 0, VK_INDEX_TYPE_UINT16);
1419 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1420 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1421 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1422 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(),
1423 0, 1, &descriptor_set.set_, 0, nullptr);
1424
1425 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1426 fpCmdDrawIndexIndirectCountKHR(m_commandBuffer->handle(), buffer_drawIndexedIndirect.handle(), 0, buffer_count.handle(),
1427 0, 1, sizeof(VkDrawIndexedIndirectCommand));
1428 m_errorMonitor->VerifyFound();
1429
1430 m_commandBuffer->EndRenderPass();
1431 m_commandBuffer->end();
1432 }
1433 } else {
1434 printf("%s Test requires unsupported vkCmdDrawIndirectCountKHR & vkDrawIndexedIndirectCountKHR feature. Skipped.\n",
1435 kSkipPrefix);
1436 }
1437}
1438
1439TEST_F(VkSyncValTest, SyncCmdClear) {
1440 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
1441 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
1442 // CmdClearColorImage
1443 m_errorMonitor->ExpectSuccess();
1444 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1445 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
1446 VkImageObj image_a(m_device), image_b(m_device);
1447 auto image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 1, format, usage, VK_IMAGE_TILING_OPTIMAL);
1448 image_a.Init(image_ci);
1449 image_b.Init(image_ci);
1450
1451 VkImageSubresourceLayers layers_all{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
1452 VkOffset3D zero_offset{0, 0, 0};
1453 VkExtent3D full_extent{128, 128, 1}; // <-- image type is 2D
1454 VkImageSubresourceRange full_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
1455
1456 VkImageCopy full_region = {layers_all, zero_offset, layers_all, zero_offset, full_extent};
1457
1458 m_commandBuffer->begin();
1459
1460 image_b.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1461 image_a.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1462
1463 auto cb = m_commandBuffer->handle();
1464 VkClearColorValue ccv = {};
1465 vk::CmdClearColorImage(m_commandBuffer->handle(), image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &full_subresource_range);
1466 m_commandBuffer->end();
1467 m_errorMonitor->VerifyNotFound();
1468
1469 m_commandBuffer->reset();
1470 m_commandBuffer->begin();
1471 vk::CmdCopyImage(cb, image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &full_region);
1472
1473 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1474 vk::CmdClearColorImage(m_commandBuffer->handle(), image_a.handle(), VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &full_subresource_range);
1475 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1476 vk::CmdClearColorImage(m_commandBuffer->handle(), image_b.handle(), VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &full_subresource_range);
1477 m_errorMonitor->VerifyFound();
1478
1479 m_commandBuffer->end();
1480
1481 // CmdClearDepthStencilImage
1482 format = FindSupportedDepthStencilFormat(gpu());
1483 if (!format) {
1484 printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix);
1485 return;
1486 }
1487 m_errorMonitor->ExpectSuccess();
1488 VkImageObj image_ds_a(m_device), image_ds_b(m_device);
1489 image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 1, format, usage, VK_IMAGE_TILING_OPTIMAL);
1490 image_ds_a.Init(image_ci);
1491 image_ds_b.Init(image_ci);
1492
1493 const VkImageAspectFlags ds_aspect = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
1494 image_ds_a.SetLayout(ds_aspect, VK_IMAGE_LAYOUT_GENERAL);
1495 image_ds_b.SetLayout(ds_aspect, VK_IMAGE_LAYOUT_GENERAL);
1496
1497 m_commandBuffer->begin();
1498 const VkClearDepthStencilValue clear_value = {};
1499 VkImageSubresourceRange ds_range = {ds_aspect, 0, 1, 0, 1};
1500
1501 vk::CmdClearDepthStencilImage(cb, image_ds_a.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1, &ds_range);
1502 m_commandBuffer->end();
1503 m_errorMonitor->VerifyNotFound();
1504
1505 VkImageSubresourceLayers ds_layers_all{ds_aspect, 0, 0, 1};
1506 VkImageCopy ds_full_region = {ds_layers_all, zero_offset, ds_layers_all, zero_offset, full_extent};
1507
1508 m_commandBuffer->reset();
1509 m_commandBuffer->begin();
1510 vk::CmdCopyImage(cb, image_ds_a.handle(), VK_IMAGE_LAYOUT_GENERAL, image_ds_b.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1511 &ds_full_region);
1512
1513 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1514 vk::CmdClearDepthStencilImage(m_commandBuffer->handle(), image_ds_a.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1,
1515 &ds_range);
1516 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1517 vk::CmdClearDepthStencilImage(m_commandBuffer->handle(), image_ds_b.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1,
1518 &ds_range);
1519 m_errorMonitor->VerifyFound();
1520
1521 m_commandBuffer->end();
1522}
1523
1524TEST_F(VkSyncValTest, SyncCmdQuery) {
1525 // CmdCopyQueryPoolResults
1526 m_errorMonitor->ExpectSuccess();
1527 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
1528 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
1529 if (IsPlatform(kNexusPlayer)) {
1530 printf("%s This test should not run on Nexus Player\n", kSkipPrefix);
1531 return;
1532 }
1533 if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) {
1534 printf("%s Queue family needs to have multiple queues to run this test.\n", kSkipPrefix);
1535 return;
1536 }
1537 uint32_t queue_count;
1538 vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_count, NULL);
1539 VkQueueFamilyProperties *queue_props = new VkQueueFamilyProperties[queue_count];
1540 vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_count, queue_props);
1541 if (queue_props[m_device->graphics_queue_node_index_].timestampValidBits == 0) {
1542 printf("%s Device graphic queue has timestampValidBits of 0, skipping.\n", kSkipPrefix);
1543 return;
1544 }
1545
1546 VkQueryPool query_pool;
1547 VkQueryPoolCreateInfo query_pool_create_info{};
1548 query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
1549 query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
1550 query_pool_create_info.queryCount = 1;
1551 vk::CreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
1552
1553 VkBufferObj buffer_a, buffer_b;
1554 VkMemoryPropertyFlags mem_prop = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
1555 buffer_a.init_as_src_and_dst(*m_device, 256, mem_prop);
1556 buffer_b.init_as_src_and_dst(*m_device, 256, mem_prop);
1557
1558 VkBufferCopy region = {0, 0, 256};
1559
1560 auto cb = m_commandBuffer->handle();
1561 m_commandBuffer->begin();
1562 vk::CmdResetQueryPool(cb, query_pool, 0, 1);
1563 vk::CmdWriteTimestamp(cb, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool, 0);
1564 vk::CmdCopyQueryPoolResults(cb, query_pool, 0, 1, buffer_a.handle(), 0, 0, VK_QUERY_RESULT_WAIT_BIT);
1565 m_commandBuffer->end();
1566 m_errorMonitor->VerifyNotFound();
1567
1568 m_commandBuffer->reset();
1569 m_commandBuffer->begin();
1570 vk::CmdCopyBuffer(cb, buffer_a.handle(), buffer_b.handle(), 1, &region);
1571 vk::CmdResetQueryPool(cb, query_pool, 0, 1);
1572 vk::CmdWriteTimestamp(cb, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool, 0);
1573 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1574 vk::CmdCopyQueryPoolResults(cb, query_pool, 0, 1, buffer_a.handle(), 0, 256, VK_QUERY_RESULT_WAIT_BIT);
1575 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1576 vk::CmdCopyQueryPoolResults(cb, query_pool, 0, 1, buffer_b.handle(), 0, 256, VK_QUERY_RESULT_WAIT_BIT);
1577 m_commandBuffer->end();
1578 m_errorMonitor->VerifyFound();
1579
1580 // TODO:Track VkQueryPool
1581 // TODO:CmdWriteTimestamp
1582 vk::DestroyQueryPool(m_device->device(), query_pool, nullptr);
1583}
1584
1585TEST_F(VkSyncValTest, SyncCmdDrawDepthStencil) {
1586 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
1587 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
1588 m_errorMonitor->ExpectSuccess();
1589
1590 const auto format_ds = FindSupportedDepthStencilFormat(gpu());
1591 if (!format_ds) {
1592 printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix);
1593 return;
1594 }
1595 const auto format_dp = FindSupportedDepthOnlyFormat(gpu());
1596 if (!format_dp) {
1597 printf("%s No only Depth format found. Skipped.\n", kSkipPrefix);
1598 return;
1599 }
1600 const auto format_st = FindSupportedStencilOnlyFormat(gpu());
1601 if (!format_st) {
1602 printf("%s No only Stencil format found. Skipped.\n", kSkipPrefix);
1603 return;
1604 }
1605
1606 VkDepthStencilObj image_ds(m_device), image_dp(m_device), image_st(m_device);
1607 image_ds.Init(m_device, 16, 16, format_ds);
1608 image_dp.Init(m_device, 16, 16, format_dp);
1609 image_st.Init(m_device, 16, 16, format_st);
1610
1611 VkRenderpassObj rp_ds(m_device, format_ds, true), rp_dp(m_device, format_dp, true), rp_st(m_device, format_st, true);
1612
1613 VkFramebuffer fb_ds, fb_dp, fb_st;
1614 VkFramebufferCreateInfo fbci = {
1615 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp_ds.handle(), 1, image_ds.BindInfo(), 16, 16, 1};
1616 ASSERT_VK_SUCCESS(vk::CreateFramebuffer(device(), &fbci, nullptr, &fb_ds));
1617 fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp_dp.handle(), 1, image_dp.BindInfo(), 16, 16, 1};
1618 ASSERT_VK_SUCCESS(vk::CreateFramebuffer(device(), &fbci, nullptr, &fb_dp));
1619 fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp_st.handle(), 1, image_st.BindInfo(), 16, 16, 1};
1620 ASSERT_VK_SUCCESS(vk::CreateFramebuffer(device(), &fbci, nullptr, &fb_st));
1621
1622 VkStencilOpState stencil = {};
1623 stencil.failOp = VK_STENCIL_OP_KEEP;
1624 stencil.passOp = VK_STENCIL_OP_KEEP;
1625 stencil.depthFailOp = VK_STENCIL_OP_KEEP;
1626 stencil.compareOp = VK_COMPARE_OP_NEVER;
1627
1628 auto ds_ci = lvl_init_struct<VkPipelineDepthStencilStateCreateInfo>();
1629 ds_ci.depthTestEnable = VK_TRUE;
1630 ds_ci.depthWriteEnable = VK_TRUE;
1631 ds_ci.depthCompareOp = VK_COMPARE_OP_NEVER;
1632 ds_ci.stencilTestEnable = VK_TRUE;
1633 ds_ci.front = stencil;
1634 ds_ci.back = stencil;
1635
1636 CreatePipelineHelper g_pipe_ds(*this), g_pipe_dp(*this), g_pipe_st(*this);
1637 g_pipe_ds.InitInfo();
1638 g_pipe_ds.gp_ci_.renderPass = rp_ds.handle();
1639 g_pipe_ds.gp_ci_.pDepthStencilState = &ds_ci;
1640 g_pipe_ds.InitState();
1641 ASSERT_VK_SUCCESS(g_pipe_ds.CreateGraphicsPipeline());
1642 g_pipe_dp.InitInfo();
1643 g_pipe_dp.gp_ci_.renderPass = rp_dp.handle();
1644 ds_ci.stencilTestEnable = VK_FALSE;
1645 g_pipe_dp.gp_ci_.pDepthStencilState = &ds_ci;
1646 g_pipe_dp.InitState();
1647 ASSERT_VK_SUCCESS(g_pipe_dp.CreateGraphicsPipeline());
1648 g_pipe_st.InitInfo();
1649 g_pipe_st.gp_ci_.renderPass = rp_st.handle();
1650 ds_ci.depthTestEnable = VK_FALSE;
1651 ds_ci.stencilTestEnable = VK_TRUE;
1652 g_pipe_st.gp_ci_.pDepthStencilState = &ds_ci;
1653 g_pipe_st.InitState();
1654 ASSERT_VK_SUCCESS(g_pipe_st.CreateGraphicsPipeline());
1655
1656 m_commandBuffer->begin();
1657 m_renderPassBeginInfo.renderArea = {{0, 0}, {16, 16}};
1658 m_renderPassBeginInfo.pClearValues = nullptr;
1659 m_renderPassBeginInfo.clearValueCount = 0;
1660
1661 m_renderPassBeginInfo.renderPass = rp_ds.handle();
1662 m_renderPassBeginInfo.framebuffer = fb_ds;
1663 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1664 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_ds.pipeline_);
1665 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1666 m_commandBuffer->EndRenderPass();
1667
1668 m_renderPassBeginInfo.renderPass = rp_dp.handle();
1669 m_renderPassBeginInfo.framebuffer = fb_dp;
1670 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1671 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_dp.pipeline_);
1672 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1673 m_commandBuffer->EndRenderPass();
1674
1675 m_renderPassBeginInfo.renderPass = rp_st.handle();
1676 m_renderPassBeginInfo.framebuffer = fb_st;
1677 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1678 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_st.pipeline_);
1679 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1680 m_commandBuffer->EndRenderPass();
1681
1682 m_commandBuffer->end();
1683 m_errorMonitor->VerifyNotFound();
1684
1685 m_commandBuffer->reset();
1686 m_commandBuffer->begin();
1687
1688 VkImageCopy copyRegion;
1689 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
1690 copyRegion.srcSubresource.mipLevel = 0;
1691 copyRegion.srcSubresource.baseArrayLayer = 0;
1692 copyRegion.srcSubresource.layerCount = 1;
1693 copyRegion.srcOffset = {0, 0, 0};
1694 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
1695 copyRegion.dstSubresource.mipLevel = 0;
1696 copyRegion.dstSubresource.baseArrayLayer = 0;
1697 copyRegion.dstSubresource.layerCount = 1;
1698 copyRegion.dstOffset = {0, 0, 0};
1699 copyRegion.extent = {16, 16, 1};
1700
1701 m_commandBuffer->CopyImage(image_ds.handle(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, image_dp.handle(),
1702 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 1, &copyRegion);
1703
1704 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
1705 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
1706 m_commandBuffer->CopyImage(image_ds.handle(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, image_st.handle(),
1707 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 1, &copyRegion);
1708 m_renderPassBeginInfo.renderPass = rp_ds.handle();
1709 m_renderPassBeginInfo.framebuffer = fb_ds;
1710 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_READ");
1711 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1712 m_errorMonitor->VerifyFound();
1713 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1714 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_ds.pipeline_);
1715 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1716 m_commandBuffer->EndRenderPass();
1717
1718 m_renderPassBeginInfo.renderPass = rp_dp.handle();
1719 m_renderPassBeginInfo.framebuffer = fb_dp;
1720 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1721 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1722 m_errorMonitor->VerifyFound();
1723 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1724 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_dp.pipeline_);
1725 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1726 m_commandBuffer->EndRenderPass();
1727
1728 m_renderPassBeginInfo.renderPass = rp_st.handle();
1729 m_renderPassBeginInfo.framebuffer = fb_st;
1730 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1731 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1732 m_errorMonitor->VerifyFound();
1733 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1734 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_st.pipeline_);
1735 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1736 m_commandBuffer->EndRenderPass();
1737
1738 m_commandBuffer->end();
1739 vk::DestroyFramebuffer(m_device->device(), fb_ds, nullptr);
1740 vk::DestroyFramebuffer(m_device->device(), fb_dp, nullptr);
1741 vk::DestroyFramebuffer(m_device->device(), fb_st, nullptr);
1742}
1743
1744TEST_F(VkSyncValTest, RenderPassLoadHazardVsInitialLayout) {
1745 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
1746 ASSERT_NO_FATAL_FAILURE(InitState());
1747 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1748
1749 VkImageUsageFlags usage_color = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1750 VkImageUsageFlags usage_input = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1751 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
1752 VkImageObj image_color(m_device), image_input(m_device);
1753 auto image_ci = VkImageObj::ImageCreateInfo2D(32, 32, 1, 1, format, usage_color, VK_IMAGE_TILING_OPTIMAL);
1754 image_color.Init(image_ci);
1755 image_ci.usage = usage_input;
1756 image_input.Init(image_ci);
1757 VkImageView attachments[] = {image_color.targetView(format), image_input.targetView(format)};
1758
1759 const VkAttachmentDescription attachmentDescriptions[] = {
1760 // Result attachment
1761 {(VkAttachmentDescriptionFlags)0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR,
1762 VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
1763 VK_IMAGE_LAYOUT_UNDEFINED, // Here causes DesiredError that SYNC-HAZARD-NONE in BeginRenderPass.
1764 // It should be VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
1765 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
1766 // Input attachment
1767 {(VkAttachmentDescriptionFlags)0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD,
1768 VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
1769 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL}};
1770
1771 const VkAttachmentReference resultAttachmentRef = {0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
1772 const VkAttachmentReference inputAttachmentRef = {1u, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};
1773
1774 const VkSubpassDescription subpassDescription = {(VkSubpassDescriptionFlags)0,
1775 VK_PIPELINE_BIND_POINT_GRAPHICS,
1776 1u,
1777 &inputAttachmentRef,
1778 1u,
1779 &resultAttachmentRef,
1780 0,
1781 0,
1782 0u,
1783 0};
1784
1785 const VkSubpassDependency subpassDependency = {VK_SUBPASS_EXTERNAL,
1786 0,
1787 VK_PIPELINE_STAGE_TRANSFER_BIT,
1788 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
1789 VK_ACCESS_TRANSFER_WRITE_BIT,
1790 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | VK_ACCESS_SHADER_READ_BIT,
1791 VK_DEPENDENCY_BY_REGION_BIT};
1792
1793 const VkRenderPassCreateInfo renderPassInfo = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
1794 0,
1795 (VkRenderPassCreateFlags)0,
1796 2u,
1797 attachmentDescriptions,
1798 1u,
1799 &subpassDescription,
1800 1u,
1801 &subpassDependency};
1802 VkRenderPass rp;
1803 ASSERT_VK_SUCCESS(vk::CreateRenderPass(device(), &renderPassInfo, nullptr, &rp));
1804
1805 VkFramebuffer fb;
1806 VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 2, attachments, 32, 32, 1};
1807 ASSERT_VK_SUCCESS(vk::CreateFramebuffer(device(), &fbci, nullptr, &fb));
1808
1809 image_input.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
1810
1811 m_commandBuffer->begin();
1812
1813 m_renderPassBeginInfo.renderArea = {{0, 0}, {32, 32}};
1814 m_renderPassBeginInfo.renderPass = rp;
1815 m_renderPassBeginInfo.framebuffer = fb;
1816
1817 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ_AFTER_WRITE");
1818 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1819 // Even though we have no accesses prior, the layout transition *is* an access, so load can be validated vs. layout transition
1820 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1821 m_errorMonitor->VerifyFound();
1822}
1823
1824TEST_F(VkSyncValTest, SyncRenderPassWithWrongDepthStencilInitialLayout) {
1825 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
1826 ASSERT_NO_FATAL_FAILURE(InitState());
1827 if (IsPlatform(kNexusPlayer)) {
1828 printf("%s This test should not run on Nexus Player\n", kSkipPrefix);
1829 return;
1830 }
1831
1832 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1833
1834 VkFormat color_format = VK_FORMAT_R8G8B8A8_UNORM;
1835 VkFormat ds_format = FindSupportedDepthStencilFormat(gpu());
1836 if (!ds_format) {
1837 printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix);
1838 return;
1839 }
1840 VkImageUsageFlags usage_color = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1841 VkImageUsageFlags usage_ds = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
1842 VkImageObj image_color(m_device), image_color2(m_device);
1843 auto image_ci = VkImageObj::ImageCreateInfo2D(32, 32, 1, 1, color_format, usage_color, VK_IMAGE_TILING_OPTIMAL);
1844 image_color.Init(image_ci);
1845 image_color2.Init(image_ci);
1846 VkDepthStencilObj image_ds(m_device);
1847 image_ds.Init(m_device, 32, 32, ds_format, usage_ds);
1848
1849 const VkAttachmentDescription colorAttachmentDescription = {(VkAttachmentDescriptionFlags)0,
1850 color_format,
1851 VK_SAMPLE_COUNT_1_BIT,
1852 VK_ATTACHMENT_LOAD_OP_CLEAR,
1853 VK_ATTACHMENT_STORE_OP_STORE,
1854 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1855 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1856 VK_IMAGE_LAYOUT_UNDEFINED,
1857 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
1858
1859 const VkAttachmentDescription depthStencilAttachmentDescription = {
1860 (VkAttachmentDescriptionFlags)0, ds_format, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR,
1861 VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE,
1862 VK_IMAGE_LAYOUT_UNDEFINED, // Here causes DesiredError that SYNC-HAZARD-WRITE_AFTER_WRITE in BeginRenderPass.
1863 // It should be VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
1864 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
1865
1866 std::vector<VkAttachmentDescription> attachmentDescriptions;
1867 attachmentDescriptions.push_back(colorAttachmentDescription);
1868 attachmentDescriptions.push_back(depthStencilAttachmentDescription);
1869
1870 const VkAttachmentReference colorAttachmentRef = {0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
1871
1872 const VkAttachmentReference depthStencilAttachmentRef = {1u, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
1873
1874 const VkSubpassDescription subpassDescription = {(VkSubpassDescriptionFlags)0,
1875 VK_PIPELINE_BIND_POINT_GRAPHICS,
1876 0u,
1877 0,
1878 1u,
1879 &colorAttachmentRef,
1880 0,
1881 &depthStencilAttachmentRef,
1882 0u,
1883 0};
1884
1885 const VkRenderPassCreateInfo renderPassInfo = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
1886 0,
1887 (VkRenderPassCreateFlags)0,
1888 (uint32_t)attachmentDescriptions.size(),
1889 &attachmentDescriptions[0],
1890 1u,
1891 &subpassDescription,
1892 0u,
1893 0};
1894 VkRenderPass rp;
1895 ASSERT_VK_SUCCESS(vk::CreateRenderPass(device(), &renderPassInfo, nullptr, &rp));
1896
1897 VkImageView fb_attachments[] = {image_color.targetView(color_format),
1898 image_ds.targetView(ds_format, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)};
1899 const VkFramebufferCreateInfo fbci = {
1900 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, 0, 0u, rp, 2u, fb_attachments, 32, 32, 1u,
1901 };
1902 VkFramebuffer fb;
1903 ASSERT_VK_SUCCESS(vk::CreateFramebuffer(device(), &fbci, nullptr, &fb));
1904 fb_attachments[0] = image_color2.targetView(color_format);
1905 VkFramebuffer fb1;
1906 ASSERT_VK_SUCCESS(vk::CreateFramebuffer(device(), &fbci, nullptr, &fb1));
1907
1908 CreatePipelineHelper g_pipe(*this);
1909 g_pipe.InitInfo();
1910 g_pipe.gp_ci_.renderPass = rp;
1911
1912 VkStencilOpState stencil = {};
1913 stencil.failOp = VK_STENCIL_OP_KEEP;
1914 stencil.passOp = VK_STENCIL_OP_KEEP;
1915 stencil.depthFailOp = VK_STENCIL_OP_KEEP;
1916 stencil.compareOp = VK_COMPARE_OP_NEVER;
1917
1918 auto ds_ci = lvl_init_struct<VkPipelineDepthStencilStateCreateInfo>();
1919 ds_ci.depthTestEnable = VK_TRUE;
1920 ds_ci.depthWriteEnable = VK_TRUE;
1921 ds_ci.depthCompareOp = VK_COMPARE_OP_NEVER;
1922 ds_ci.stencilTestEnable = VK_TRUE;
1923 ds_ci.front = stencil;
1924 ds_ci.back = stencil;
1925
1926 g_pipe.gp_ci_.pDepthStencilState = &ds_ci;
1927 g_pipe.InitState();
1928 ASSERT_VK_SUCCESS(g_pipe.CreateGraphicsPipeline());
1929
1930 m_commandBuffer->begin();
1931 m_renderPassBeginInfo.renderArea = {{0, 0}, {32, 32}};
1932 m_renderPassBeginInfo.renderPass = rp;
1933
1934 m_renderPassBeginInfo.framebuffer = fb;
1935 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1936 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
1937 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
1938 m_commandBuffer->EndRenderPass();
1939
1940 m_renderPassBeginInfo.framebuffer = fb1;
1941
1942 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
1943 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1944 m_errorMonitor->VerifyFound();
1945}
1946
1947TEST_F(VkSyncValTest, SyncLayoutTransition) {
1948 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
1949 ASSERT_NO_FATAL_FAILURE(InitState());
1950 if (IsPlatform(kNexusPlayer)) {
1951 printf("%s This test should not run on Nexus Player\n", kSkipPrefix);
1952 return;
1953 }
1954
1955 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1956
1957 VkImageUsageFlags usage_color = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1958 VkImageUsageFlags usage_input =
1959 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
1960 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
1961 VkImageObj image_color(m_device), image_input(m_device);
1962 auto image_ci = VkImageObj::ImageCreateInfo2D(64, 64, 1, 1, format, usage_input, VK_IMAGE_TILING_OPTIMAL);
1963 image_input.InitNoLayout(image_ci);
1964 image_ci.usage = usage_color;
1965 image_color.InitNoLayout(image_ci);
1966 VkImageView view_input = image_input.targetView(format);
1967 VkImageView view_color = image_color.targetView(format);
1968 VkImageView attachments[] = {view_color, view_input};
1969
1970 const VkAttachmentDescription fbAttachment = {
1971 0u,
1972 format,
1973 VK_SAMPLE_COUNT_1_BIT,
1974 VK_ATTACHMENT_LOAD_OP_CLEAR,
1975 VK_ATTACHMENT_STORE_OP_STORE,
1976 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1977 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1978 VK_IMAGE_LAYOUT_UNDEFINED,
1979 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1980 };
1981
1982 std::vector<VkAttachmentDescription> attachmentDescs;
1983 attachmentDescs.push_back(fbAttachment);
1984
1985 // Add it as a frame buffer attachment.
1986 const VkAttachmentDescription inputAttachment = {
1987 0u,
1988 format,
1989 VK_SAMPLE_COUNT_1_BIT,
1990 VK_ATTACHMENT_LOAD_OP_LOAD,
1991 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1992 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1993 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1994 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
1995 VK_IMAGE_LAYOUT_GENERAL,
1996 };
1997 attachmentDescs.push_back(inputAttachment);
1998
1999 std::vector<VkAttachmentReference> inputAttachments;
2000 const VkAttachmentReference inputRef = {
2001 1u,
2002 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
2003 };
2004 inputAttachments.push_back(inputRef);
2005
2006 const VkAttachmentReference colorRef = {
2007 0u,
2008 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
2009 };
2010 const std::vector<VkAttachmentReference> colorAttachments(1u, colorRef);
2011
2012 const VkSubpassDescription subpass = {
2013 0u,
2014 VK_PIPELINE_BIND_POINT_GRAPHICS,
2015 static_cast<uint32_t>(inputAttachments.size()),
2016 inputAttachments.data(),
2017 static_cast<uint32_t>(colorAttachments.size()),
2018 colorAttachments.data(),
2019 0u,
2020 nullptr,
2021 0u,
2022 nullptr,
2023 };
2024 const std::vector<VkSubpassDescription> subpasses(1u, subpass);
2025
2026 const VkRenderPassCreateInfo renderPassInfo = {
2027 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
2028 nullptr,
2029 0u,
2030 static_cast<uint32_t>(attachmentDescs.size()),
2031 attachmentDescs.data(),
2032 static_cast<uint32_t>(subpasses.size()),
2033 subpasses.data(),
2034 0u,
2035 nullptr,
2036 };
2037 VkRenderPass rp;
2038 ASSERT_VK_SUCCESS(vk::CreateRenderPass(device(), &renderPassInfo, nullptr, &rp));
2039
2040 const VkFramebufferCreateInfo fbci = {
2041 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, 0, 0u, rp, 2u, attachments, 64, 64, 1u,
2042 };
2043 VkFramebuffer fb;
2044 ASSERT_VK_SUCCESS(vk::CreateFramebuffer(device(), &fbci, nullptr, &fb));
2045
2046 VkSampler sampler = VK_NULL_HANDLE;
2047 VkSamplerCreateInfo sampler_info = SafeSaneSamplerCreateInfo();
2048 vk::CreateSampler(m_device->device(), &sampler_info, NULL, &sampler);
2049
2050 char const *fsSource =
2051 "#version 450\n"
2052 "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n"
2053 "void main() {\n"
2054 " vec4 color = subpassLoad(x);\n"
2055 "}\n";
2056
2057 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
2058 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
2059
2060 CreatePipelineHelper g_pipe(*this);
2061 g_pipe.InitInfo();
2062 g_pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
2063 g_pipe.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
2064 g_pipe.gp_ci_.renderPass = rp;
2065 g_pipe.InitState();
2066 ASSERT_VK_SUCCESS(g_pipe.CreateGraphicsPipeline());
2067
2068 g_pipe.descriptor_set_->WriteDescriptorImageInfo(0, view_input, sampler, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
2069 g_pipe.descriptor_set_->UpdateDescriptorSets();
2070
2071 m_commandBuffer->begin();
2072 auto cb = m_commandBuffer->handle();
2073 VkClearColorValue ccv = {};
2074 VkImageSubresourceRange full_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
2075
2076 const VkImageMemoryBarrier preClearBarrier = {
2077 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, 0, 0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
2078 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, 0, image_input.handle(), full_subresource_range,
2079 };
2080 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u,
2081 &preClearBarrier);
2082
2083 vk::CmdClearColorImage(m_commandBuffer->handle(), image_input.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &ccv, 1,
2084 &full_subresource_range);
2085
2086 const VkImageMemoryBarrier postClearBarrier = {
2087 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
2088 0,
2089 VK_ACCESS_TRANSFER_WRITE_BIT,
2090 VK_ACCESS_SHADER_READ_BIT,
2091 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
2092 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
2093 0,
2094 0,
2095 image_input.handle(),
2096 full_subresource_range,
2097 };
2098 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u, nullptr, 0u, nullptr,
2099 1u, &postClearBarrier);
2100
2101 m_renderPassBeginInfo.renderArea = {{0, 0}, {64, 64}};
2102 m_renderPassBeginInfo.renderPass = rp;
2103 m_renderPassBeginInfo.framebuffer = fb;
2104
2105 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2106 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
2107 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
2108 &g_pipe.descriptor_set_->set_, 0, nullptr);
2109
2110 // Positive test for ordering rules between load and input attachment usage
2111 m_errorMonitor->ExpectSuccess();
2112 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
2113
2114 // Positive test for store ordering vs. input attachment and dependency *to* external for layout transition
2115 m_commandBuffer->EndRenderPass();
2116 m_errorMonitor->VerifyNotFound();
2117
2118 // Catch a conflict with the input attachment final layout transition
2119 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE_AFTER_WRITE");
2120 vk::CmdClearColorImage(m_commandBuffer->handle(), image_input.handle(), VK_IMAGE_LAYOUT_GENERAL, &ccv, 1,
2121 &full_subresource_range);
2122 m_errorMonitor->VerifyFound();
2123}
2124
2125TEST_F(VkSyncValTest, SyncSubpassMultiDep) {
2126 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
2127 ASSERT_NO_FATAL_FAILURE(InitState());
2128 if (IsPlatform(kNexusPlayer)) {
2129 printf("%s This test should not run on Nexus Player\n", kSkipPrefix);
2130 return;
2131 }
2132
2133 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2134
2135 VkImageUsageFlags usage_color = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
2136 VkImageUsageFlags usage_input =
2137 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
2138 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
2139 VkImageObj image_color(m_device), image_input(m_device);
2140 auto image_ci = VkImageObj::ImageCreateInfo2D(64, 64, 1, 1, format, usage_input, VK_IMAGE_TILING_OPTIMAL);
2141 image_input.InitNoLayout(image_ci);
2142 image_ci.usage = usage_color;
2143 image_color.InitNoLayout(image_ci);
2144 VkImageView view_input = image_input.targetView(format);
2145 VkImageView view_color = image_color.targetView(format);
2146 VkImageView attachments[] = {view_color, view_input};
2147 VkImageSubresourceRange full_subresource_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
2148 VkImageSubresourceLayers mip_0_layer_0{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
2149 VkOffset3D image_zero{0, 0, 0};
2150 VkExtent3D image_size{64, 64, 1};
2151 VkImageCopy full_region{mip_0_layer_0, image_zero, mip_0_layer_0, image_zero, image_size};
2152
2153 const VkAttachmentDescription fbAttachment = {
2154 0u,
2155 format,
2156 VK_SAMPLE_COUNT_1_BIT,
2157 VK_ATTACHMENT_LOAD_OP_CLEAR,
2158 VK_ATTACHMENT_STORE_OP_STORE,
2159 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2160 VK_ATTACHMENT_STORE_OP_STORE,
2161 VK_IMAGE_LAYOUT_GENERAL,
2162 VK_IMAGE_LAYOUT_GENERAL,
2163 };
2164
2165 std::vector<VkAttachmentDescription> attachmentDescs;
2166 attachmentDescs.push_back(fbAttachment);
2167
2168 // Add it as a frame buffer attachment.
2169 const VkAttachmentDescription inputAttachment = {
2170 0u,
2171 format,
2172 VK_SAMPLE_COUNT_1_BIT,
2173 VK_ATTACHMENT_LOAD_OP_LOAD,
2174 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2175 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2176 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2177 VK_IMAGE_LAYOUT_GENERAL,
2178 VK_IMAGE_LAYOUT_GENERAL,
2179 };
2180 attachmentDescs.push_back(inputAttachment);
2181
2182 std::vector<VkAttachmentReference> inputAttachments;
2183 const VkAttachmentReference inputRef = {
2184 1u,
2185 VK_IMAGE_LAYOUT_GENERAL,
2186 };
2187 inputAttachments.push_back(inputRef);
2188
2189 const VkAttachmentReference colorRef = {
2190 0u,
2191 VK_IMAGE_LAYOUT_GENERAL,
2192 };
2193 const std::vector<VkAttachmentReference> colorAttachments(1u, colorRef);
2194
2195 const VkSubpassDescription subpass = {
2196 0u,
2197 VK_PIPELINE_BIND_POINT_GRAPHICS,
2198 static_cast<uint32_t>(inputAttachments.size()),
2199 inputAttachments.data(),
2200 static_cast<uint32_t>(colorAttachments.size()),
2201 colorAttachments.data(),
2202 0u,
2203 nullptr,
2204 0u,
2205 nullptr,
2206 };
2207 const std::vector<VkSubpassDescription> subpasses(1u, subpass);
2208
2209 std::vector<VkSubpassDependency> subpass_dep_postive;
2210 subpass_dep_postive.push_back({VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_TRANSFER_BIT,
2211 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2212 VK_DEPENDENCY_VIEW_LOCAL_BIT});
2213 subpass_dep_postive.push_back({VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_TRANSFER_BIT,
2214 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_TRANSFER_WRITE_BIT,
2215 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, VK_DEPENDENCY_VIEW_LOCAL_BIT});
2216 subpass_dep_postive.push_back({0, VK_SUBPASS_EXTERNAL, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2217 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2218 VK_ACCESS_TRANSFER_READ_BIT, VK_DEPENDENCY_VIEW_LOCAL_BIT});
2219 subpass_dep_postive.push_back({0, VK_SUBPASS_EXTERNAL, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2220 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2221 VK_ACCESS_TRANSFER_WRITE_BIT, VK_DEPENDENCY_VIEW_LOCAL_BIT});
2222
2223 VkRenderPassCreateInfo renderPassInfo = {
2224 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
2225 nullptr,
2226 0u,
2227 static_cast<uint32_t>(attachmentDescs.size()),
2228 attachmentDescs.data(),
2229 static_cast<uint32_t>(subpasses.size()),
2230 subpasses.data(),
2231 static_cast<uint32_t>(subpass_dep_postive.size()),
2232 subpass_dep_postive.data(),
2233 };
2234 VkRenderPass rp_positive;
2235 ASSERT_VK_SUCCESS(vk::CreateRenderPass(device(), &renderPassInfo, nullptr, &rp_positive));
2236
2237 std::vector<VkSubpassDependency> subpass_dep_negative;
2238 subpass_dep_negative.push_back({VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_TRANSFER_BIT,
2239 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2240 VK_DEPENDENCY_VIEW_LOCAL_BIT});
2241 // Show that the two barriers do *not* chain by breaking the positive barrier into two bits.
2242 subpass_dep_negative.push_back({VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_TRANSFER_BIT,
2243 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, 0,
2244 VK_DEPENDENCY_VIEW_LOCAL_BIT});
2245 subpass_dep_negative.push_back({VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2246 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
2247 VK_DEPENDENCY_VIEW_LOCAL_BIT});
2248
2249 renderPassInfo.dependencyCount = static_cast<uint32_t>(subpass_dep_negative.size());
2250 renderPassInfo.pDependencies = subpass_dep_negative.data();
2251 VkRenderPass rp_negative;
2252 ASSERT_VK_SUCCESS(vk::CreateRenderPass(device(), &renderPassInfo, nullptr, &rp_negative));
2253
2254 // rp_postive and rp_negative should be compatible for the same fb object
2255 const VkFramebufferCreateInfo fbci = {
2256 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, 0, 0u, rp_positive, 2u, attachments, 64, 64, 1u,
2257 };
2258 VkFramebuffer fb;
2259 ASSERT_VK_SUCCESS(vk::CreateFramebuffer(device(), &fbci, nullptr, &fb));
2260
2261 VkSampler sampler = VK_NULL_HANDLE;
2262 VkSamplerCreateInfo sampler_info = SafeSaneSamplerCreateInfo();
2263 vk::CreateSampler(m_device->device(), &sampler_info, NULL, &sampler);
2264
2265 char const *fsSource =
2266 "#version 450\n"
2267 "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n"
2268 "void main() {\n"
2269 " vec4 color = subpassLoad(x);\n"
2270 "}\n";
2271
2272 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
2273 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
2274
2275 CreatePipelineHelper g_pipe(*this);
2276 g_pipe.InitInfo();
2277 g_pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
2278 g_pipe.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
2279 g_pipe.gp_ci_.renderPass = rp_positive;
2280 g_pipe.InitState();
2281 ASSERT_VK_SUCCESS(g_pipe.CreateGraphicsPipeline());
2282
2283 g_pipe.descriptor_set_->WriteDescriptorImageInfo(0, view_input, sampler, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
2284 g_pipe.descriptor_set_->UpdateDescriptorSets();
2285
2286 m_commandBuffer->begin();
2287 auto cb = m_commandBuffer->handle();
2288 VkClearColorValue ccv = {};
2289
2290 const VkImageMemoryBarrier xferDestBarrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
2291 nullptr,
2292 VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT,
2293 VK_ACCESS_TRANSFER_WRITE_BIT,
2294 VK_IMAGE_LAYOUT_GENERAL,
2295 VK_IMAGE_LAYOUT_GENERAL,
2296 VK_QUEUE_FAMILY_IGNORED,
2297 VK_QUEUE_FAMILY_IGNORED,
2298 VK_NULL_HANDLE,
2299 full_subresource_range};
2300 const VkImageMemoryBarrier xferDestToSrcBarrier = {
2301 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
2302 nullptr,
2303 VK_ACCESS_TRANSFER_WRITE_BIT,
2304 VK_ACCESS_TRANSFER_READ_BIT,
2305 VK_IMAGE_LAYOUT_GENERAL,
2306 VK_IMAGE_LAYOUT_GENERAL,
2307 VK_QUEUE_FAMILY_IGNORED,
2308 VK_QUEUE_FAMILY_IGNORED,
2309 VK_NULL_HANDLE,
2310 full_subresource_range,
2311 };
2312
2313 VkImageMemoryBarrier preClearBarrier = xferDestBarrier;
2314 preClearBarrier.image = image_color.handle();
2315
2316 VkImageMemoryBarrier preCopyBarriers[2] = {xferDestToSrcBarrier, xferDestBarrier};
2317 preCopyBarriers[0].image = image_color.handle();
2318 preCopyBarriers[1].image = image_input.handle();
2319 // Positive test for ordering rules between load and input attachment usage
2320 m_errorMonitor->ExpectSuccess();
2321
2322 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u,
2323 &preClearBarrier);
2324
2325 vk::CmdClearColorImage(m_commandBuffer->handle(), image_color.handle(), VK_IMAGE_LAYOUT_GENERAL, &ccv, 1,
2326 &full_subresource_range);
2327
2328 vk::CmdPipelineBarrier(cb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 2u,
2329 preCopyBarriers);
2330
2331 vk::CmdCopyImage(m_commandBuffer->handle(), image_color.handle(), VK_IMAGE_LAYOUT_GENERAL, image_input.handle(),
2332 VK_IMAGE_LAYOUT_GENERAL, 1u, &full_region);
2333
2334 // No post copy image barrier, we are testing the subpass dependencies
2335
2336 m_renderPassBeginInfo.renderArea = {{0, 0}, {64, 64}};
2337 m_renderPassBeginInfo.renderPass = rp_positive;
2338 m_renderPassBeginInfo.framebuffer = fb;
2339
2340 // Postive renderpass multidependency test
2341 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2342 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
2343 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
2344 &g_pipe.descriptor_set_->set_, 0, nullptr);
2345
2346 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
2347
2348 // Positive test for store ordering vs. input attachment and dependency *to* external for layout transition
2349 m_commandBuffer->EndRenderPass();
2350 // m_errorMonitor->VerifyNotFound();
2351
2352 vk::CmdCopyImage(m_commandBuffer->handle(), image_color.handle(), VK_IMAGE_LAYOUT_GENERAL, image_input.handle(),
2353 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &full_region);
2354 m_errorMonitor->VerifyNotFound();
2355
2356 m_renderPassBeginInfo.renderArea = {{0, 0}, {64, 64}};
2357 m_renderPassBeginInfo.renderPass = rp_negative;
2358 m_renderPassBeginInfo.framebuffer = fb;
2359
2360 // Postive renderpass multidependency test, will fail IFF the dependencies are acting indepently.
2361 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "SYNC-HAZARD-READ_AFTER_WRITE");
2362 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2363 m_errorMonitor->VerifyFound();
2364}
Jeremy Gebben6feafd42020-11-30 09:11:38 -07002365
2366TEST_F(VkSyncValTest, RenderPassAsyncHazard) {
2367 ASSERT_NO_FATAL_FAILURE(InitSyncValFramework());
2368 ASSERT_NO_FATAL_FAILURE(InitState());
2369
2370 // overall set up:
2371 // subpass 0:
2372 // write image 0
2373 // subpass 1:
2374 // read image 0
2375 // write image 1
2376 // subpass 2:
2377 // read image 0
2378 // write image 2
2379 // subpass 3:
2380 // read image 0
2381 // write image 3
2382 //
2383 // subpasses 1 & 2 can run in parallel but both should depend on 0
2384 // subpass 3 must run after 1 & 2 because otherwise the store operation will
2385 // race with the reads in the other subpasses.
2386
2387 constexpr VkFormat kFormat = VK_FORMAT_R8G8B8A8_UNORM;
2388 constexpr uint32_t kWidth = 32, kHeight = 32;
2389 constexpr uint32_t kNumImages = 4;
2390
2391 VkImageCreateInfo src_img_info = {};
2392 src_img_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2393 src_img_info.pNext = NULL;
2394 src_img_info.flags = 0;
2395 src_img_info.imageType = VK_IMAGE_TYPE_2D;
2396 src_img_info.format = kFormat;
2397 src_img_info.extent = {kWidth, kHeight, 1};
2398 src_img_info.mipLevels = 1;
2399 src_img_info.arrayLayers = 1;
2400 src_img_info.samples = VK_SAMPLE_COUNT_2_BIT;
2401 src_img_info.tiling = VK_IMAGE_TILING_OPTIMAL;
2402 src_img_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
2403 src_img_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2404 src_img_info.queueFamilyIndexCount = 0;
2405 src_img_info.pQueueFamilyIndices = nullptr;
2406 src_img_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2407
2408 VkImageCreateInfo dst_img_info = {};
2409 dst_img_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2410 dst_img_info.pNext = nullptr;
2411 dst_img_info.flags = 0;
2412 dst_img_info.imageType = VK_IMAGE_TYPE_2D;
2413 dst_img_info.format = kFormat;
2414 dst_img_info.extent = {kWidth, kHeight, 1};
2415 dst_img_info.mipLevels = 1;
2416 dst_img_info.arrayLayers = 1;
2417 dst_img_info.samples = VK_SAMPLE_COUNT_1_BIT;
2418 dst_img_info.tiling = VK_IMAGE_TILING_OPTIMAL;
2419 dst_img_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
2420 dst_img_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2421 dst_img_info.queueFamilyIndexCount = 0;
2422 dst_img_info.pQueueFamilyIndices = nullptr;
2423 dst_img_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2424
2425 std::vector<std::unique_ptr<VkImageObj>> images;
2426 for (uint32_t i = 0; i < kNumImages; i++) {
2427 images.emplace_back(new VkImageObj(m_device));
2428 }
2429 images[0]->Init(src_img_info);
2430 for (uint32_t i = 1; i < images.size(); i++) {
2431 images[i]->Init(dst_img_info);
2432 }
2433
2434 std::array<VkImageView, kNumImages> attachments{};
2435 std::array<VkAttachmentDescription, kNumImages> attachment_descriptions{};
2436 std::array<VkAttachmentReference, kNumImages> color_refs{};
2437 std::array<VkImageMemoryBarrier, kNumImages> img_barriers{};
2438
2439 for (uint32_t i = 0; i < attachments.size(); i++) {
2440 attachments[i] = images[i]->targetView(kFormat);
2441 attachment_descriptions[i] = {};
2442 attachment_descriptions[i].flags = 0;
2443 attachment_descriptions[i].format = kFormat;
2444 attachment_descriptions[i].samples = VK_SAMPLE_COUNT_1_BIT;
2445 attachment_descriptions[i].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
2446 attachment_descriptions[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
2447 attachment_descriptions[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
2448 attachment_descriptions[i].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
2449 attachment_descriptions[i].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
2450 attachment_descriptions[i].finalLayout =
2451 (i == 0) ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
2452
2453 color_refs[i] = {i, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
2454
2455 img_barriers[i].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
2456 img_barriers[i].srcAccessMask = 0;
2457 img_barriers[i].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
2458 img_barriers[i].oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2459 img_barriers[i].newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
2460 img_barriers[i].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
2461 img_barriers[i].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
2462 img_barriers[i].image = images[i]->handle();
2463 img_barriers[i].subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS};
2464 }
2465
2466 const VkAttachmentReference input_ref{0u, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};
2467
2468 std::array<std::array<uint32_t, 2>, kNumImages - 1> preserve_subpass{{{2, 3}, {1, 3}, {1, 2}}};
2469
2470 std::array<VkSubpassDescription, kNumImages> subpasses{};
2471
2472 subpasses[0].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
2473 subpasses[0].inputAttachmentCount = 0;
2474 subpasses[0].pInputAttachments = nullptr;
2475 subpasses[0].colorAttachmentCount = 1;
2476 subpasses[0].pColorAttachments = &color_refs[0];
2477
2478 for (uint32_t i = 1; i < subpasses.size(); i++) {
2479 subpasses[i].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
2480 subpasses[i].inputAttachmentCount = 1;
2481 subpasses[i].pInputAttachments = &input_ref;
2482 subpasses[i].colorAttachmentCount = 1;
2483 subpasses[i].pColorAttachments = &color_refs[1];
2484 subpasses[i].preserveAttachmentCount = preserve_subpass[i - 1].size();
2485 subpasses[i].pPreserveAttachments = preserve_subpass[i - 1].data();
2486 }
2487
2488 VkRenderPassCreateInfo renderpass_info = {};
2489 renderpass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
2490 renderpass_info.pNext = nullptr;
2491 renderpass_info.flags = 0;
2492 renderpass_info.attachmentCount = attachment_descriptions.size();
2493 renderpass_info.pAttachments = attachment_descriptions.data();
2494 renderpass_info.subpassCount = subpasses.size();
2495 renderpass_info.pSubpasses = subpasses.data();
2496 renderpass_info.dependencyCount = 0;
2497 renderpass_info.pDependencies = nullptr;
2498
2499 VkFramebufferCreateInfo fbci = {};
2500 fbci.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
2501 fbci.pNext = nullptr;
2502 fbci.flags = 0;
2503 fbci.attachmentCount = attachments.size();
2504 fbci.pAttachments = attachments.data();
2505 fbci.width = kWidth;
2506 fbci.height = kHeight;
2507 fbci.layers = 1;
2508
2509 VkSampler sampler = VK_NULL_HANDLE;
2510 VkSamplerCreateInfo sampler_info = SafeSaneSamplerCreateInfo();
2511 vk::CreateSampler(m_device->device(), &sampler_info, NULL, &sampler);
2512
2513 char const *fsSource =
2514 "#version 450\n"
2515 "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n"
2516 "void main() {\n"
2517 " vec4 color = subpassLoad(x);\n"
2518 "}\n";
2519
2520 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
2521 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
2522
2523 VkClearValue clear = {};
2524 clear.color = m_clear_color;
2525 std::array<VkClearValue, 3> clear_values = {{clear, clear, clear}};
2526
2527 // run the renderpass with no dependencies
2528 {
2529 VkRenderPass rp;
2530 VkFramebuffer fb;
2531 ASSERT_VK_SUCCESS(vk::CreateRenderPass(device(), &renderpass_info, nullptr, &rp));
2532
2533 fbci.renderPass = rp;
2534 ASSERT_VK_SUCCESS(vk::CreateFramebuffer(device(), &fbci, nullptr, &fb));
2535
2536 CreatePipelineHelper g_pipe_0(*this);
2537 g_pipe_0.InitInfo();
2538 g_pipe_0.gp_ci_.renderPass = rp;
2539 g_pipe_0.InitState();
2540 ASSERT_VK_SUCCESS(g_pipe_0.CreateGraphicsPipeline());
2541
2542 CreatePipelineHelper g_pipe_12(*this);
2543 g_pipe_12.InitInfo();
2544 g_pipe_12.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
2545 g_pipe_12.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
2546 g_pipe_12.gp_ci_.renderPass = rp;
2547 g_pipe_12.InitState();
2548 ASSERT_VK_SUCCESS(g_pipe_12.CreateGraphicsPipeline());
2549
2550 g_pipe_12.descriptor_set_->WriteDescriptorImageInfo(0, attachments[0], sampler, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
2551 g_pipe_12.descriptor_set_->UpdateDescriptorSets();
2552
2553 m_commandBuffer->begin();
2554
2555 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
2556 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0, nullptr, img_barriers.size(),
2557 img_barriers.data());
2558
2559 m_renderPassBeginInfo.renderArea = {{0, 0}, {16, 16}};
2560 m_renderPassBeginInfo.pClearValues = clear_values.data();
2561 m_renderPassBeginInfo.clearValueCount = clear_values.size();
2562
2563 m_renderPassBeginInfo.renderArea = {{0, 0}, {kWidth, kHeight}};
2564 m_renderPassBeginInfo.renderPass = rp;
2565 m_renderPassBeginInfo.framebuffer = fb;
2566
2567 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
2568 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_);
2569 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_layout_.handle(), 0,
2570 1, &g_pipe_0.descriptor_set_->set_, 0, NULL);
2571
2572 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
2573
2574 for (uint32_t i = 1; i < subpasses.size(); i++) {
2575 vk::CmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
2576 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_12.pipeline_);
2577 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS,
2578 g_pipe_12.pipeline_layout_.handle(), 0, 1, &g_pipe_12.descriptor_set_->set_, 0, NULL);
2579
2580 // we're racing the writes from subpass 0 with our shader reads
2581 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-READ-RACING-WRITE");
2582 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
2583 m_errorMonitor->VerifyFound();
2584 }
2585
2586 // we should get an error from async checking in both subpasses 2 & 3
2587 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE-RACING-WRITE");
2588 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE-RACING-WRITE");
2589 vk::CmdEndRenderPass(m_commandBuffer->handle());
2590 m_errorMonitor->VerifyFound();
2591
2592 m_commandBuffer->end();
2593
2594 vk::DestroyFramebuffer(device(), fb, nullptr);
2595 vk::DestroyRenderPass(device(), rp, nullptr);
2596 }
2597
2598 // add dependencies from subpass 0 to the others, which are necessary but not sufficient
2599 std::vector<VkSubpassDependency> subpass_dependencies;
2600 for (uint32_t i = 1; i < subpasses.size(); i++) {
2601 VkSubpassDependency dep{0,
2602 i,
2603 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2604 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
2605 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2606 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
2607 0};
2608 subpass_dependencies.push_back(dep);
2609 }
2610 renderpass_info.dependencyCount = subpass_dependencies.size();
2611 renderpass_info.pDependencies = subpass_dependencies.data();
2612
2613 {
2614 VkRenderPass rp;
2615 VkFramebuffer fb;
2616 ASSERT_VK_SUCCESS(vk::CreateRenderPass(device(), &renderpass_info, nullptr, &rp));
2617
2618 fbci.renderPass = rp;
2619 ASSERT_VK_SUCCESS(vk::CreateFramebuffer(device(), &fbci, nullptr, &fb));
2620
2621 CreatePipelineHelper g_pipe_0(*this);
2622 g_pipe_0.InitInfo();
2623 g_pipe_0.gp_ci_.renderPass = rp;
2624 g_pipe_0.InitState();
2625 ASSERT_VK_SUCCESS(g_pipe_0.CreateGraphicsPipeline());
2626
2627 CreatePipelineHelper g_pipe_12(*this);
2628 g_pipe_12.InitInfo();
2629 g_pipe_12.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
2630 g_pipe_12.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
2631 g_pipe_12.gp_ci_.renderPass = rp;
2632 g_pipe_12.InitState();
2633 ASSERT_VK_SUCCESS(g_pipe_12.CreateGraphicsPipeline());
2634
2635 g_pipe_12.descriptor_set_->WriteDescriptorImageInfo(0, attachments[0], sampler, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
2636 g_pipe_12.descriptor_set_->UpdateDescriptorSets();
2637
2638 m_commandBuffer->begin();
2639
2640 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
2641 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0, nullptr, img_barriers.size(),
2642 img_barriers.data());
2643
2644 m_renderPassBeginInfo.renderArea = {{0, 0}, {16, 16}};
2645 m_renderPassBeginInfo.pClearValues = clear_values.data();
2646 m_renderPassBeginInfo.clearValueCount = clear_values.size();
2647
2648 m_renderPassBeginInfo.renderArea = {{0, 0}, {kWidth, kHeight}};
2649 m_renderPassBeginInfo.renderPass = rp;
2650 m_renderPassBeginInfo.framebuffer = fb;
2651
2652 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
2653 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_);
2654 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_layout_.handle(), 0,
2655 1, &g_pipe_0.descriptor_set_->set_, 0, NULL);
2656
2657 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
2658
2659 m_errorMonitor->ExpectSuccess();
2660 for (uint32_t i = 1; i < subpasses.size(); i++) {
2661 vk::CmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
2662 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_12.pipeline_);
2663 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS,
2664 g_pipe_12.pipeline_layout_.handle(), 0, 1, &g_pipe_12.descriptor_set_->set_, 0, NULL);
2665 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
2666 }
2667 m_errorMonitor->VerifyNotFound();
2668 // expect this error because 2 subpasses could try to do the store operation
2669 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE-RACING-WRITE");
2670 // ... and this one because the store could happen during a shader read from another subpass
2671 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SYNC-HAZARD-WRITE-RACING-READ");
2672 vk::CmdEndRenderPass(m_commandBuffer->handle());
2673 m_errorMonitor->VerifyFound();
2674
2675 m_commandBuffer->end();
2676
2677 m_errorMonitor->VerifyFound();
2678 vk::DestroyFramebuffer(device(), fb, nullptr);
2679 vk::DestroyRenderPass(device(), rp, nullptr);
2680 }
2681
2682 // try again with correct dependencies to make subpass 3 depend on 1 & 2
2683 for (uint32_t i = 1; i < (subpasses.size() - 1); i++) {
2684 VkSubpassDependency dep{i,
2685 static_cast<uint32_t>(subpasses.size() - 1),
2686 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2687 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
2688 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2689 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
2690 0};
2691 subpass_dependencies.push_back(dep);
2692 }
2693 renderpass_info.dependencyCount = subpass_dependencies.size();
2694 renderpass_info.pDependencies = subpass_dependencies.data();
2695 {
2696 VkRenderPass rp;
2697 VkFramebuffer fb;
2698 ASSERT_VK_SUCCESS(vk::CreateRenderPass(device(), &renderpass_info, nullptr, &rp));
2699
2700 fbci.renderPass = rp;
2701 ASSERT_VK_SUCCESS(vk::CreateFramebuffer(device(), &fbci, nullptr, &fb));
2702
2703 CreatePipelineHelper g_pipe_0(*this);
2704 g_pipe_0.InitInfo();
2705 g_pipe_0.gp_ci_.renderPass = rp;
2706 g_pipe_0.InitState();
2707 ASSERT_VK_SUCCESS(g_pipe_0.CreateGraphicsPipeline());
2708
2709 CreatePipelineHelper g_pipe_12(*this);
2710 g_pipe_12.InitInfo();
2711 g_pipe_12.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
2712 g_pipe_12.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
2713 g_pipe_12.gp_ci_.renderPass = rp;
2714 g_pipe_12.InitState();
2715 ASSERT_VK_SUCCESS(g_pipe_12.CreateGraphicsPipeline());
2716
2717 g_pipe_12.descriptor_set_->WriteDescriptorImageInfo(0, attachments[0], sampler, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
2718 g_pipe_12.descriptor_set_->UpdateDescriptorSets();
2719
2720 m_errorMonitor->ExpectSuccess();
2721 m_commandBuffer->begin();
2722 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
2723 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0, nullptr, img_barriers.size(),
2724 img_barriers.data());
2725
2726 m_renderPassBeginInfo.renderArea = {{0, 0}, {16, 16}};
2727 m_renderPassBeginInfo.pClearValues = clear_values.data();
2728 m_renderPassBeginInfo.clearValueCount = clear_values.size();
2729
2730 m_renderPassBeginInfo.renderArea = {{0, 0}, {kWidth, kHeight}};
2731 m_renderPassBeginInfo.renderPass = rp;
2732 m_renderPassBeginInfo.framebuffer = fb;
2733
2734 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
2735 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_);
2736 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_0.pipeline_layout_.handle(), 0,
2737 1, &g_pipe_0.descriptor_set_->set_, 0, NULL);
2738
2739 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
2740
2741 for (uint32_t i = 1; i < subpasses.size(); i++) {
2742 vk::CmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
2743 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe_12.pipeline_);
2744 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS,
2745 g_pipe_12.pipeline_layout_.handle(), 0, 1, &g_pipe_12.descriptor_set_->set_, 0, NULL);
2746 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
2747 }
2748
2749 vk::CmdEndRenderPass(m_commandBuffer->handle());
2750
2751 m_commandBuffer->end();
2752
2753 m_errorMonitor->VerifyNotFound();
2754 vk::DestroyFramebuffer(device(), fb, nullptr);
2755 vk::DestroyRenderPass(device(), rp, nullptr);
2756 }
2757}