blob: 278f73fbb5a500bcfd7af9d8cd07dcaa3fb03b36 [file] [log] [blame]
Tony-LunarG4c253372022-01-18 13:51:07 -07001/* Copyright (c) 2020-2022 The Khronos Group Inc.
2 * Copyright (c) 2020-2022 Valve Corporation
3 * Copyright (c) 2020-2022 LunarG, Inc.
Tony-LunarG04717522019-10-17 10:41:17 -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
Tony-LunarGb5fae462020-03-05 12:43:25 -070020#include "debug_printf.h"
Tony-LunarG04717522019-10-17 10:41:17 -060021#include "spirv-tools/optimizer.hpp"
22#include "spirv-tools/instrument.hpp"
23#include <iostream>
Tony-LunarG04717522019-10-17 10:41:17 -060024#include "layer_chassis_dispatch.h"
Jeremy Gebbena3705f42021-01-19 16:47:43 -070025#include "sync_utils.h"
Jeremy Gebben159b3cc2021-06-03 09:09:03 -060026#include "cmd_buffer_state.h"
Tony-LunarG04717522019-10-17 10:41:17 -060027
Tony-LunarG04717522019-10-17 10:41:17 -060028static const VkShaderStageFlags kShaderStageAllRayTracing =
29 VK_SHADER_STAGE_ANY_HIT_BIT_NV | VK_SHADER_STAGE_CALLABLE_BIT_NV | VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV |
30 VK_SHADER_STAGE_INTERSECTION_BIT_NV | VK_SHADER_STAGE_MISS_BIT_NV | VK_SHADER_STAGE_RAYGEN_BIT_NV;
31
Tony-LunarG04717522019-10-17 10:41:17 -060032// Perform initializations that can be done at Create Device time.
Jeremy Gebben36a3b832022-03-23 10:54:18 -060033void DebugPrintf::CreateDevice(const VkDeviceCreateInfo *pCreateInfo) {
Jeremy Gebben33717862022-03-28 15:53:56 -060034 if (enabled[gpu_validation]) {
35 ReportSetupProblem(device,
36 "Debug Printf cannot be enabled when gpu assisted validation is enabled. "
37 "Debug Printf disabled.");
38 aborted = true;
39 return;
40 }
Tony-LunarG43416b42019-10-31 16:47:24 -060041
42 const char *size_string = getLayerOption("khronos_validation.printf_buffer_size");
Jeremy Gebben36a3b832022-03-23 10:54:18 -060043 output_buffer_size = *size_string ? atoi(size_string) : 1024;
Tony-LunarGc99dbef2021-06-14 15:11:50 -060044
45 std::string verbose_string = getLayerOption("khronos_validation.printf_verbose");
46 transform(verbose_string.begin(), verbose_string.end(), verbose_string.begin(), ::tolower);
Jeremy Gebben36a3b832022-03-23 10:54:18 -060047 verbose = verbose_string.length() ? !verbose_string.compare("true") : false;
Tony-LunarGc99dbef2021-06-14 15:11:50 -060048
49 std::string stdout_string = getLayerOption("khronos_validation.printf_to_stdout");
50 transform(stdout_string.begin(), stdout_string.end(), stdout_string.begin(), ::tolower);
Jeremy Gebben36a3b832022-03-23 10:54:18 -060051 use_stdout = stdout_string.length() ? !stdout_string.compare("true") : false;
52 if (getenv("DEBUG_PRINTF_TO_STDOUT")) use_stdout = true;
Tony-LunarG04717522019-10-17 10:41:17 -060053
Jeremy Gebben33717862022-03-28 15:53:56 -060054 // GpuAssistedBase::CreateDevice will set up bindings
55 VkDescriptorSetLayoutBinding binding = {3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
56 VK_SHADER_STAGE_ALL_GRAPHICS | VK_SHADER_STAGE_MESH_BIT_NV |
57 VK_SHADER_STAGE_TASK_BIT_NV | VK_SHADER_STAGE_COMPUTE_BIT |
58 kShaderStageAllRayTracing,
59 NULL};
60 bindings_.push_back(binding);
61
62 GpuAssistedBase::CreateDevice(pCreateInfo);
63
Jeremy Gebben36a3b832022-03-23 10:54:18 -060064 if (phys_dev_props.apiVersion < VK_API_VERSION_1_1) {
Tony-LunarGbbbed672020-03-04 10:51:11 -070065 ReportSetupProblem(device, "Debug Printf requires Vulkan 1.1 or later. Debug Printf disabled.");
Jeremy Gebben36a3b832022-03-23 10:54:18 -060066 aborted = true;
Tony-LunarG04717522019-10-17 10:41:17 -060067 return;
68 }
69
Jeremy Gebben36a3b832022-03-23 10:54:18 -060070 DispatchGetPhysicalDeviceFeatures(physical_device, &supported_features);
Tony-LunarG04717522019-10-17 10:41:17 -060071 if (!supported_features.fragmentStoresAndAtomics || !supported_features.vertexPipelineStoresAndAtomics) {
Tony-LunarG1dce2392019-10-23 16:49:29 -060072 ReportSetupProblem(device,
Tony-LunarGbbbed672020-03-04 10:51:11 -070073 "Debug Printf requires fragmentStoresAndAtomics and vertexPipelineStoresAndAtomics. "
74 "Debug Printf disabled.");
Jeremy Gebben36a3b832022-03-23 10:54:18 -060075 aborted = true;
Tony-LunarG04717522019-10-17 10:41:17 -060076 return;
77 }
Tony-LunarG9586e732020-03-04 10:50:30 -070078
Tony-LunarG04717522019-10-17 10:41:17 -060079}
80
81// Modify the pipeline layout to include our debug descriptor set and any needed padding with the dummy descriptor set.
Tony-LunarGb5fae462020-03-05 12:43:25 -070082void DebugPrintf::PreCallRecordCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo,
83 const VkAllocationCallbacks *pAllocator, VkPipelineLayout *pPipelineLayout,
84 void *cpl_state_data) {
Tony-LunarG04717522019-10-17 10:41:17 -060085 if (aborted) {
86 return;
87 }
88
89 create_pipeline_layout_api_state *cpl_state = reinterpret_cast<create_pipeline_layout_api_state *>(cpl_state_data);
90
91 if (cpl_state->modified_create_info.setLayoutCount >= adjusted_max_desc_sets) {
92 std::ostringstream strm;
93 strm << "Pipeline Layout conflict with validation's descriptor set at slot " << desc_set_bind_index << ". "
Tony-LunarGbbbed672020-03-04 10:51:11 -070094 << "Application has too many descriptor sets in the pipeline layout to continue with debug printf. "
Tony-LunarG04717522019-10-17 10:41:17 -060095 << "Not modifying the pipeline layout. "
96 << "Instrumented shaders are replaced with non-instrumented shaders.";
Tony-LunarG1dce2392019-10-23 16:49:29 -060097 ReportSetupProblem(device, strm.str().c_str());
Tony-LunarG04717522019-10-17 10:41:17 -060098 } else {
Tony-LunarGb5fae462020-03-05 12:43:25 -070099 UtilPreCallRecordCreatePipelineLayout(cpl_state, this, pCreateInfo);
Tony-LunarG04717522019-10-17 10:41:17 -0600100 }
101}
102
Tony-LunarGb5fae462020-03-05 12:43:25 -0700103void DebugPrintf::PostCallRecordCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo,
104 const VkAllocationCallbacks *pAllocator, VkPipelineLayout *pPipelineLayout,
105 VkResult result) {
Tony-LunarG04717522019-10-17 10:41:17 -0600106 ValidationStateTracker::PostCallRecordCreatePipelineLayout(device, pCreateInfo, pAllocator, pPipelineLayout, result);
107 if (result != VK_SUCCESS) {
Tony-LunarG1dce2392019-10-23 16:49:29 -0600108 ReportSetupProblem(device, "Unable to create pipeline layout. Device could become unstable.");
Tony-LunarG04717522019-10-17 10:41:17 -0600109 aborted = true;
110 }
111}
112
113// Free the device memory and descriptor set associated with a command buffer.
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600114void DebugPrintf::DestroyBuffer(DPFBufferInfo &buffer_info) {
115 vmaDestroyBuffer(vmaAllocator, buffer_info.output_mem_block.buffer, buffer_info.output_mem_block.allocation);
116 if (buffer_info.desc_set != VK_NULL_HANDLE) {
117 desc_set_manager->PutBackDescriptorSet(buffer_info.desc_pool, buffer_info.desc_set);
Tony-LunarG04717522019-10-17 10:41:17 -0600118 }
Tony-LunarG04717522019-10-17 10:41:17 -0600119}
120
121// Just gives a warning about a possible deadlock.
Tony-LunarGb5fae462020-03-05 12:43:25 -0700122bool DebugPrintf::PreCallValidateCmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
123 VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask,
124 uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
125 uint32_t bufferMemoryBarrierCount,
126 const VkBufferMemoryBarrier *pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount,
127 const VkImageMemoryBarrier *pImageMemoryBarriers) const {
Tony-LunarG04717522019-10-17 10:41:17 -0600128 if (srcStageMask & VK_PIPELINE_STAGE_HOST_BIT) {
Tony-LunarG1dce2392019-10-23 16:49:29 -0600129 ReportSetupProblem(commandBuffer,
130 "CmdWaitEvents recorded with VK_PIPELINE_STAGE_HOST_BIT set. "
Tony-LunarGbbbed672020-03-04 10:51:11 -0700131 "Debug Printf waits on queue completion. "
Tony-LunarG1dce2392019-10-23 16:49:29 -0600132 "This wait could block the host's signaling of this event, resulting in deadlock.");
Tony-LunarG04717522019-10-17 10:41:17 -0600133 }
134 return false;
135}
136
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700137bool DebugPrintf::PreCallValidateCmdWaitEvents2KHR(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
138 const VkDependencyInfoKHR *pDependencyInfos) const {
Jeremy Gebbenf18d4362022-01-27 14:37:25 -0700139 VkPipelineStageFlags2KHR src_stage_mask = 0;
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700140
141 for (uint32_t i = 0; i < eventCount; i++) {
142 auto stage_masks = sync_utils::GetGlobalStageMasks(pDependencyInfos[i]);
Jeremy Gebbenf18d4362022-01-27 14:37:25 -0700143 src_stage_mask |= stage_masks.src;
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700144 }
145
Jeremy Gebbenf18d4362022-01-27 14:37:25 -0700146 if (src_stage_mask & VK_PIPELINE_STAGE_HOST_BIT) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700147 ReportSetupProblem(commandBuffer,
148 "CmdWaitEvents2KHR recorded with VK_PIPELINE_STAGE_HOST_BIT set. "
149 "Debug Printf waits on queue completion. "
150 "This wait could block the host's signaling of this event, resulting in deadlock.");
151 }
152 return false;
153}
154
Tony-LunarG1364cf52021-11-17 16:10:11 -0700155bool DebugPrintf::PreCallValidateCmdWaitEvents2(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
156 const VkDependencyInfo *pDependencyInfos) const {
Jeremy Gebbenf18d4362022-01-27 14:37:25 -0700157 VkPipelineStageFlags2 src_stage_mask = 0;
Tony-LunarG1364cf52021-11-17 16:10:11 -0700158
159 for (uint32_t i = 0; i < eventCount; i++) {
160 auto stage_masks = sync_utils::GetGlobalStageMasks(pDependencyInfos[i]);
Jeremy Gebbenf18d4362022-01-27 14:37:25 -0700161 src_stage_mask |= stage_masks.src;
Tony-LunarG1364cf52021-11-17 16:10:11 -0700162 }
163
Jeremy Gebbenf18d4362022-01-27 14:37:25 -0700164 if (src_stage_mask & VK_PIPELINE_STAGE_HOST_BIT) {
Tony-LunarG1364cf52021-11-17 16:10:11 -0700165 ReportSetupProblem(commandBuffer,
166 "CmdWaitEvents2 recorded with VK_PIPELINE_STAGE_HOST_BIT set. "
167 "Debug Printf waits on queue completion. "
168 "This wait could block the host's signaling of this event, resulting in deadlock.");
169 }
170 return false;
171}
172
Tony-LunarGb5fae462020-03-05 12:43:25 -0700173void DebugPrintf::PreCallRecordCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
174 const VkGraphicsPipelineCreateInfo *pCreateInfos,
175 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
176 void *cgpl_state_data) {
Tony-LunarG00e7b7d2021-06-30 12:59:43 -0600177 if (aborted) return;
Tony-LunarG04717522019-10-17 10:41:17 -0600178 std::vector<safe_VkGraphicsPipelineCreateInfo> new_pipeline_create_infos;
179 create_graphics_pipeline_api_state *cgpl_state = reinterpret_cast<create_graphics_pipeline_api_state *>(cgpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -0700180 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, cgpl_state->pipe_state,
181 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_GRAPHICS, this);
Tony-LunarG04717522019-10-17 10:41:17 -0600182 cgpl_state->printf_create_infos = new_pipeline_create_infos;
183 cgpl_state->pCreateInfos = reinterpret_cast<VkGraphicsPipelineCreateInfo *>(cgpl_state->printf_create_infos.data());
184}
185
Tony-LunarGb5fae462020-03-05 12:43:25 -0700186void DebugPrintf::PreCallRecordCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
187 const VkComputePipelineCreateInfo *pCreateInfos,
188 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
189 void *ccpl_state_data) {
Tony-LunarG00e7b7d2021-06-30 12:59:43 -0600190 if (aborted) return;
Tony-LunarG04717522019-10-17 10:41:17 -0600191 std::vector<safe_VkComputePipelineCreateInfo> new_pipeline_create_infos;
192 auto *ccpl_state = reinterpret_cast<create_compute_pipeline_api_state *>(ccpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -0700193 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, ccpl_state->pipe_state,
194 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_COMPUTE, this);
Tony-LunarG04717522019-10-17 10:41:17 -0600195 ccpl_state->printf_create_infos = new_pipeline_create_infos;
Tony-LunarG9b9dc022020-10-08 13:55:37 -0600196 ccpl_state->pCreateInfos = reinterpret_cast<VkComputePipelineCreateInfo *>(ccpl_state->printf_create_infos.data());
Tony-LunarG04717522019-10-17 10:41:17 -0600197}
198
Tony-LunarGb5fae462020-03-05 12:43:25 -0700199void DebugPrintf::PreCallRecordCreateRayTracingPipelinesNV(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
200 const VkRayTracingPipelineCreateInfoNV *pCreateInfos,
201 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
202 void *crtpl_state_data) {
Tony-LunarG00e7b7d2021-06-30 12:59:43 -0600203 if (aborted) return;
Tony-LunarG04717522019-10-17 10:41:17 -0600204 std::vector<safe_VkRayTracingPipelineCreateInfoCommon> new_pipeline_create_infos;
205 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_api_state *>(crtpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -0700206 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, crtpl_state->pipe_state,
207 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, this);
Tony-LunarG04717522019-10-17 10:41:17 -0600208 crtpl_state->printf_create_infos = new_pipeline_create_infos;
Tony-LunarG9b9dc022020-10-08 13:55:37 -0600209 crtpl_state->pCreateInfos = reinterpret_cast<VkRayTracingPipelineCreateInfoNV *>(crtpl_state->printf_create_infos.data());
Tony-LunarG04717522019-10-17 10:41:17 -0600210}
211
sourav parmarcd5fb182020-07-17 12:58:44 -0700212void DebugPrintf::PreCallRecordCreateRayTracingPipelinesKHR(VkDevice device, VkDeferredOperationKHR deferredOperation,
213 VkPipelineCache pipelineCache, uint32_t count,
Tony-LunarGb5fae462020-03-05 12:43:25 -0700214 const VkRayTracingPipelineCreateInfoKHR *pCreateInfos,
215 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
216 void *crtpl_state_data) {
Tony-LunarG00e7b7d2021-06-30 12:59:43 -0600217 if (aborted) return;
Tony-LunarG04717522019-10-17 10:41:17 -0600218 std::vector<safe_VkRayTracingPipelineCreateInfoCommon> new_pipeline_create_infos;
219 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_khr_api_state *>(crtpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -0700220 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, crtpl_state->pipe_state,
221 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, this);
Tony-LunarG9b9dc022020-10-08 13:55:37 -0600222 crtpl_state->printf_create_infos = new_pipeline_create_infos;
223 crtpl_state->pCreateInfos = reinterpret_cast<VkRayTracingPipelineCreateInfoKHR *>(crtpl_state->printf_create_infos.data());
Tony-LunarG04717522019-10-17 10:41:17 -0600224}
Tony-LunarG04717522019-10-17 10:41:17 -0600225
Tony-LunarGb5fae462020-03-05 12:43:25 -0700226void DebugPrintf::PostCallRecordCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
227 const VkGraphicsPipelineCreateInfo *pCreateInfos,
228 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
229 VkResult result, void *cgpl_state_data) {
Tony-LunarG04717522019-10-17 10:41:17 -0600230 ValidationStateTracker::PostCallRecordCreateGraphicsPipelines(device, pipelineCache, count, pCreateInfos, pAllocator,
231 pPipelines, result, cgpl_state_data);
Tony-LunarG00e7b7d2021-06-30 12:59:43 -0600232 if (aborted) return;
Tony-LunarGc876c6e2020-09-09 15:19:43 -0600233 create_graphics_pipeline_api_state *cgpl_state = reinterpret_cast<create_graphics_pipeline_api_state *>(cgpl_state_data);
234 UtilCopyCreatePipelineFeedbackData(count, pCreateInfos, cgpl_state->printf_create_infos.data());
Tony-LunarGb5fae462020-03-05 12:43:25 -0700235 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_GRAPHICS, this);
Tony-LunarG04717522019-10-17 10:41:17 -0600236}
237
Tony-LunarGb5fae462020-03-05 12:43:25 -0700238void DebugPrintf::PostCallRecordCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
239 const VkComputePipelineCreateInfo *pCreateInfos,
240 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
241 VkResult result, void *ccpl_state_data) {
Tony-LunarG04717522019-10-17 10:41:17 -0600242 ValidationStateTracker::PostCallRecordCreateComputePipelines(device, pipelineCache, count, pCreateInfos, pAllocator, pPipelines,
243 result, ccpl_state_data);
Tony-LunarG00e7b7d2021-06-30 12:59:43 -0600244 if (aborted) return;
Tony-LunarGc876c6e2020-09-09 15:19:43 -0600245 create_compute_pipeline_api_state *ccpl_state = reinterpret_cast<create_compute_pipeline_api_state *>(ccpl_state_data);
246 UtilCopyCreatePipelineFeedbackData(count, pCreateInfos, ccpl_state->printf_create_infos.data());
Tony-LunarGb5fae462020-03-05 12:43:25 -0700247 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_COMPUTE, this);
Tony-LunarG04717522019-10-17 10:41:17 -0600248}
249
Tony-LunarGb5fae462020-03-05 12:43:25 -0700250void DebugPrintf::PostCallRecordCreateRayTracingPipelinesNV(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
251 const VkRayTracingPipelineCreateInfoNV *pCreateInfos,
252 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
253 VkResult result, void *crtpl_state_data) {
Tony-LunarGc876c6e2020-09-09 15:19:43 -0600254 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_khr_api_state *>(crtpl_state_data);
Tony-LunarG04717522019-10-17 10:41:17 -0600255 ValidationStateTracker::PostCallRecordCreateRayTracingPipelinesNV(device, pipelineCache, count, pCreateInfos, pAllocator,
256 pPipelines, result, crtpl_state_data);
Tony-LunarG00e7b7d2021-06-30 12:59:43 -0600257 if (aborted) return;
Tony-LunarG9b9dc022020-10-08 13:55:37 -0600258 UtilCopyCreatePipelineFeedbackData(count, pCreateInfos, crtpl_state->printf_create_infos.data());
Tony-LunarGb5fae462020-03-05 12:43:25 -0700259 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, this);
Tony-LunarG04717522019-10-17 10:41:17 -0600260}
261
Tony-LunarGfb2ab872021-01-13 15:17:15 -0700262void DebugPrintf::PostCallRecordCreateRayTracingPipelinesKHR(VkDevice device, VkDeferredOperationKHR deferredOperation,
263 VkPipelineCache pipelineCache, uint32_t count,
264 const VkRayTracingPipelineCreateInfoKHR *pCreateInfos,
265 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
266 VkResult result, void *crtpl_state_data) {
267 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_khr_api_state *>(crtpl_state_data);
268 ValidationStateTracker::PostCallRecordCreateRayTracingPipelinesKHR(
269 device, deferredOperation, pipelineCache, count, pCreateInfos, pAllocator, pPipelines, result, crtpl_state_data);
Tony-LunarG00e7b7d2021-06-30 12:59:43 -0600270 if (aborted) return;
Tony-LunarGfb2ab872021-01-13 15:17:15 -0700271 UtilCopyCreatePipelineFeedbackData(count, pCreateInfos, crtpl_state->printf_create_infos.data());
aitor-lunarg3c145292022-03-25 17:30:11 +0100272
273 bool is_operation_deferred = (deferredOperation != VK_NULL_HANDLE && result == VK_OPERATION_DEFERRED_KHR);
274 if (is_operation_deferred) {
275 std::vector<safe_VkRayTracingPipelineCreateInfoKHR> infos{pCreateInfos, pCreateInfos + count};
276 auto register_fn = [this, infos, pAllocator](const std::vector<VkPipeline> &pipelines) {
277 UtilPostCallRecordPipelineCreations(static_cast<uint32_t>(infos.size()),
278 reinterpret_cast<const VkRayTracingPipelineCreateInfoKHR *>(infos.data()),
279 pAllocator, pipelines.data(), VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, this);
280 };
281
282 auto layer_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
283 if (wrap_handles) {
284 deferredOperation = layer_data->Unwrap(deferredOperation);
285 }
286 std::vector<std::function<void(const std::vector<VkPipeline> &)>> cleanup_fn;
287 auto find_res = layer_data->deferred_operation_post_check.pop(deferredOperation);
288 if (find_res->first) {
289 cleanup_fn = std::move(find_res->second);
290 }
291 cleanup_fn.emplace_back(register_fn);
292 layer_data->deferred_operation_post_check.insert(deferredOperation, cleanup_fn);
293 } else {
294 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR,
295 this);
296 }
Tony-LunarGfb2ab872021-01-13 15:17:15 -0700297}
298
Tony-LunarG04717522019-10-17 10:41:17 -0600299// Remove all the shader trackers associated with this destroyed pipeline.
Tony-LunarGb5fae462020-03-05 12:43:25 -0700300void DebugPrintf::PreCallRecordDestroyPipeline(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks *pAllocator) {
Tony-LunarG04717522019-10-17 10:41:17 -0600301 for (auto it = shader_map.begin(); it != shader_map.end();) {
302 if (it->second.pipeline == pipeline) {
303 it = shader_map.erase(it);
304 } else {
305 ++it;
306 }
307 }
308 ValidationStateTracker::PreCallRecordDestroyPipeline(device, pipeline, pAllocator);
309}
310// Call the SPIR-V Optimizer to run the instrumentation pass on the shader.
sfricke-samsung7fac88a2022-01-26 11:44:22 -0800311bool DebugPrintf::InstrumentShader(const VkShaderModuleCreateInfo *pCreateInfo, std::vector<uint32_t> &new_pgm,
Tony-LunarGb5fae462020-03-05 12:43:25 -0700312 uint32_t *unique_shader_id) {
Tony-LunarG04717522019-10-17 10:41:17 -0600313 if (aborted) return false;
314 if (pCreateInfo->pCode[0] != spv::MagicNumber) return false;
315
316 // Load original shader SPIR-V
317 uint32_t num_words = static_cast<uint32_t>(pCreateInfo->codeSize / 4);
318 new_pgm.clear();
319 new_pgm.reserve(num_words);
320 new_pgm.insert(new_pgm.end(), &pCreateInfo->pCode[0], &pCreateInfo->pCode[num_words]);
321
322 // Call the optimizer to instrument the shader.
323 // Use the unique_shader_module_id as a shader ID so we can look up its handle later in the shader_map.
324 // If descriptor indexing is enabled, enable length checks and updated descriptor checks
325 using namespace spvtools;
sfricke-samsung45996a42021-09-16 13:45:27 -0700326 spv_target_env target_env = PickSpirvEnv(api_version, IsExtEnabled(device_extensions.vk_khr_spirv_1_4));
Tony-LunarGf29f77f2020-08-26 15:48:00 -0600327 spvtools::ValidatorOptions val_options;
328 AdjustValidatorOptions(device_extensions, enabled_features, val_options);
329 spvtools::OptimizerOptions opt_options;
330 opt_options.set_run_validator(true);
331 opt_options.set_validator_options(val_options);
Tony-LunarG04717522019-10-17 10:41:17 -0600332 Optimizer optimizer(target_env);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700333 const spvtools::MessageConsumer debug_printf_console_message_consumer =
Tony-LunarG79641702020-07-13 15:43:05 -0600334 [this](spv_message_level_t level, const char *, const spv_position_t &position, const char *message) -> void {
335 switch (level) {
336 case SPV_MSG_FATAL:
337 case SPV_MSG_INTERNAL_ERROR:
338 case SPV_MSG_ERROR:
339 this->LogError(this->device, "UNASSIGNED-Debug-Printf", "Error during shader instrumentation: line %zu: %s",
340 position.index, message);
341 break;
342 default:
343 break;
344 }
345 };
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700346 optimizer.SetMessageConsumer(debug_printf_console_message_consumer);
Tony-LunarG04717522019-10-17 10:41:17 -0600347 optimizer.RegisterPass(CreateInstDebugPrintfPass(desc_set_bind_index, unique_shader_module_id));
Tony-LunarGf29f77f2020-08-26 15:48:00 -0600348 bool pass = optimizer.Run(new_pgm.data(), new_pgm.size(), &new_pgm, opt_options);
Tony-LunarG04717522019-10-17 10:41:17 -0600349 if (!pass) {
Tony-LunarG1dce2392019-10-23 16:49:29 -0600350 ReportSetupProblem(device, "Failure to instrument shader. Proceeding with non-instrumented shader.");
Tony-LunarG04717522019-10-17 10:41:17 -0600351 }
352 *unique_shader_id = unique_shader_module_id++;
353 return pass;
354}
355// Create the instrumented shader data to provide to the driver.
Tony-LunarGb5fae462020-03-05 12:43:25 -0700356void DebugPrintf::PreCallRecordCreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo *pCreateInfo,
357 const VkAllocationCallbacks *pAllocator, VkShaderModule *pShaderModule,
358 void *csm_state_data) {
Tony-LunarG04717522019-10-17 10:41:17 -0600359 create_shader_module_api_state *csm_state = reinterpret_cast<create_shader_module_api_state *>(csm_state_data);
360 bool pass = InstrumentShader(pCreateInfo, csm_state->instrumented_pgm, &csm_state->unique_shader_id);
361 if (pass) {
362 csm_state->instrumented_create_info.pCode = csm_state->instrumented_pgm.data();
sfricke-samsung7fac88a2022-01-26 11:44:22 -0800363 csm_state->instrumented_create_info.codeSize = csm_state->instrumented_pgm.size() * sizeof(uint32_t);
Tony-LunarG04717522019-10-17 10:41:17 -0600364 }
365}
Tony-LunarG04717522019-10-17 10:41:17 -0600366
367vartype vartype_lookup(char intype) {
368 switch (intype) {
369 case 'd':
370 case 'i':
371 return varsigned;
372 break;
373
374 case 'f':
375 case 'F':
376 case 'a':
377 case 'A':
378 case 'e':
379 case 'E':
380 case 'g':
381 case 'G':
382 return varfloat;
383 break;
384
385 case 'u':
386 case 'x':
387 case 'o':
388 default:
389 return varunsigned;
390 break;
391 }
392}
393
Tony-LunarGa19e31e2020-03-30 13:30:29 -0600394std::vector<DPFSubstring> DebugPrintf::ParseFormatString(const std::string format_string) {
395 const char types[] = {'d', 'i', 'o', 'u', 'x', 'X', 'a', 'A', 'e', 'E', 'f', 'F', 'g', 'G', 'v', '\0'};
Tony-LunarGb5fae462020-03-05 12:43:25 -0700396 std::vector<DPFSubstring> parsed_strings;
Tony-LunarG04717522019-10-17 10:41:17 -0600397 size_t pos = 0;
398 size_t begin = 0;
399 size_t percent = 0;
400
401 while (begin < format_string.length()) {
Tony-LunarGb5fae462020-03-05 12:43:25 -0700402 DPFSubstring substring;
Tony-LunarG04717522019-10-17 10:41:17 -0600403
404 // Find a percent sign
405 pos = percent = format_string.find_first_of('%', pos);
406 if (pos == std::string::npos) {
407 // End of the format string Push the rest of the characters
408 substring.string = format_string.substr(begin, format_string.length());
409 substring.needs_value = false;
410 parsed_strings.push_back(substring);
411 break;
412 }
413 pos++;
414 if (format_string[pos] == '%') {
415 pos++;
416 continue; // %% - skip it
417 }
418 // Find the type of the value
419 pos = format_string.find_first_of(types, pos);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700420 if (pos == format_string.npos) {
Tony-LunarG04717522019-10-17 10:41:17 -0600421 // This really shouldn't happen with a legal value string
422 pos = format_string.length();
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700423 } else {
Tony-LunarG04717522019-10-17 10:41:17 -0600424 char tempstring[32];
425 int count = 0;
426 std::string specifier = {};
427
428 if (format_string[pos] == 'v') {
429 // Vector must be of size 2, 3, or 4
430 // and format %v<size><type>
431 specifier = format_string.substr(percent, pos - percent);
432 count = atoi(&format_string[pos + 1]);
433 pos += 2;
434
435 // skip v<count>, handle long
436 specifier.push_back(format_string[pos]);
437 if (format_string[pos + 1] == 'l') {
438 specifier.push_back('l');
439 pos++;
440 }
441
442 // Take the preceding characters, and the percent through the type
443 substring.string = format_string.substr(begin, percent - begin);
444 substring.string += specifier;
445 substring.needs_value = true;
446 substring.type = vartype_lookup(specifier.back());
447 parsed_strings.push_back(substring);
448
449 // Continue with a comma separated list
450 sprintf(tempstring, ", %s", specifier.c_str());
451 substring.string = tempstring;
452 for (int i = 0; i < (count - 1); i++) {
453 parsed_strings.push_back(substring);
454 }
455 } else {
456 // Single non-vector value
457 if (format_string[pos + 1] == 'l') pos++; // Save long size
458 substring.string = format_string.substr(begin, pos - begin + 1);
459 substring.needs_value = true;
460 substring.type = vartype_lookup(format_string[pos]);
461 parsed_strings.push_back(substring);
462 }
463 begin = pos + 1;
464 }
465 }
466 return parsed_strings;
467}
468
sfricke-samsung7fac88a2022-01-26 11:44:22 -0800469std::string DebugPrintf::FindFormatString(std::vector<uint32_t> pgm, uint32_t string_id) {
Tony-LunarG04717522019-10-17 10:41:17 -0600470 std::string format_string;
sfricke-samsungef15e482022-01-26 11:32:49 -0800471 SHADER_MODULE_STATE module_state(pgm);
472 if (module_state.words.size() > 0) {
473 for (const auto &insn : module_state) {
Tony-LunarG04717522019-10-17 10:41:17 -0600474 if (insn.opcode() == spv::OpString) {
475 uint32_t offset = insn.offset();
476 if (pgm[offset + 1] == string_id) {
477 format_string = reinterpret_cast<char *>(&pgm[offset + 2]);
478 break;
479 }
480 }
481 }
482 }
483
484 return format_string;
485}
486
Corentin Wallez171ac5e2020-03-31 16:09:05 +0200487// GCC and clang don't like using variables as format strings in sprintf.
488// #pragma GCC is recognized by both compilers
489#if defined(__GNUC__) || defined(__clang__)
Tony-LunarG04717522019-10-17 10:41:17 -0600490#pragma GCC diagnostic push
491#pragma GCC diagnostic ignored "-Wformat-security"
492#endif
493
Tony-LunarGb5fae462020-03-05 12:43:25 -0700494void snprintf_with_malloc(std::stringstream &shader_message, DPFSubstring substring, size_t needed, void *values) {
Tony-LunarG04717522019-10-17 10:41:17 -0600495 char *buffer = static_cast<char *>(malloc((needed + 1) * sizeof(char))); // Add 1 for terminator
496 if (substring.longval) {
497 snprintf(buffer, needed, substring.string.c_str(), substring.longval);
498 } else if (!substring.needs_value) {
499 snprintf(buffer, needed, substring.string.c_str());
500 } else {
501 switch (substring.type) {
502 case varunsigned:
503 needed = snprintf(buffer, needed, substring.string.c_str(), *static_cast<uint32_t *>(values) - 1);
504 break;
505
506 case varsigned:
507 needed = snprintf(buffer, needed, substring.string.c_str(), *static_cast<int32_t *>(values) - 1);
508 break;
509
510 case varfloat:
511 needed = snprintf(buffer, needed, substring.string.c_str(), *static_cast<float *>(values) - 1);
512 break;
513 }
514 }
515 shader_message << buffer;
516 free(buffer);
517}
518
Tony-LunarG7de10e82020-11-24 11:31:55 -0700519void DebugPrintf::AnalyzeAndGenerateMessages(VkCommandBuffer command_buffer, VkQueue queue, DPFBufferInfo &buffer_info,
Tony-LunarGb5fae462020-03-05 12:43:25 -0700520 uint32_t operation_index, uint32_t *const debug_output_buffer) {
Tony-LunarG04717522019-10-17 10:41:17 -0600521 // Word Content
522 // 0 Size of output record, including this word
523 // 1 Shader ID
524 // 2 Instruction Position
525 // 3 Stage Ordinal
526 // 4 Stage - specific Info Word 0
527 // 5 Stage - specific Info Word 1
528 // 6 Stage - specific Info Word 2
529 // 7 Printf Format String Id
530 // 8 Printf Values Word 0 (optional)
531 // 9 Printf Values Word 1 (optional)
Tony-LunarG12a7ec32019-11-01 13:00:05 -0600532 uint32_t expect = debug_output_buffer[0];
533 if (!expect) return;
Tony-LunarG04717522019-10-17 10:41:17 -0600534
Tony-LunarG12a7ec32019-11-01 13:00:05 -0600535 uint32_t index = 1;
Tony-LunarG04717522019-10-17 10:41:17 -0600536 while (debug_output_buffer[index]) {
Tony-LunarG04717522019-10-17 10:41:17 -0600537 std::stringstream shader_message;
Tony-LunarG04717522019-10-17 10:41:17 -0600538 VkShaderModule shader_module_handle = VK_NULL_HANDLE;
539 VkPipeline pipeline_handle = VK_NULL_HANDLE;
sfricke-samsung7fac88a2022-01-26 11:44:22 -0800540 std::vector<uint32_t> pgm;
Tony-LunarG04717522019-10-17 10:41:17 -0600541
Tony-LunarGb5fae462020-03-05 12:43:25 -0700542 DPFOutputRecord *debug_record = reinterpret_cast<DPFOutputRecord *>(&debug_output_buffer[index]);
Tony-LunarG04717522019-10-17 10:41:17 -0600543 // Lookup the VkShaderModule handle and SPIR-V code used to create the shader, using the unique shader ID value returned
544 // by the instrumented shader.
545 auto it = shader_map.find(debug_record->shader_id);
546 if (it != shader_map.end()) {
547 shader_module_handle = it->second.shader_module;
548 pipeline_handle = it->second.pipeline;
549 pgm = it->second.pgm;
550 }
551 // Search through the shader source for the printf format string for this invocation
552 auto format_string = FindFormatString(pgm, debug_record->format_string_id);
553 // Break the format string into strings with 1 or 0 value
554 auto format_substrings = ParseFormatString(format_string);
555 void *values = static_cast<void *>(&debug_record->values);
556 const uint32_t static_size = 1024;
557 // Sprintf each format substring into a temporary string then add that to the message
558 for (auto &substring : format_substrings) {
559 char temp_string[static_size];
560 size_t needed = 0;
Tony-LunarGef469c92021-05-14 06:33:22 -0600561 std::vector<std::string> format_strings = { "%ul", "%lu", "%lx" };
562 size_t ul_pos = 0;
563 bool print_hex = true;
564 for (auto ul_string : format_strings) {
565 ul_pos = substring.string.find(ul_string);
566 if (ul_pos != std::string::npos) {
567 if (ul_string == "%lu") print_hex = false;
568 break;
569 }
570 }
Tony-LunarG04717522019-10-17 10:41:17 -0600571 if (ul_pos != std::string::npos) {
572 // Unsigned 64 bit value
573 substring.longval = *static_cast<uint64_t *>(values);
574 values = static_cast<uint64_t *>(values) + 1;
Tony-LunarGef469c92021-05-14 06:33:22 -0600575 if (print_hex) {
576 substring.string.replace(ul_pos + 1, 2, PRIx64);
577 } else {
578 substring.string.replace(ul_pos + 1, 2, PRIu64);
579 }
Tony-LunarG04717522019-10-17 10:41:17 -0600580 needed = snprintf(temp_string, static_size, substring.string.c_str(), substring.longval);
581 } else {
582 if (substring.needs_value) {
583 switch (substring.type) {
584 case varunsigned:
585 needed = snprintf(temp_string, static_size, substring.string.c_str(), *static_cast<uint32_t *>(values));
586 break;
587
588 case varsigned:
589 needed = snprintf(temp_string, static_size, substring.string.c_str(), *static_cast<int32_t *>(values));
590 break;
591
592 case varfloat:
593 needed = snprintf(temp_string, static_size, substring.string.c_str(), *static_cast<float *>(values));
594 break;
595 }
596 values = static_cast<uint32_t *>(values) + 1;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700597 } else {
Tony-LunarG04717522019-10-17 10:41:17 -0600598 needed = snprintf(temp_string, static_size, substring.string.c_str());
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700599 }
Tony-LunarG04717522019-10-17 10:41:17 -0600600 }
601
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700602 if (needed < static_size) {
Tony-LunarG04717522019-10-17 10:41:17 -0600603 shader_message << temp_string;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700604 } else {
Tony-LunarG04717522019-10-17 10:41:17 -0600605 // Static buffer not big enough for message, use malloc to get enough
606 snprintf_with_malloc(shader_message, substring, needed, values);
607 }
608 }
Tony-LunarG43416b42019-10-31 16:47:24 -0600609
610 if (verbose) {
611 std::string stage_message;
612 std::string common_message;
613 std::string filename_message;
614 std::string source_message;
Tony-LunarGb5fae462020-03-05 12:43:25 -0700615 UtilGenerateStageMessage(&debug_output_buffer[index], stage_message);
616 UtilGenerateCommonMessage(report_data, command_buffer, &debug_output_buffer[index], shader_module_handle,
Tony-LunarG7de10e82020-11-24 11:31:55 -0700617 pipeline_handle, buffer_info.pipeline_bind_point, operation_index, common_message);
Tony-LunarGb5fae462020-03-05 12:43:25 -0700618 UtilGenerateSourceMessages(pgm, &debug_output_buffer[index], true, filename_message, source_message);
Tony-LunarG43416b42019-10-31 16:47:24 -0600619 if (use_stdout) {
Tony-LunarG5af54eb2020-03-27 15:32:51 -0600620 std::cout << "UNASSIGNED-DEBUG-PRINTF " << common_message.c_str() << " " << stage_message.c_str() << " "
Tony-LunarGb5fae462020-03-05 12:43:25 -0700621 << shader_message.str().c_str() << " " << filename_message.c_str() << " " << source_message.c_str();
Tony-LunarG43416b42019-10-31 16:47:24 -0600622 } else {
Tony-LunarG5af54eb2020-03-27 15:32:51 -0600623 LogInfo(queue, "UNASSIGNED-DEBUG-PRINTF", "%s %s %s %s%s", common_message.c_str(), stage_message.c_str(),
624 shader_message.str().c_str(), filename_message.c_str(), source_message.c_str());
Tony-LunarG43416b42019-10-31 16:47:24 -0600625 }
626 } else {
Tony-LunarG5af54eb2020-03-27 15:32:51 -0600627 if (use_stdout) {
Tony-LunarG43416b42019-10-31 16:47:24 -0600628 std::cout << shader_message.str();
Tony-LunarG5af54eb2020-03-27 15:32:51 -0600629 } else {
630 // Don't let LogInfo process any '%'s in the string
631 LogInfo(device, "UNASSIGNED-DEBUG-PRINTF", "%s", shader_message.str().c_str());
632 }
Tony-LunarG43416b42019-10-31 16:47:24 -0600633 }
Tony-LunarG04717522019-10-17 10:41:17 -0600634 index += debug_record->size;
635 }
Tony-LunarG12a7ec32019-11-01 13:00:05 -0600636 if ((index - 1) != expect) {
Tony-LunarG5af54eb2020-03-27 15:32:51 -0600637 LogWarning(device, "UNASSIGNED-DEBUG-PRINTF",
638 "WARNING - Debug Printf message was truncated, likely due to a buffer size that was too small for the message");
Tony-LunarG12a7ec32019-11-01 13:00:05 -0600639 }
Tony-LunarG04717522019-10-17 10:41:17 -0600640 memset(debug_output_buffer, 0, 4 * (debug_output_buffer[0] + 1));
641}
Tony-LunarG43416b42019-10-31 16:47:24 -0600642
Tony-LunarG04717522019-10-17 10:41:17 -0600643#if defined(__GNUC__)
644#pragma GCC diagnostic pop
645#endif
646
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700647bool DebugPrintf::CommandBufferNeedsProcessing(VkCommandBuffer command_buffer) {
648 bool buffers_present = false;
Jeremy Gebben37c5c5d2022-03-21 07:16:03 -0600649 auto cb_node = Get<debug_printf_state::CommandBuffer>(command_buffer);
Jeremy Gebben9f537102021-10-05 16:37:12 -0600650 if (GetBufferInfo(cb_node.get()).size()) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700651 buffers_present = true;
652 }
John Zulauf79f06582021-02-27 18:38:39 -0700653 for (const auto *secondaryCmdBuffer : cb_node->linkedCommandBuffers) {
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600654 if (GetBufferInfo(secondaryCmdBuffer).size()) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700655 buffers_present = true;
656 }
657 }
658 return buffers_present;
659}
660
661void DebugPrintf::ProcessCommandBuffer(VkQueue queue, VkCommandBuffer command_buffer) {
Jeremy Gebben37c5c5d2022-03-21 07:16:03 -0600662 auto cb_node = Get<debug_printf_state::CommandBuffer>(command_buffer);
Jeremy Gebben9f537102021-10-05 16:37:12 -0600663 UtilProcessInstrumentationBuffer(queue, cb_node.get(), this);
John Zulauf79f06582021-02-27 18:38:39 -0700664 for (auto *secondary_cmd_buffer : cb_node->linkedCommandBuffers) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700665 UtilProcessInstrumentationBuffer(queue, secondary_cmd_buffer, this);
666 }
667}
668
Tony-LunarG04717522019-10-17 10:41:17 -0600669// Issue a memory barrier to make GPU-written data available to host.
670// Wait for the queue to complete execution.
671// Check the debug buffers for all the command buffers that were submitted.
Tony-LunarGb5fae462020-03-05 12:43:25 -0700672void DebugPrintf::PostCallRecordQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence,
673 VkResult result) {
Tony-LunarG04717522019-10-17 10:41:17 -0600674 ValidationStateTracker::PostCallRecordQueueSubmit(queue, submitCount, pSubmits, fence, result);
675
Mark Lobodzinski09379db2020-05-07 08:22:01 -0600676 if (aborted || (result != VK_SUCCESS)) return;
Tony-LunarG04717522019-10-17 10:41:17 -0600677 bool buffers_present = false;
678 // Don't QueueWaitIdle if there's nothing to process
679 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
680 const VkSubmitInfo *submit = &pSubmits[submit_idx];
681 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700682 buffers_present |= CommandBufferNeedsProcessing(submit->pCommandBuffers[i]);
Tony-LunarG04717522019-10-17 10:41:17 -0600683 }
684 }
685 if (!buffers_present) return;
686
Tony-LunarGb5fae462020-03-05 12:43:25 -0700687 UtilSubmitBarrier(queue, this);
Tony-LunarG04717522019-10-17 10:41:17 -0600688
689 DispatchQueueWaitIdle(queue);
690
691 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
692 const VkSubmitInfo *submit = &pSubmits[submit_idx];
693 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700694 ProcessCommandBuffer(queue, submit->pCommandBuffers[i]);
695 }
696 }
697}
698
Tony-LunarG26fe2842021-11-16 14:07:59 -0700699void DebugPrintf::RecordQueueSubmit2(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2 *pSubmits, VkFence fence,
700 VkResult result) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700701 if (aborted || (result != VK_SUCCESS)) return;
702 bool buffers_present = false;
703 // Don't QueueWaitIdle if there's nothing to process
704 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
705 const auto *submit = &pSubmits[submit_idx];
706 for (uint32_t i = 0; i < submit->commandBufferInfoCount; i++) {
707 buffers_present |= CommandBufferNeedsProcessing(submit->pCommandBufferInfos[i].commandBuffer);
708 }
709 }
710 if (!buffers_present) return;
711
712 UtilSubmitBarrier(queue, this);
713
714 DispatchQueueWaitIdle(queue);
715
716 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
Tony-LunarG26fe2842021-11-16 14:07:59 -0700717 const VkSubmitInfo2 *submit = &pSubmits[submit_idx];
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700718 for (uint32_t i = 0; i < submit->commandBufferInfoCount; i++) {
719 ProcessCommandBuffer(queue, submit->pCommandBufferInfos[i].commandBuffer);
Tony-LunarG04717522019-10-17 10:41:17 -0600720 }
721 }
722}
723
Tony-LunarG26fe2842021-11-16 14:07:59 -0700724void DebugPrintf::PostCallRecordQueueSubmit2KHR(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2KHR *pSubmits,
725 VkFence fence, VkResult result) {
726 ValidationStateTracker::PostCallRecordQueueSubmit2KHR(queue, submitCount, pSubmits, fence, result);
727 RecordQueueSubmit2(queue, submitCount, pSubmits, fence, result);
728}
729
730void DebugPrintf::PostCallRecordQueueSubmit2(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2 *pSubmits, VkFence fence,
731 VkResult result) {
732 ValidationStateTracker::PostCallRecordQueueSubmit2(queue, submitCount, pSubmits, fence, result);
733 RecordQueueSubmit2(queue, submitCount, pSubmits, fence, result);
734}
735
Tony-LunarGb5fae462020-03-05 12:43:25 -0700736void DebugPrintf::PreCallRecordCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
737 uint32_t firstVertex, uint32_t firstInstance) {
738 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
Tony-LunarG04717522019-10-17 10:41:17 -0600739}
740
Tony-LunarG745150c2021-07-02 15:07:31 -0600741void DebugPrintf::PreCallRecordCmdDrawMultiEXT(VkCommandBuffer commandBuffer, uint32_t drawCount,
742 const VkMultiDrawInfoEXT *pVertexInfo, uint32_t instanceCount,
743 uint32_t firstInstance, uint32_t stride) {
744 for(uint32_t i = 0; i < drawCount; i++) {
745 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
746 }
747}
748
Tony-LunarGb5fae462020-03-05 12:43:25 -0700749void DebugPrintf::PreCallRecordCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount,
750 uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) {
751 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
Tony-LunarG04717522019-10-17 10:41:17 -0600752}
753
Tony-LunarG745150c2021-07-02 15:07:31 -0600754void DebugPrintf::PreCallRecordCmdDrawMultiIndexedEXT(VkCommandBuffer commandBuffer, uint32_t drawCount,
755 const VkMultiDrawIndexedInfoEXT *pIndexInfo, uint32_t instanceCount,
756 uint32_t firstInstance, uint32_t stride, const int32_t *pVertexOffset) {
757 for (uint32_t i = 0; i < drawCount; i++) {
758 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
759 }
760}
761
Tony-LunarGb5fae462020-03-05 12:43:25 -0700762void DebugPrintf::PreCallRecordCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count,
763 uint32_t stride) {
764 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
Tony-LunarG04717522019-10-17 10:41:17 -0600765}
766
Tony-LunarGb5fae462020-03-05 12:43:25 -0700767void DebugPrintf::PreCallRecordCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
768 uint32_t count, uint32_t stride) {
769 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
Tony-LunarG04717522019-10-17 10:41:17 -0600770}
771
Tony-LunarGb5fae462020-03-05 12:43:25 -0700772void DebugPrintf::PreCallRecordCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
773 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE);
Tony-LunarG04717522019-10-17 10:41:17 -0600774}
775
Tony-LunarGb5fae462020-03-05 12:43:25 -0700776void DebugPrintf::PreCallRecordCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
777 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE);
Tony-LunarG04717522019-10-17 10:41:17 -0600778}
779
Tony-LunarGd13f9b52020-09-08 15:45:45 -0600780void DebugPrintf::PreCallRecordCmdDispatchBase(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY,
781 uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY,
782 uint32_t groupCountZ) {
783 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE);
784}
785
Tony-LunarG52c8c602020-09-10 16:29:56 -0600786void DebugPrintf::PreCallRecordCmdDispatchBaseKHR(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY,
787 uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY,
788 uint32_t groupCountZ) {
789 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE);
790}
791
Tony-LunarG2fb8ff02020-06-11 12:45:07 -0600792void DebugPrintf::PreCallRecordCmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
793 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
794 uint32_t stride) {
795 ValidationStateTracker::PreCallRecordCmdDrawIndirectCountKHR(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
796 maxDrawCount, stride);
797 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
798}
799
800void DebugPrintf::PreCallRecordCmdDrawIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
801 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
802 uint32_t stride) {
803 ValidationStateTracker::PreCallRecordCmdDrawIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
804 maxDrawCount, stride);
805 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
806}
807
808void DebugPrintf::PreCallRecordCmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
809 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
810 uint32_t maxDrawCount, uint32_t stride) {
811 ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirectCountKHR(commandBuffer, buffer, offset, countBuffer,
812 countBufferOffset, maxDrawCount, stride);
813 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
814}
815
816void DebugPrintf::PreCallRecordCmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
817 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
818 uint32_t maxDrawCount, uint32_t stride) {
819 ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
820 maxDrawCount, stride);
821 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
822}
823
Tony-LunarG54176fb2020-12-02 10:47:22 -0700824void DebugPrintf::PreCallRecordCmdDrawIndirectByteCountEXT(VkCommandBuffer commandBuffer, uint32_t instanceCount,
825 uint32_t firstInstance, VkBuffer counterBuffer,
826 VkDeviceSize counterBufferOffset, uint32_t counterOffset,
827 uint32_t vertexStride) {
828 ValidationStateTracker::PreCallRecordCmdDrawIndirectByteCountEXT(commandBuffer, instanceCount, firstInstance, counterBuffer,
829 counterBufferOffset, counterOffset, vertexStride);
830 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
831}
832
Tony-LunarG2fb8ff02020-06-11 12:45:07 -0600833void DebugPrintf::PreCallRecordCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask) {
834 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksNV(commandBuffer, taskCount, firstTask);
835 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
836}
837
838void DebugPrintf::PreCallRecordCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
839 uint32_t drawCount, uint32_t stride) {
840 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksIndirectNV(commandBuffer, buffer, offset, drawCount, stride);
841 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
842}
843
844void DebugPrintf::PreCallRecordCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
845 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
846 uint32_t maxDrawCount, uint32_t stride) {
847 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksIndirectCountNV(commandBuffer, buffer, offset, countBuffer,
848 countBufferOffset, maxDrawCount, stride);
849 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
850}
851
Tony-LunarGb5fae462020-03-05 12:43:25 -0700852void DebugPrintf::PreCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
853 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
854 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
855 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
856 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
857 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
858 uint32_t width, uint32_t height, uint32_t depth) {
859 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV);
860}
861
862void DebugPrintf::PostCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
Tony-LunarG04717522019-10-17 10:41:17 -0600863 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
864 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
865 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
866 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
867 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
868 uint32_t width, uint32_t height, uint32_t depth) {
Jeremy Gebben37c5c5d2022-03-21 07:16:03 -0600869 auto cb_state = Get<debug_printf_state::CommandBuffer>(commandBuffer);
Tony-LunarG04717522019-10-17 10:41:17 -0600870 cb_state->hasTraceRaysCmd = true;
871}
872
Tony-LunarGb5fae462020-03-05 12:43:25 -0700873void DebugPrintf::PreCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -0700874 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
875 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
876 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
877 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable, uint32_t width,
Tony-LunarGb5fae462020-03-05 12:43:25 -0700878 uint32_t height, uint32_t depth) {
879 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR);
Tony-LunarG1dce2392019-10-23 16:49:29 -0600880}
881
Tony-LunarGb5fae462020-03-05 12:43:25 -0700882void DebugPrintf::PostCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -0700883 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
884 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
885 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
886 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable, uint32_t width,
Tony-LunarGb5fae462020-03-05 12:43:25 -0700887 uint32_t height, uint32_t depth) {
Jeremy Gebben37c5c5d2022-03-21 07:16:03 -0600888 auto cb_state = Get<debug_printf_state::CommandBuffer>(commandBuffer);
Tony-LunarG1dce2392019-10-23 16:49:29 -0600889 cb_state->hasTraceRaysCmd = true;
890}
891
Tony-LunarGb5fae462020-03-05 12:43:25 -0700892void DebugPrintf::PreCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -0700893 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
894 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
895 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
896 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable,
Shannon McPherson54e1f892020-11-27 11:04:19 -0700897 VkDeviceAddress indirectDeviceAddress) {
Tony-LunarGb5fae462020-03-05 12:43:25 -0700898 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR);
Tony-LunarG1dce2392019-10-23 16:49:29 -0600899}
900
Tony-LunarGb5fae462020-03-05 12:43:25 -0700901void DebugPrintf::PostCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -0700902 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
903 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
904 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
905 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable,
Shannon McPherson54e1f892020-11-27 11:04:19 -0700906 VkDeviceAddress indirectDeviceAddress) {
Jeremy Gebben37c5c5d2022-03-21 07:16:03 -0600907 auto cb_state = Get<debug_printf_state::CommandBuffer>(commandBuffer);
Tony-LunarG1dce2392019-10-23 16:49:29 -0600908 cb_state->hasTraceRaysCmd = true;
909}
910
Tony-LunarGb5fae462020-03-05 12:43:25 -0700911void DebugPrintf::AllocateDebugPrintfResources(const VkCommandBuffer cmd_buffer, const VkPipelineBindPoint bind_point) {
Tony-LunarG04717522019-10-17 10:41:17 -0600912 if (bind_point != VK_PIPELINE_BIND_POINT_GRAPHICS && bind_point != VK_PIPELINE_BIND_POINT_COMPUTE &&
913 bind_point != VK_PIPELINE_BIND_POINT_RAY_TRACING_NV) {
914 return;
915 }
916 VkResult result;
917
918 if (aborted) return;
919
920 std::vector<VkDescriptorSet> desc_sets;
921 VkDescriptorPool desc_pool = VK_NULL_HANDLE;
Tony-LunarG1dce2392019-10-23 16:49:29 -0600922 result = desc_set_manager->GetDescriptorSets(1, &desc_pool, debug_desc_layout, &desc_sets);
Tony-LunarG04717522019-10-17 10:41:17 -0600923 assert(result == VK_SUCCESS);
924 if (result != VK_SUCCESS) {
Tony-LunarG1dce2392019-10-23 16:49:29 -0600925 ReportSetupProblem(device, "Unable to allocate descriptor sets. Device could become unstable.");
Tony-LunarG04717522019-10-17 10:41:17 -0600926 aborted = true;
927 return;
928 }
929
930 VkDescriptorBufferInfo output_desc_buffer_info = {};
931 output_desc_buffer_info.range = output_buffer_size;
932
Jeremy Gebben37c5c5d2022-03-21 07:16:03 -0600933 auto cb_node = Get<debug_printf_state::CommandBuffer>(cmd_buffer);
Tony-LunarG04717522019-10-17 10:41:17 -0600934 if (!cb_node) {
Tony-LunarG1dce2392019-10-23 16:49:29 -0600935 ReportSetupProblem(device, "Unrecognized command buffer");
Tony-LunarG04717522019-10-17 10:41:17 -0600936 aborted = true;
937 return;
938 }
939
Nathaniel Cesariobcb79682022-03-31 21:13:52 -0600940 const auto lv_bind_point = ConvertToLvlBindPoint(bind_point);
941 const auto *pipeline_state = cb_node->lastBound[lv_bind_point].pipeline_state;
942
943 // TODO (ncesario) remove once VK_EXT_graphics_pipeline_library support is added for debug printf
944 if (pipeline_state && pipeline_state->IsGraphicsLibrary()) {
945 ReportSetupProblem(device, "Debug printf does not currently support VK_EXT_graphics_pipeline_library");
946 aborted = true;
947 return;
948 }
949
Tony-LunarG04717522019-10-17 10:41:17 -0600950 // Allocate memory for the output block that the gpu will use to return values for printf
Tony-LunarGb5fae462020-03-05 12:43:25 -0700951 DPFDeviceMemoryBlock output_block = {};
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700952 VkBufferCreateInfo buffer_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
953 buffer_info.size = output_buffer_size;
954 buffer_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
955 VmaAllocationCreateInfo alloc_info = {};
956 alloc_info.usage = VMA_MEMORY_USAGE_GPU_TO_CPU;
957 result = vmaCreateBuffer(vmaAllocator, &buffer_info, &alloc_info, &output_block.buffer, &output_block.allocation, nullptr);
Tony-LunarG04717522019-10-17 10:41:17 -0600958 if (result != VK_SUCCESS) {
Tony-LunarG1dce2392019-10-23 16:49:29 -0600959 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
Tony-LunarG04717522019-10-17 10:41:17 -0600960 aborted = true;
961 return;
962 }
963
964 // Clear the output block to zeros so that only printf values from the gpu will be present
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700965 uint32_t *data;
966 result = vmaMapMemory(vmaAllocator, output_block.allocation, reinterpret_cast<void **>(&data));
Tony-LunarG04717522019-10-17 10:41:17 -0600967 if (result == VK_SUCCESS) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700968 memset(data, 0, output_buffer_size);
Tony-LunarG04717522019-10-17 10:41:17 -0600969 vmaUnmapMemory(vmaAllocator, output_block.allocation);
970 }
971
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600972 auto desc_writes = LvlInitStruct<VkWriteDescriptorSet>();
Tony-LunarG04717522019-10-17 10:41:17 -0600973 const uint32_t desc_count = 1;
974
975 // Write the descriptor
976 output_desc_buffer_info.buffer = output_block.buffer;
977 output_desc_buffer_info.offset = 0;
978
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600979 desc_writes.descriptorCount = 1;
980 desc_writes.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
981 desc_writes.pBufferInfo = &output_desc_buffer_info;
982 desc_writes.dstSet = desc_sets[0];
983 desc_writes.dstBinding = 3;
984 DispatchUpdateDescriptorSets(device, desc_count, &desc_writes, 0, NULL);
Tony-LunarG04717522019-10-17 10:41:17 -0600985
locke-lunargb8d7a7a2020-10-25 16:01:52 -0600986 if (pipeline_state) {
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -0700987 const auto &pipeline_layout = pipeline_state->PipelineLayoutState();
988 if (pipeline_layout->set_layouts.size() <= desc_set_bind_index) {
989 DispatchCmdBindDescriptorSets(cmd_buffer, bind_point, pipeline_layout->layout(), desc_set_bind_index, 1,
Tony-LunarG04717522019-10-17 10:41:17 -0600990 desc_sets.data(), 0, nullptr);
991 }
992 // Record buffer and memory info in CB state tracking
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600993 cb_node->buffer_infos.emplace_back(output_block, desc_sets[0], desc_pool, bind_point);
Tony-LunarG04717522019-10-17 10:41:17 -0600994 } else {
Tony-LunarG1dce2392019-10-23 16:49:29 -0600995 ReportSetupProblem(device, "Unable to find pipeline state");
Tony-LunarG04717522019-10-17 10:41:17 -0600996 vmaDestroyBuffer(vmaAllocator, output_block.buffer, output_block.allocation);
997 aborted = true;
998 return;
999 }
1000}
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06001001
1002std::shared_ptr<CMD_BUFFER_STATE> DebugPrintf::CreateCmdBufferState(VkCommandBuffer cb,
1003 const VkCommandBufferAllocateInfo *pCreateInfo,
Jeremy Gebbencd7fa282021-10-27 10:25:32 -06001004 const COMMAND_POOL_STATE *pool) {
Jeremy Gebben37c5c5d2022-03-21 07:16:03 -06001005 return std::static_pointer_cast<CMD_BUFFER_STATE>(
1006 std::make_shared<debug_printf_state::CommandBuffer>(this, cb, pCreateInfo, pool));
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06001007}
1008
Jeremy Gebben37c5c5d2022-03-21 07:16:03 -06001009debug_printf_state::CommandBuffer::CommandBuffer(DebugPrintf *dp, VkCommandBuffer cb,
Jeremy Gebbencd7fa282021-10-27 10:25:32 -06001010 const VkCommandBufferAllocateInfo *pCreateInfo, const COMMAND_POOL_STATE *pool)
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06001011 : CMD_BUFFER_STATE(dp, cb, pCreateInfo, pool) {}
1012
Jeremy Gebben37c5c5d2022-03-21 07:16:03 -06001013void debug_printf_state::CommandBuffer::Reset() {
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06001014 CMD_BUFFER_STATE::Reset();
1015 auto debug_printf = static_cast<DebugPrintf *>(dev_data);
1016 // Free the device memory and descriptor set(s) associated with a command buffer.
1017 if (debug_printf->aborted) {
1018 return;
1019 }
1020 for (auto &buffer_info : buffer_infos) {
1021 debug_printf->DestroyBuffer(buffer_info);
1022 }
1023 buffer_infos.clear();
1024}