blob: a6f95e61dba943d5c126ba67bdd7d0c6bbafb743 [file] [log] [blame]
sfricke-samsungef15e482022-01-26 11:32:49 -08001/* Copyright (c) 2020-2022 The Khronos Group Inc.
2 * Copyright (c) 2020-2022 Valve Corporation
3 * Copyright (c) 2020-2022 LunarG, Inc.
Tony-LunarG1dce2392019-10-23 16:49:29 -06004 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 * Author: Tony Barbour <tony@lunarg.com>
18 */
19#pragma once
20#include "chassis.h"
21#include "shader_validation.h"
Jeremy Gebben159b3cc2021-06-03 09:09:03 -060022#include "cmd_buffer_state.h"
Jeremy Gebben5160e032022-03-28 14:57:43 -060023#include "state_tracker.h"
24#include "vk_mem_alloc.h"
25
Jeremy Gebbend177d922021-10-28 13:42:10 -060026class QUEUE_STATE;
Jeremy Gebben159b3cc2021-06-03 09:09:03 -060027
Tony-LunarGb5fae462020-03-05 12:43:25 -070028class UtilDescriptorSetManager {
Tony-LunarG1dce2392019-10-23 16:49:29 -060029 public:
Tony-LunarGb5fae462020-03-05 12:43:25 -070030 UtilDescriptorSetManager(VkDevice device, uint32_t numBindingsInSet);
31 ~UtilDescriptorSetManager();
Tony-LunarG1dce2392019-10-23 16:49:29 -060032
33 VkResult GetDescriptorSet(VkDescriptorPool *desc_pool, VkDescriptorSetLayout ds_layout, VkDescriptorSet *desc_sets);
34 VkResult GetDescriptorSets(uint32_t count, VkDescriptorPool *pool, VkDescriptorSetLayout ds_layout,
35 std::vector<VkDescriptorSet> *desc_sets);
36 void PutBackDescriptorSet(VkDescriptorPool desc_pool, VkDescriptorSet desc_set);
37
38 private:
39 static const uint32_t kItemsPerChunk = 512;
40 struct PoolTracker {
41 uint32_t size;
42 uint32_t used;
43 };
44 VkDevice device;
45 uint32_t numBindingsInSet;
Jeremy Gebbencbf22862021-03-03 12:01:22 -070046 layer_data::unordered_map<VkDescriptorPool, struct PoolTracker> desc_pool_map_;
Tony-LunarG1dce2392019-10-23 16:49:29 -060047};
Tony-LunarGb5fae462020-03-05 12:43:25 -070048struct UtilQueueBarrierCommandInfo {
Tony-LunarG1dce2392019-10-23 16:49:29 -060049 VkCommandPool barrier_command_pool = VK_NULL_HANDLE;
50 VkCommandBuffer barrier_command_buffer = VK_NULL_HANDLE;
51};
Tony-LunarGb5fae462020-03-05 12:43:25 -070052VkResult UtilInitializeVma(VkPhysicalDevice physical_device, VkDevice device, VmaAllocator *pAllocator);
Tony-LunarG1dce2392019-10-23 16:49:29 -060053template <typename ObjectType>
Tony-LunarGb5fae462020-03-05 12:43:25 -070054void UtilPreCallRecordCreatePipelineLayout(create_pipeline_layout_api_state *cpl_state, ObjectType *object_ptr,
55 const VkPipelineLayoutCreateInfo *pCreateInfo) {
Tony-LunarG1dce2392019-10-23 16:49:29 -060056 // Modify the pipeline layout by:
57 // 1. Copying the caller's descriptor set desc_layouts
58 // 2. Fill in dummy descriptor layouts up to the max binding
59 // 3. Fill in with the debug descriptor layout at the max binding slot
60 cpl_state->new_layouts.reserve(object_ptr->adjusted_max_desc_sets);
61 cpl_state->new_layouts.insert(cpl_state->new_layouts.end(), &pCreateInfo->pSetLayouts[0],
62 &pCreateInfo->pSetLayouts[pCreateInfo->setLayoutCount]);
63 for (uint32_t i = pCreateInfo->setLayoutCount; i < object_ptr->adjusted_max_desc_sets - 1; ++i) {
64 cpl_state->new_layouts.push_back(object_ptr->dummy_desc_layout);
65 }
66 cpl_state->new_layouts.push_back(object_ptr->debug_desc_layout);
67 cpl_state->modified_create_info.pSetLayouts = cpl_state->new_layouts.data();
68 cpl_state->modified_create_info.setLayoutCount = object_ptr->adjusted_max_desc_sets;
69}
70
71template <typename CreateInfo>
72struct CreatePipelineTraits {};
73template <>
74struct CreatePipelineTraits<VkGraphicsPipelineCreateInfo> {
75 using SafeType = safe_VkGraphicsPipelineCreateInfo;
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -070076 static const SafeType &GetPipelineCI(const PIPELINE_STATE *pipeline_state) {
77 return pipeline_state->GetUnifiedCreateInfo().graphics;
78 }
Tony-LunarG1dce2392019-10-23 16:49:29 -060079 static uint32_t GetStageCount(const VkGraphicsPipelineCreateInfo &createInfo) { return createInfo.stageCount; }
80 static VkShaderModule GetShaderModule(const VkGraphicsPipelineCreateInfo &createInfo, uint32_t stage) {
81 return createInfo.pStages[stage].module;
82 }
83 static void SetShaderModule(SafeType *createInfo, VkShaderModule shader_module, uint32_t stage) {
84 createInfo->pStages[stage].module = shader_module;
85 }
86};
87
88template <>
89struct CreatePipelineTraits<VkComputePipelineCreateInfo> {
90 using SafeType = safe_VkComputePipelineCreateInfo;
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -070091 static const SafeType &GetPipelineCI(const PIPELINE_STATE *pipeline_state) {
92 return pipeline_state->GetUnifiedCreateInfo().compute;
93 }
Tony-LunarG1dce2392019-10-23 16:49:29 -060094 static uint32_t GetStageCount(const VkComputePipelineCreateInfo &createInfo) { return 1; }
95 static VkShaderModule GetShaderModule(const VkComputePipelineCreateInfo &createInfo, uint32_t stage) {
96 return createInfo.stage.module;
97 }
98 static void SetShaderModule(SafeType *createInfo, VkShaderModule shader_module, uint32_t stage) {
99 assert(stage == 0);
100 createInfo->stage.module = shader_module;
101 }
102};
103
104template <>
105struct CreatePipelineTraits<VkRayTracingPipelineCreateInfoNV> {
106 using SafeType = safe_VkRayTracingPipelineCreateInfoCommon;
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -0700107 static const SafeType &GetPipelineCI(const PIPELINE_STATE *pipeline_state) {
108 return pipeline_state->GetUnifiedCreateInfo().raytracing;
109 }
Tony-LunarG1dce2392019-10-23 16:49:29 -0600110 static uint32_t GetStageCount(const VkRayTracingPipelineCreateInfoNV &createInfo) { return createInfo.stageCount; }
111 static VkShaderModule GetShaderModule(const VkRayTracingPipelineCreateInfoNV &createInfo, uint32_t stage) {
112 return createInfo.pStages[stage].module;
113 }
114 static void SetShaderModule(SafeType *createInfo, VkShaderModule shader_module, uint32_t stage) {
115 createInfo->pStages[stage].module = shader_module;
116 }
117};
118
119template <>
120struct CreatePipelineTraits<VkRayTracingPipelineCreateInfoKHR> {
121 using SafeType = safe_VkRayTracingPipelineCreateInfoCommon;
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -0700122 static const SafeType &GetPipelineCI(const PIPELINE_STATE *pipeline_state) {
123 return pipeline_state->GetUnifiedCreateInfo().raytracing;
124 }
Tony-LunarG1dce2392019-10-23 16:49:29 -0600125 static uint32_t GetStageCount(const VkRayTracingPipelineCreateInfoKHR &createInfo) { return createInfo.stageCount; }
126 static VkShaderModule GetShaderModule(const VkRayTracingPipelineCreateInfoKHR &createInfo, uint32_t stage) {
127 return createInfo.pStages[stage].module;
128 }
129 static void SetShaderModule(SafeType *createInfo, VkShaderModule shader_module, uint32_t stage) {
130 createInfo->pStages[stage].module = shader_module;
131 }
132};
133
134// Examine the pipelines to see if they use the debug descriptor set binding index.
135// If any do, create new non-instrumented shader modules and use them to replace the instrumented
136// shaders in the pipeline. Return the (possibly) modified create infos to the caller.
137template <typename CreateInfo, typename SafeCreateInfo, typename ObjectType>
Tony-LunarGb5fae462020-03-05 12:43:25 -0700138void UtilPreCallRecordPipelineCreations(uint32_t count, const CreateInfo *pCreateInfos, const VkAllocationCallbacks *pAllocator,
139 VkPipeline *pPipelines, std::vector<std::shared_ptr<PIPELINE_STATE>> &pipe_state,
140 std::vector<SafeCreateInfo> *new_pipeline_create_infos,
141 const VkPipelineBindPoint bind_point, ObjectType *object_ptr) {
Tony-LunarG1dce2392019-10-23 16:49:29 -0600142 using Accessor = CreatePipelineTraits<CreateInfo>;
143 if (bind_point != VK_PIPELINE_BIND_POINT_GRAPHICS && bind_point != VK_PIPELINE_BIND_POINT_COMPUTE &&
144 bind_point != VK_PIPELINE_BIND_POINT_RAY_TRACING_NV) {
145 return;
146 }
147
148 // Walk through all the pipelines, make a copy of each and flag each pipeline that contains a shader that uses the debug
149 // descriptor set index.
150 for (uint32_t pipeline = 0; pipeline < count; ++pipeline) {
151 uint32_t stageCount = Accessor::GetStageCount(pCreateInfos[pipeline]);
152 new_pipeline_create_infos->push_back(Accessor::GetPipelineCI(pipe_state[pipeline].get()));
Nathaniel Cesariobcb79682022-03-31 21:13:52 -0600153 const auto &pipe = pipe_state[pipeline];
Tony-LunarG1dce2392019-10-23 16:49:29 -0600154
Nathaniel Cesariobcb79682022-03-31 21:13:52 -0600155 if (!pipe->IsGraphicsLibrary()) {
156 bool replace_shaders = false;
157 if (pipe->active_slots.find(object_ptr->desc_set_bind_index) != pipe->active_slots.end()) {
158 replace_shaders = true;
159 }
160 // If the app requests all available sets, the pipeline layout was not modified at pipeline layout creation and the
161 // already instrumented shaders need to be replaced with uninstrumented shaders
162 const auto pipeline_layout = pipe->PipelineLayoutState();
163 if (pipeline_layout->set_layouts.size() >= object_ptr->adjusted_max_desc_sets) {
164 replace_shaders = true;
165 }
Tony-LunarG1dce2392019-10-23 16:49:29 -0600166
Nathaniel Cesariobcb79682022-03-31 21:13:52 -0600167 if (replace_shaders) {
168 for (uint32_t stage = 0; stage < stageCount; ++stage) {
169 const auto module_state =
170 object_ptr->template Get<SHADER_MODULE_STATE>(Accessor::GetShaderModule(pCreateInfos[pipeline], stage));
Tony-LunarG1dce2392019-10-23 16:49:29 -0600171
Nathaniel Cesariobcb79682022-03-31 21:13:52 -0600172 VkShaderModule shader_module;
173 auto create_info = LvlInitStruct<VkShaderModuleCreateInfo>();
174 create_info.pCode = module_state->words.data();
175 create_info.codeSize = module_state->words.size() * sizeof(uint32_t);
176 VkResult result = DispatchCreateShaderModule(object_ptr->device, &create_info, pAllocator, &shader_module);
177 if (result == VK_SUCCESS) {
178 Accessor::SetShaderModule(&(*new_pipeline_create_infos)[pipeline], shader_module, stage);
179 } else {
180 object_ptr->ReportSetupProblem(object_ptr->device,
181 "Unable to replace instrumented shader with non-instrumented one. "
182 "Device could become unstable.");
183 }
Tony-LunarG1dce2392019-10-23 16:49:29 -0600184 }
185 }
186 }
187 }
188}
189// For every pipeline:
190// - For every shader in a pipeline:
191// - If the shader had to be replaced in PreCallRecord (because the pipeline is using the debug desc set index):
192// - Destroy it since it has been bound into the pipeline by now. This is our only chance to delete it.
193// - Track the shader in the shader_map
194// - Save the shader binary if it contains debug code
195template <typename CreateInfo, typename ObjectType>
Tony-LunarGb5fae462020-03-05 12:43:25 -0700196void UtilPostCallRecordPipelineCreations(const uint32_t count, const CreateInfo *pCreateInfos,
aitor-lunarg3c145292022-03-25 17:30:11 +0100197 const VkAllocationCallbacks *pAllocator, const VkPipeline *pPipelines,
Tony-LunarGb5fae462020-03-05 12:43:25 -0700198 const VkPipelineBindPoint bind_point, ObjectType *object_ptr) {
Tony-LunarG1dce2392019-10-23 16:49:29 -0600199 using Accessor = CreatePipelineTraits<CreateInfo>;
200 if (bind_point != VK_PIPELINE_BIND_POINT_GRAPHICS && bind_point != VK_PIPELINE_BIND_POINT_COMPUTE &&
201 bind_point != VK_PIPELINE_BIND_POINT_RAY_TRACING_NV) {
202 return;
203 }
204 for (uint32_t pipeline = 0; pipeline < count; ++pipeline) {
Jeremy Gebbenb20a8242021-11-05 15:14:43 -0600205 auto pipeline_state = object_ptr->template Get<PIPELINE_STATE>(pPipelines[pipeline]);
Nathaniel Cesariobcb79682022-03-31 21:13:52 -0600206 if (!pipeline_state || pipeline_state->IsGraphicsLibrary()) continue;
Tony-LunarG1dce2392019-10-23 16:49:29 -0600207
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -0700208 const uint32_t stageCount = static_cast<uint32_t>(pipeline_state->stage_state.size());
209 assert(stageCount > 0);
Tony-LunarG1dce2392019-10-23 16:49:29 -0600210
211 for (uint32_t stage = 0; stage < stageCount; ++stage) {
212 if (pipeline_state->active_slots.find(object_ptr->desc_set_bind_index) != pipeline_state->active_slots.end()) {
213 DispatchDestroyShaderModule(object_ptr->device, Accessor::GetShaderModule(pCreateInfos[pipeline], stage),
214 pAllocator);
215 }
216
sfricke-samsungef15e482022-01-26 11:32:49 -0800217 std::shared_ptr<const SHADER_MODULE_STATE> module_state;
Tony-LunarG1dce2392019-10-23 16:49:29 -0600218 if (bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS) {
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -0700219 module_state = object_ptr->template Get<SHADER_MODULE_STATE>(
220 pipeline_state->GetUnifiedCreateInfo().graphics.pStages[stage].module);
Tony-LunarG1dce2392019-10-23 16:49:29 -0600221 } else if (bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) {
222 assert(stage == 0);
sfricke-samsungef15e482022-01-26 11:32:49 -0800223 module_state =
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -0700224 object_ptr->template Get<SHADER_MODULE_STATE>(pipeline_state->GetUnifiedCreateInfo().compute.stage.module);
225 } else if (bind_point == VK_PIPELINE_BIND_POINT_RAY_TRACING_NV) {
226 module_state = object_ptr->template Get<SHADER_MODULE_STATE>(
227 pipeline_state->GetUnifiedCreateInfo().raytracing.pStages[stage].module);
Tony-LunarG1dce2392019-10-23 16:49:29 -0600228 } else {
229 assert(false);
230 }
231
232 std::vector<unsigned int> code;
233 // Save the shader binary
234 // The core_validation ShaderModule tracker saves the binary too, but discards it when the ShaderModule
235 // is destroyed. Applications may destroy ShaderModules after they are placed in a pipeline and before
236 // the pipeline is used, so we have to keep another copy.
sfricke-samsungef15e482022-01-26 11:32:49 -0800237 if (module_state && module_state->has_valid_spirv) code = module_state->words;
Tony-LunarG1dce2392019-10-23 16:49:29 -0600238
sfricke-samsungef15e482022-01-26 11:32:49 -0800239 object_ptr->shader_map[module_state->gpu_validation_shader_id].pipeline = pipeline_state->pipeline();
Tony-LunarG1dce2392019-10-23 16:49:29 -0600240 // Be careful to use the originally bound (instrumented) shader here, even if PreCallRecord had to back it
241 // out with a non-instrumented shader. The non-instrumented shader (found in pCreateInfo) was destroyed above.
242 VkShaderModule shader_module = VK_NULL_HANDLE;
243 if (bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS) {
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -0700244 shader_module = pipeline_state->GetUnifiedCreateInfo().graphics.pStages[stage].module;
Tony-LunarG1dce2392019-10-23 16:49:29 -0600245 } else if (bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) {
246 assert(stage == 0);
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -0700247 shader_module = pipeline_state->GetUnifiedCreateInfo().compute.stage.module;
Tony-LunarG1dce2392019-10-23 16:49:29 -0600248 } else if (bind_point == VK_PIPELINE_BIND_POINT_RAY_TRACING_NV) {
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -0700249 shader_module = pipeline_state->GetUnifiedCreateInfo().raytracing.pStages[stage].module;
Tony-LunarG1dce2392019-10-23 16:49:29 -0600250 } else {
251 assert(false);
252 }
sfricke-samsungef15e482022-01-26 11:32:49 -0800253 object_ptr->shader_map[module_state->gpu_validation_shader_id].shader_module = shader_module;
254 object_ptr->shader_map[module_state->gpu_validation_shader_id].pgm = std::move(code);
Tony-LunarG1dce2392019-10-23 16:49:29 -0600255 }
256 }
257}
Tony-LunarGc876c6e2020-09-09 15:19:43 -0600258template <typename CreateInfos, typename SafeCreateInfos>
259void UtilCopyCreatePipelineFeedbackData(const uint32_t count, CreateInfos *pCreateInfos, SafeCreateInfos *pSafeCreateInfos) {
260 for (uint32_t i = 0; i < count; i++) {
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700261 auto src_feedback_struct = LvlFindInChain<VkPipelineCreationFeedbackCreateInfoEXT>(pSafeCreateInfos[i].pNext);
Tony-LunarGc876c6e2020-09-09 15:19:43 -0600262 if (!src_feedback_struct) return;
263 auto dst_feedback_struct = const_cast<VkPipelineCreationFeedbackCreateInfoEXT *>(
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700264 LvlFindInChain<VkPipelineCreationFeedbackCreateInfoEXT>(pCreateInfos[i].pNext));
Tony-LunarGc876c6e2020-09-09 15:19:43 -0600265 *dst_feedback_struct->pPipelineCreationFeedback = *src_feedback_struct->pPipelineCreationFeedback;
266 for (uint32_t j = 0; j < src_feedback_struct->pipelineStageCreationFeedbackCount; j++) {
267 dst_feedback_struct->pPipelineStageCreationFeedbacks[j] = src_feedback_struct->pPipelineStageCreationFeedbacks[j];
268 }
269 }
270}
271
Tony-LunarG1dce2392019-10-23 16:49:29 -0600272template <typename ObjectType>
273// For the given command buffer, map its debug data buffers and read their contents for analysis.
Tony-LunarGb5fae462020-03-05 12:43:25 -0700274void UtilProcessInstrumentationBuffer(VkQueue queue, CMD_BUFFER_STATE *cb_node, ObjectType *object_ptr) {
Tony-LunarG1dce2392019-10-23 16:49:29 -0600275 if (cb_node && (cb_node->hasDrawCmd || cb_node->hasTraceRaysCmd || cb_node->hasDispatchCmd)) {
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600276 auto gpu_buffer_list = object_ptr->GetBufferInfo(cb_node);
Tony-LunarG1dce2392019-10-23 16:49:29 -0600277 uint32_t draw_index = 0;
278 uint32_t compute_index = 0;
279 uint32_t ray_trace_index = 0;
280
281 for (auto &buffer_info : gpu_buffer_list) {
282 char *pData;
283
284 uint32_t operation_index = 0;
285 if (buffer_info.pipeline_bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS) {
286 operation_index = draw_index;
287 } else if (buffer_info.pipeline_bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) {
288 operation_index = compute_index;
289 } else if (buffer_info.pipeline_bind_point == VK_PIPELINE_BIND_POINT_RAY_TRACING_NV) {
290 operation_index = ray_trace_index;
291 } else {
292 assert(false);
293 }
294
295 VkResult result = vmaMapMemory(object_ptr->vmaAllocator, buffer_info.output_mem_block.allocation, (void **)&pData);
296 if (result == VK_SUCCESS) {
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -0600297 object_ptr->AnalyzeAndGenerateMessages(cb_node->commandBuffer(), queue, buffer_info,
Tony-LunarG1dce2392019-10-23 16:49:29 -0600298 operation_index, (uint32_t *)pData);
299 vmaUnmapMemory(object_ptr->vmaAllocator, buffer_info.output_mem_block.allocation);
300 }
301
302 if (buffer_info.pipeline_bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS) {
303 draw_index++;
304 } else if (buffer_info.pipeline_bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) {
305 compute_index++;
306 } else if (buffer_info.pipeline_bind_point == VK_PIPELINE_BIND_POINT_RAY_TRACING_NV) {
307 ray_trace_index++;
308 } else {
309 assert(false);
310 }
311 }
312 }
313}
314template <typename ObjectType>
315// Submit a memory barrier on graphics queues.
316// Lazy-create and record the needed command buffer.
Tony-LunarGb5fae462020-03-05 12:43:25 -0700317void UtilSubmitBarrier(VkQueue queue, ObjectType *object_ptr) {
318 auto queue_barrier_command_info_it = object_ptr->queue_barrier_command_infos.emplace(queue, UtilQueueBarrierCommandInfo{});
Tony-LunarG1dce2392019-10-23 16:49:29 -0600319 if (queue_barrier_command_info_it.second) {
Tony-LunarGb5fae462020-03-05 12:43:25 -0700320 UtilQueueBarrierCommandInfo &queue_barrier_command_info = queue_barrier_command_info_it.first->second;
Tony-LunarG1dce2392019-10-23 16:49:29 -0600321
322 uint32_t queue_family_index = 0;
323
Jeremy Gebben9f537102021-10-05 16:37:12 -0600324 auto queue_state = object_ptr->ValidationStateTracker::template Get<QUEUE_STATE>(queue);
Jeremy Gebbend177d922021-10-28 13:42:10 -0600325 if (queue_state) {
326 queue_family_index = queue_state->queueFamilyIndex;
Tony-LunarG1dce2392019-10-23 16:49:29 -0600327 }
328
329 VkResult result = VK_SUCCESS;
330
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600331 auto pool_create_info = LvlInitStruct<VkCommandPoolCreateInfo>();
Tony-LunarG1dce2392019-10-23 16:49:29 -0600332 pool_create_info.queueFamilyIndex = queue_family_index;
333 result = DispatchCreateCommandPool(object_ptr->device, &pool_create_info, nullptr,
334 &queue_barrier_command_info.barrier_command_pool);
335 if (result != VK_SUCCESS) {
336 object_ptr->ReportSetupProblem(object_ptr->device, "Unable to create command pool for barrier CB.");
337 queue_barrier_command_info.barrier_command_pool = VK_NULL_HANDLE;
338 return;
339 }
340
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600341 auto buffer_alloc_info = LvlInitStruct<VkCommandBufferAllocateInfo>();
Tony-LunarG1dce2392019-10-23 16:49:29 -0600342 buffer_alloc_info.commandPool = queue_barrier_command_info.barrier_command_pool;
343 buffer_alloc_info.commandBufferCount = 1;
344 buffer_alloc_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
345 result = DispatchAllocateCommandBuffers(object_ptr->device, &buffer_alloc_info,
346 &queue_barrier_command_info.barrier_command_buffer);
347 if (result != VK_SUCCESS) {
348 object_ptr->ReportSetupProblem(object_ptr->device, "Unable to create barrier command buffer.");
349 DispatchDestroyCommandPool(object_ptr->device, queue_barrier_command_info.barrier_command_pool, nullptr);
350 queue_barrier_command_info.barrier_command_pool = VK_NULL_HANDLE;
351 queue_barrier_command_info.barrier_command_buffer = VK_NULL_HANDLE;
352 return;
353 }
354
355 // Hook up command buffer dispatch
356 object_ptr->vkSetDeviceLoaderData(object_ptr->device, queue_barrier_command_info.barrier_command_buffer);
357
358 // Record a global memory barrier to force availability of device memory operations to the host domain.
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600359 auto command_buffer_begin_info = LvlInitStruct<VkCommandBufferBeginInfo>();
Tony-LunarG1dce2392019-10-23 16:49:29 -0600360 result = DispatchBeginCommandBuffer(queue_barrier_command_info.barrier_command_buffer, &command_buffer_begin_info);
361 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600362 auto memory_barrier = LvlInitStruct<VkMemoryBarrier>();
Tony-LunarG1dce2392019-10-23 16:49:29 -0600363 memory_barrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
364 memory_barrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT;
365
366 DispatchCmdPipelineBarrier(queue_barrier_command_info.barrier_command_buffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
367 VK_PIPELINE_STAGE_HOST_BIT, 0, 1, &memory_barrier, 0, nullptr, 0, nullptr);
368 DispatchEndCommandBuffer(queue_barrier_command_info.barrier_command_buffer);
369 }
370 }
371
Tony-LunarGb5fae462020-03-05 12:43:25 -0700372 UtilQueueBarrierCommandInfo &queue_barrier_command_info = queue_barrier_command_info_it.first->second;
Tony-LunarG1dce2392019-10-23 16:49:29 -0600373 if (queue_barrier_command_info.barrier_command_buffer != VK_NULL_HANDLE) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600374 auto submit_info = LvlInitStruct<VkSubmitInfo>();
Tony-LunarG1dce2392019-10-23 16:49:29 -0600375 submit_info.commandBufferCount = 1;
376 submit_info.pCommandBuffers = &queue_barrier_command_info.barrier_command_buffer;
377 DispatchQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
378 }
379}
Tony-LunarGb5fae462020-03-05 12:43:25 -0700380void UtilGenerateStageMessage(const uint32_t *debug_record, std::string &msg);
381void UtilGenerateCommonMessage(const debug_report_data *report_data, const VkCommandBuffer commandBuffer,
382 const uint32_t *debug_record, const VkShaderModule shader_module_handle,
383 const VkPipeline pipeline_handle, const VkPipelineBindPoint pipeline_bind_point,
384 const uint32_t operation_index, std::string &msg);
sfricke-samsung7fac88a2022-01-26 11:44:22 -0800385void UtilGenerateSourceMessages(const std::vector<uint32_t> &pgm, const uint32_t *debug_record, bool from_printf,
Tony-LunarGb5fae462020-03-05 12:43:25 -0700386 std::string &filename_msg, std::string &source_msg);
Jeremy Gebben5160e032022-03-28 14:57:43 -0600387
388struct GpuAssistedShaderTracker {
389 VkPipeline pipeline;
390 VkShaderModule shader_module;
391 std::vector<uint32_t> pgm;
392};
393
394class GpuAssistedBase : public ValidationStateTracker {
395 public:
Jeremy Gebben33717862022-03-28 15:53:56 -0600396 void PreCallRecordCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
397 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice, void *modified_create_info) override;
398 void CreateDevice(const VkDeviceCreateInfo *pCreateInfo) override;
399
400 void PreCallRecordDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) override;
401
402 template <typename T>
403 void ReportSetupProblem(T object, const char *const specific_message) const {
404 LogError(object, setup_vuid, "Setup Error. Detail: (%s)", specific_message);
405 }
406
Jeremy Gebben5160e032022-03-28 14:57:43 -0600407 bool aborted = false;
408 const char *setup_vuid;
409 VkPhysicalDeviceFeatures supported_features{};
410 VkPhysicalDeviceFeatures desired_features{};
411 uint32_t adjusted_max_desc_sets = 0;
412 uint32_t unique_shader_module_id = 0;
413 uint32_t output_buffer_size = 0;
414 VkDescriptorSetLayout debug_desc_layout = VK_NULL_HANDLE;
415 VkDescriptorSetLayout dummy_desc_layout = VK_NULL_HANDLE;
416 uint32_t desc_set_bind_index = 0;
417 VmaAllocator vmaAllocator = {};
418 std::map<VkQueue, UtilQueueBarrierCommandInfo> queue_barrier_command_infos;
419 std::unique_ptr<UtilDescriptorSetManager> desc_set_manager;
420 PFN_vkSetDeviceLoaderData vkSetDeviceLoaderData;
421 layer_data::unordered_map<uint32_t, GpuAssistedShaderTracker> shader_map;
422 std::vector<VkDescriptorSetLayoutBinding> bindings_;
423};
424