blob: 46c34fe7b16c5f76dbacdb0b40401b1749192723 [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
Jeremy Gebbenfcfc33c2022-03-28 15:31:29 -0600643// For the given command buffer, map its debug data buffers and read their contents for analysis.
644void DebugPrintf::ProcessInstrumentationBuffer(VkQueue queue, CMD_BUFFER_STATE *cb_base) {
645 auto *cb_node = static_cast<debug_printf_state::CommandBuffer *>(cb_base);
646 if (cb_node && (cb_node->hasDrawCmd || cb_node->hasTraceRaysCmd || cb_node->hasDispatchCmd)) {
647 auto &gpu_buffer_list = cb_node->buffer_infos;
648 uint32_t draw_index = 0;
649 uint32_t compute_index = 0;
650 uint32_t ray_trace_index = 0;
651
652 for (auto &buffer_info : gpu_buffer_list) {
653 char *pData;
654
655 uint32_t operation_index = 0;
656 if (buffer_info.pipeline_bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS) {
657 operation_index = draw_index;
658 } else if (buffer_info.pipeline_bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) {
659 operation_index = compute_index;
660 } else if (buffer_info.pipeline_bind_point == VK_PIPELINE_BIND_POINT_RAY_TRACING_NV) {
661 operation_index = ray_trace_index;
662 } else {
663 assert(false);
664 }
665
666 VkResult result = vmaMapMemory(vmaAllocator, buffer_info.output_mem_block.allocation, (void **)&pData);
667 if (result == VK_SUCCESS) {
668 AnalyzeAndGenerateMessages(cb_node->commandBuffer(), queue, buffer_info, operation_index, (uint32_t *)pData);
669 vmaUnmapMemory(vmaAllocator, buffer_info.output_mem_block.allocation);
670 }
671
672 if (buffer_info.pipeline_bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS) {
673 draw_index++;
674 } else if (buffer_info.pipeline_bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) {
675 compute_index++;
676 } else if (buffer_info.pipeline_bind_point == VK_PIPELINE_BIND_POINT_RAY_TRACING_NV) {
677 ray_trace_index++;
678 } else {
679 assert(false);
680 }
681 }
682 }
683}
684
Tony-LunarG04717522019-10-17 10:41:17 -0600685#if defined(__GNUC__)
686#pragma GCC diagnostic pop
687#endif
688
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700689bool DebugPrintf::CommandBufferNeedsProcessing(VkCommandBuffer command_buffer) {
690 bool buffers_present = false;
Jeremy Gebben37c5c5d2022-03-21 07:16:03 -0600691 auto cb_node = Get<debug_printf_state::CommandBuffer>(command_buffer);
Jeremy Gebbenfcfc33c2022-03-28 15:31:29 -0600692 if (cb_node->buffer_infos.size()) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700693 buffers_present = true;
694 }
Jeremy Gebbenfcfc33c2022-03-28 15:31:29 -0600695 for (const auto *secondary_cb : cb_node->linkedCommandBuffers) {
696 auto secondary_cb_node = static_cast<const debug_printf_state::CommandBuffer *>(secondary_cb);
697 if (secondary_cb_node->buffer_infos.size()) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700698 buffers_present = true;
699 }
700 }
701 return buffers_present;
702}
703
704void DebugPrintf::ProcessCommandBuffer(VkQueue queue, VkCommandBuffer command_buffer) {
Jeremy Gebben37c5c5d2022-03-21 07:16:03 -0600705 auto cb_node = Get<debug_printf_state::CommandBuffer>(command_buffer);
Jeremy Gebbenfcfc33c2022-03-28 15:31:29 -0600706
707 ProcessInstrumentationBuffer(queue, cb_node.get());
708
John Zulauf79f06582021-02-27 18:38:39 -0700709 for (auto *secondary_cmd_buffer : cb_node->linkedCommandBuffers) {
Jeremy Gebbenfcfc33c2022-03-28 15:31:29 -0600710 ProcessInstrumentationBuffer(queue, static_cast<debug_printf_state::CommandBuffer *>(secondary_cmd_buffer));
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700711 }
712}
713
Tony-LunarGb5fae462020-03-05 12:43:25 -0700714void DebugPrintf::PreCallRecordCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
715 uint32_t firstVertex, uint32_t firstInstance) {
716 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
Tony-LunarG04717522019-10-17 10:41:17 -0600717}
718
Tony-LunarG745150c2021-07-02 15:07:31 -0600719void DebugPrintf::PreCallRecordCmdDrawMultiEXT(VkCommandBuffer commandBuffer, uint32_t drawCount,
720 const VkMultiDrawInfoEXT *pVertexInfo, uint32_t instanceCount,
721 uint32_t firstInstance, uint32_t stride) {
722 for(uint32_t i = 0; i < drawCount; i++) {
723 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
724 }
725}
726
Tony-LunarGb5fae462020-03-05 12:43:25 -0700727void DebugPrintf::PreCallRecordCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount,
728 uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) {
729 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
Tony-LunarG04717522019-10-17 10:41:17 -0600730}
731
Tony-LunarG745150c2021-07-02 15:07:31 -0600732void DebugPrintf::PreCallRecordCmdDrawMultiIndexedEXT(VkCommandBuffer commandBuffer, uint32_t drawCount,
733 const VkMultiDrawIndexedInfoEXT *pIndexInfo, uint32_t instanceCount,
734 uint32_t firstInstance, uint32_t stride, const int32_t *pVertexOffset) {
735 for (uint32_t i = 0; i < drawCount; i++) {
736 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
737 }
738}
739
Tony-LunarGb5fae462020-03-05 12:43:25 -0700740void DebugPrintf::PreCallRecordCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count,
741 uint32_t stride) {
742 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
Tony-LunarG04717522019-10-17 10:41:17 -0600743}
744
Tony-LunarGb5fae462020-03-05 12:43:25 -0700745void DebugPrintf::PreCallRecordCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
746 uint32_t count, uint32_t stride) {
747 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
Tony-LunarG04717522019-10-17 10:41:17 -0600748}
749
Tony-LunarGb5fae462020-03-05 12:43:25 -0700750void DebugPrintf::PreCallRecordCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
751 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE);
Tony-LunarG04717522019-10-17 10:41:17 -0600752}
753
Tony-LunarGb5fae462020-03-05 12:43:25 -0700754void DebugPrintf::PreCallRecordCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
755 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE);
Tony-LunarG04717522019-10-17 10:41:17 -0600756}
757
Tony-LunarGd13f9b52020-09-08 15:45:45 -0600758void DebugPrintf::PreCallRecordCmdDispatchBase(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY,
759 uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY,
760 uint32_t groupCountZ) {
761 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE);
762}
763
Tony-LunarG52c8c602020-09-10 16:29:56 -0600764void DebugPrintf::PreCallRecordCmdDispatchBaseKHR(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY,
765 uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY,
766 uint32_t groupCountZ) {
767 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE);
768}
769
Tony-LunarG2fb8ff02020-06-11 12:45:07 -0600770void DebugPrintf::PreCallRecordCmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
771 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
772 uint32_t stride) {
773 ValidationStateTracker::PreCallRecordCmdDrawIndirectCountKHR(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
774 maxDrawCount, stride);
775 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
776}
777
778void DebugPrintf::PreCallRecordCmdDrawIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
779 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
780 uint32_t stride) {
781 ValidationStateTracker::PreCallRecordCmdDrawIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
782 maxDrawCount, stride);
783 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
784}
785
786void DebugPrintf::PreCallRecordCmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
787 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
788 uint32_t maxDrawCount, uint32_t stride) {
789 ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirectCountKHR(commandBuffer, buffer, offset, countBuffer,
790 countBufferOffset, maxDrawCount, stride);
791 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
792}
793
794void DebugPrintf::PreCallRecordCmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
795 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
796 uint32_t maxDrawCount, uint32_t stride) {
797 ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
798 maxDrawCount, stride);
799 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
800}
801
Tony-LunarG54176fb2020-12-02 10:47:22 -0700802void DebugPrintf::PreCallRecordCmdDrawIndirectByteCountEXT(VkCommandBuffer commandBuffer, uint32_t instanceCount,
803 uint32_t firstInstance, VkBuffer counterBuffer,
804 VkDeviceSize counterBufferOffset, uint32_t counterOffset,
805 uint32_t vertexStride) {
806 ValidationStateTracker::PreCallRecordCmdDrawIndirectByteCountEXT(commandBuffer, instanceCount, firstInstance, counterBuffer,
807 counterBufferOffset, counterOffset, vertexStride);
808 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
809}
810
Tony-LunarG2fb8ff02020-06-11 12:45:07 -0600811void DebugPrintf::PreCallRecordCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask) {
812 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksNV(commandBuffer, taskCount, firstTask);
813 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
814}
815
816void DebugPrintf::PreCallRecordCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
817 uint32_t drawCount, uint32_t stride) {
818 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksIndirectNV(commandBuffer, buffer, offset, drawCount, stride);
819 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
820}
821
822void DebugPrintf::PreCallRecordCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
823 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
824 uint32_t maxDrawCount, uint32_t stride) {
825 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksIndirectCountNV(commandBuffer, buffer, offset, countBuffer,
826 countBufferOffset, maxDrawCount, stride);
827 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
828}
829
Tony-LunarGb5fae462020-03-05 12:43:25 -0700830void DebugPrintf::PreCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
831 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
832 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
833 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
834 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
835 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
836 uint32_t width, uint32_t height, uint32_t depth) {
837 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV);
838}
839
840void DebugPrintf::PostCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
Tony-LunarG04717522019-10-17 10:41:17 -0600841 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
842 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
843 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
844 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
845 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
846 uint32_t width, uint32_t height, uint32_t depth) {
Jeremy Gebben37c5c5d2022-03-21 07:16:03 -0600847 auto cb_state = Get<debug_printf_state::CommandBuffer>(commandBuffer);
Tony-LunarG04717522019-10-17 10:41:17 -0600848 cb_state->hasTraceRaysCmd = true;
849}
850
Tony-LunarGb5fae462020-03-05 12:43:25 -0700851void DebugPrintf::PreCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -0700852 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
853 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
854 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
855 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable, uint32_t width,
Tony-LunarGb5fae462020-03-05 12:43:25 -0700856 uint32_t height, uint32_t depth) {
857 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR);
Tony-LunarG1dce2392019-10-23 16:49:29 -0600858}
859
Tony-LunarGb5fae462020-03-05 12:43:25 -0700860void DebugPrintf::PostCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -0700861 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
862 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
863 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
864 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable, uint32_t width,
Tony-LunarGb5fae462020-03-05 12:43:25 -0700865 uint32_t height, uint32_t depth) {
Jeremy Gebben37c5c5d2022-03-21 07:16:03 -0600866 auto cb_state = Get<debug_printf_state::CommandBuffer>(commandBuffer);
Tony-LunarG1dce2392019-10-23 16:49:29 -0600867 cb_state->hasTraceRaysCmd = true;
868}
869
Tony-LunarGb5fae462020-03-05 12:43:25 -0700870void DebugPrintf::PreCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -0700871 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
872 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
873 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
874 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable,
Shannon McPherson54e1f892020-11-27 11:04:19 -0700875 VkDeviceAddress indirectDeviceAddress) {
Tony-LunarGb5fae462020-03-05 12:43:25 -0700876 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR);
Tony-LunarG1dce2392019-10-23 16:49:29 -0600877}
878
Tony-LunarGb5fae462020-03-05 12:43:25 -0700879void DebugPrintf::PostCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -0700880 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
881 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
882 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
883 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable,
Shannon McPherson54e1f892020-11-27 11:04:19 -0700884 VkDeviceAddress indirectDeviceAddress) {
Jeremy Gebben37c5c5d2022-03-21 07:16:03 -0600885 auto cb_state = Get<debug_printf_state::CommandBuffer>(commandBuffer);
Tony-LunarG1dce2392019-10-23 16:49:29 -0600886 cb_state->hasTraceRaysCmd = true;
887}
888
Tony-LunarGb5fae462020-03-05 12:43:25 -0700889void DebugPrintf::AllocateDebugPrintfResources(const VkCommandBuffer cmd_buffer, const VkPipelineBindPoint bind_point) {
Tony-LunarG04717522019-10-17 10:41:17 -0600890 if (bind_point != VK_PIPELINE_BIND_POINT_GRAPHICS && bind_point != VK_PIPELINE_BIND_POINT_COMPUTE &&
891 bind_point != VK_PIPELINE_BIND_POINT_RAY_TRACING_NV) {
892 return;
893 }
894 VkResult result;
895
896 if (aborted) return;
897
898 std::vector<VkDescriptorSet> desc_sets;
899 VkDescriptorPool desc_pool = VK_NULL_HANDLE;
Tony-LunarG1dce2392019-10-23 16:49:29 -0600900 result = desc_set_manager->GetDescriptorSets(1, &desc_pool, debug_desc_layout, &desc_sets);
Tony-LunarG04717522019-10-17 10:41:17 -0600901 assert(result == VK_SUCCESS);
902 if (result != VK_SUCCESS) {
Tony-LunarG1dce2392019-10-23 16:49:29 -0600903 ReportSetupProblem(device, "Unable to allocate descriptor sets. Device could become unstable.");
Tony-LunarG04717522019-10-17 10:41:17 -0600904 aborted = true;
905 return;
906 }
907
908 VkDescriptorBufferInfo output_desc_buffer_info = {};
909 output_desc_buffer_info.range = output_buffer_size;
910
Jeremy Gebben37c5c5d2022-03-21 07:16:03 -0600911 auto cb_node = Get<debug_printf_state::CommandBuffer>(cmd_buffer);
Tony-LunarG04717522019-10-17 10:41:17 -0600912 if (!cb_node) {
Tony-LunarG1dce2392019-10-23 16:49:29 -0600913 ReportSetupProblem(device, "Unrecognized command buffer");
Tony-LunarG04717522019-10-17 10:41:17 -0600914 aborted = true;
915 return;
916 }
917
Nathaniel Cesariobcb79682022-03-31 21:13:52 -0600918 const auto lv_bind_point = ConvertToLvlBindPoint(bind_point);
919 const auto *pipeline_state = cb_node->lastBound[lv_bind_point].pipeline_state;
920
921 // TODO (ncesario) remove once VK_EXT_graphics_pipeline_library support is added for debug printf
922 if (pipeline_state && pipeline_state->IsGraphicsLibrary()) {
923 ReportSetupProblem(device, "Debug printf does not currently support VK_EXT_graphics_pipeline_library");
924 aborted = true;
925 return;
926 }
927
Tony-LunarG04717522019-10-17 10:41:17 -0600928 // Allocate memory for the output block that the gpu will use to return values for printf
Tony-LunarGb5fae462020-03-05 12:43:25 -0700929 DPFDeviceMemoryBlock output_block = {};
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700930 VkBufferCreateInfo buffer_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
931 buffer_info.size = output_buffer_size;
932 buffer_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
933 VmaAllocationCreateInfo alloc_info = {};
934 alloc_info.usage = VMA_MEMORY_USAGE_GPU_TO_CPU;
935 result = vmaCreateBuffer(vmaAllocator, &buffer_info, &alloc_info, &output_block.buffer, &output_block.allocation, nullptr);
Tony-LunarG04717522019-10-17 10:41:17 -0600936 if (result != VK_SUCCESS) {
Tony-LunarG1dce2392019-10-23 16:49:29 -0600937 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
Tony-LunarG04717522019-10-17 10:41:17 -0600938 aborted = true;
939 return;
940 }
941
942 // Clear the output block to zeros so that only printf values from the gpu will be present
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700943 uint32_t *data;
944 result = vmaMapMemory(vmaAllocator, output_block.allocation, reinterpret_cast<void **>(&data));
Tony-LunarG04717522019-10-17 10:41:17 -0600945 if (result == VK_SUCCESS) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700946 memset(data, 0, output_buffer_size);
Tony-LunarG04717522019-10-17 10:41:17 -0600947 vmaUnmapMemory(vmaAllocator, output_block.allocation);
948 }
949
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600950 auto desc_writes = LvlInitStruct<VkWriteDescriptorSet>();
Tony-LunarG04717522019-10-17 10:41:17 -0600951 const uint32_t desc_count = 1;
952
953 // Write the descriptor
954 output_desc_buffer_info.buffer = output_block.buffer;
955 output_desc_buffer_info.offset = 0;
956
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600957 desc_writes.descriptorCount = 1;
958 desc_writes.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
959 desc_writes.pBufferInfo = &output_desc_buffer_info;
960 desc_writes.dstSet = desc_sets[0];
961 desc_writes.dstBinding = 3;
962 DispatchUpdateDescriptorSets(device, desc_count, &desc_writes, 0, NULL);
Tony-LunarG04717522019-10-17 10:41:17 -0600963
locke-lunargb8d7a7a2020-10-25 16:01:52 -0600964 if (pipeline_state) {
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -0700965 const auto &pipeline_layout = pipeline_state->PipelineLayoutState();
966 if (pipeline_layout->set_layouts.size() <= desc_set_bind_index) {
967 DispatchCmdBindDescriptorSets(cmd_buffer, bind_point, pipeline_layout->layout(), desc_set_bind_index, 1,
Tony-LunarG04717522019-10-17 10:41:17 -0600968 desc_sets.data(), 0, nullptr);
969 }
970 // Record buffer and memory info in CB state tracking
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600971 cb_node->buffer_infos.emplace_back(output_block, desc_sets[0], desc_pool, bind_point);
Tony-LunarG04717522019-10-17 10:41:17 -0600972 } else {
Tony-LunarG1dce2392019-10-23 16:49:29 -0600973 ReportSetupProblem(device, "Unable to find pipeline state");
Tony-LunarG04717522019-10-17 10:41:17 -0600974 vmaDestroyBuffer(vmaAllocator, output_block.buffer, output_block.allocation);
975 aborted = true;
976 return;
977 }
978}
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600979
980std::shared_ptr<CMD_BUFFER_STATE> DebugPrintf::CreateCmdBufferState(VkCommandBuffer cb,
981 const VkCommandBufferAllocateInfo *pCreateInfo,
Jeremy Gebbencd7fa282021-10-27 10:25:32 -0600982 const COMMAND_POOL_STATE *pool) {
Jeremy Gebben37c5c5d2022-03-21 07:16:03 -0600983 return std::static_pointer_cast<CMD_BUFFER_STATE>(
984 std::make_shared<debug_printf_state::CommandBuffer>(this, cb, pCreateInfo, pool));
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600985}
986
Jeremy Gebben37c5c5d2022-03-21 07:16:03 -0600987debug_printf_state::CommandBuffer::CommandBuffer(DebugPrintf *dp, VkCommandBuffer cb,
Jeremy Gebbencd7fa282021-10-27 10:25:32 -0600988 const VkCommandBufferAllocateInfo *pCreateInfo, const COMMAND_POOL_STATE *pool)
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600989 : CMD_BUFFER_STATE(dp, cb, pCreateInfo, pool) {}
990
Jeremy Gebben37c5c5d2022-03-21 07:16:03 -0600991void debug_printf_state::CommandBuffer::Reset() {
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600992 CMD_BUFFER_STATE::Reset();
993 auto debug_printf = static_cast<DebugPrintf *>(dev_data);
994 // Free the device memory and descriptor set(s) associated with a command buffer.
995 if (debug_printf->aborted) {
996 return;
997 }
998 for (auto &buffer_info : buffer_infos) {
999 debug_printf->DestroyBuffer(buffer_info);
1000 }
1001 buffer_infos.clear();
1002}