blob: c893b77f46ddef8ac7768bacf06caa3531054126 [file] [log] [blame]
Tony-LunarGfb2ab872021-01-13 15:17:15 -07001/* Copyright (c) 2020-2021 The Khronos Group Inc.
2 * Copyright (c) 2020-2021 Valve Corporation
3 * Copyright (c) 2020-2021 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-LunarG5af54eb2020-03-27 15:32:51 -060032// Convenience function for reporting problems with setting up Debug Printf.
Tony-LunarG1dce2392019-10-23 16:49:29 -060033template <typename T>
Tony-LunarGb5fae462020-03-05 12:43:25 -070034void DebugPrintf::ReportSetupProblem(T object, const char *const specific_message) const {
Tony-LunarG5af54eb2020-03-27 15:32:51 -060035 LogError(object, "UNASSIGNED-DEBUG-PRINTF ", "Detail: (%s)", specific_message);
Tony-LunarG04717522019-10-17 10:41:17 -060036}
37
38// Turn on necessary device features.
Tony-LunarGb5fae462020-03-05 12:43:25 -070039void DebugPrintf::PreCallRecordCreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *create_info,
40 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice,
Mark Lobodzinskib588cd42020-09-30 11:03:34 -060041 void *modified_create_info) {
Tony-LunarG04717522019-10-17 10:41:17 -060042 DispatchGetPhysicalDeviceFeatures(gpu, &supported_features);
Tony-LunarG1dce2392019-10-23 16:49:29 -060043 VkPhysicalDeviceFeatures features = {};
44 features.vertexPipelineStoresAndAtomics = true;
45 features.fragmentStoresAndAtomics = true;
Mark Lobodzinskib588cd42020-09-30 11:03:34 -060046 UtilPreCallRecordCreateDevice(gpu, reinterpret_cast<safe_VkDeviceCreateInfo *>(modified_create_info), supported_features,
47 features);
Tony-LunarG04717522019-10-17 10:41:17 -060048}
Tony-LunarG1dce2392019-10-23 16:49:29 -060049
Tony-LunarG04717522019-10-17 10:41:17 -060050// Perform initializations that can be done at Create Device time.
Tony-LunarGb5fae462020-03-05 12:43:25 -070051void DebugPrintf::PostCallRecordCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
52 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice, VkResult result) {
Tony-LunarG04717522019-10-17 10:41:17 -060053 ValidationStateTracker::PostCallRecordCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice, result);
54
55 ValidationObject *device_object = GetLayerDataPtr(get_dispatch_key(*pDevice), layer_data_map);
56 ValidationObject *validation_data = GetValidationObject(device_object->object_dispatch, this->container_type);
Tony-LunarGb5fae462020-03-05 12:43:25 -070057 DebugPrintf *device_debug_printf = static_cast<DebugPrintf *>(validation_data);
58 device_debug_printf->physicalDevice = physicalDevice;
59 device_debug_printf->device = *pDevice;
Tony-LunarG43416b42019-10-31 16:47:24 -060060
61 const char *size_string = getLayerOption("khronos_validation.printf_buffer_size");
Tony-LunarGb5fae462020-03-05 12:43:25 -070062 device_debug_printf->output_buffer_size = *size_string ? atoi(size_string) : 1024;
Tony-LunarGc99dbef2021-06-14 15:11:50 -060063
64 std::string verbose_string = getLayerOption("khronos_validation.printf_verbose");
65 transform(verbose_string.begin(), verbose_string.end(), verbose_string.begin(), ::tolower);
66 device_debug_printf->verbose = verbose_string.length() ? !verbose_string.compare("true") : false;
67
68 std::string stdout_string = getLayerOption("khronos_validation.printf_to_stdout");
69 transform(stdout_string.begin(), stdout_string.end(), stdout_string.begin(), ::tolower);
70 device_debug_printf->use_stdout = stdout_string.length() ? !stdout_string.compare("true") : false;
Tony-LunarGb5fae462020-03-05 12:43:25 -070071 if (getenv("DEBUG_PRINTF_TO_STDOUT")) device_debug_printf->use_stdout = true;
Tony-LunarG04717522019-10-17 10:41:17 -060072
Tony-LunarGb5fae462020-03-05 12:43:25 -070073 if (device_debug_printf->phys_dev_props.apiVersion < VK_API_VERSION_1_1) {
Tony-LunarGbbbed672020-03-04 10:51:11 -070074 ReportSetupProblem(device, "Debug Printf requires Vulkan 1.1 or later. Debug Printf disabled.");
Tony-LunarGb5fae462020-03-05 12:43:25 -070075 device_debug_printf->aborted = true;
Tony-LunarG04717522019-10-17 10:41:17 -060076 return;
77 }
78
79 if (!supported_features.fragmentStoresAndAtomics || !supported_features.vertexPipelineStoresAndAtomics) {
Tony-LunarG1dce2392019-10-23 16:49:29 -060080 ReportSetupProblem(device,
Tony-LunarGbbbed672020-03-04 10:51:11 -070081 "Debug Printf requires fragmentStoresAndAtomics and vertexPipelineStoresAndAtomics. "
82 "Debug Printf disabled.");
Tony-LunarGb5fae462020-03-05 12:43:25 -070083 device_debug_printf->aborted = true;
Tony-LunarG04717522019-10-17 10:41:17 -060084 return;
85 }
Tony-LunarG9586e732020-03-04 10:50:30 -070086
Mark Lobodzinski90eea5b2020-05-15 12:54:00 -060087 if (enabled[gpu_validation]) {
Tony-LunarG9586e732020-03-04 10:50:30 -070088 ReportSetupProblem(device,
89 "Debug Printf cannot be enabled when gpu assisted validation is enabled. "
90 "Debug Printf disabled.");
Tony-LunarGb5fae462020-03-05 12:43:25 -070091 device_debug_printf->aborted = true;
Tony-LunarG9586e732020-03-04 10:50:30 -070092 return;
93 }
94
Tony-LunarG1dce2392019-10-23 16:49:29 -060095 std::vector<VkDescriptorSetLayoutBinding> bindings;
96 VkDescriptorSetLayoutBinding binding = {3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
Tony-LunarGc7ed2082020-06-11 14:00:04 -060097 VK_SHADER_STAGE_ALL_GRAPHICS | VK_SHADER_STAGE_MESH_BIT_NV |
98 VK_SHADER_STAGE_TASK_BIT_NV | VK_SHADER_STAGE_COMPUTE_BIT |
99 kShaderStageAllRayTracing,
Tony-LunarG1dce2392019-10-23 16:49:29 -0600100 NULL};
101 bindings.push_back(binding);
Tony-LunarGb5fae462020-03-05 12:43:25 -0700102 UtilPostCallRecordCreateDevice(pCreateInfo, bindings, device_debug_printf, device_debug_printf->phys_dev_props);
Tony-LunarG04717522019-10-17 10:41:17 -0600103}
104
Tony-LunarGb5fae462020-03-05 12:43:25 -0700105void DebugPrintf::PreCallRecordDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
106 UtilPreCallRecordDestroyDevice(this);
Tony-LunarG0a863bc2020-09-16 09:50:04 -0600107 ValidationStateTracker::PreCallRecordDestroyDevice(device, pAllocator);
108 // State Tracker can end up making vma calls through callbacks - don't destroy allocator until ST is done
109 if (vmaAllocator) {
110 vmaDestroyAllocator(vmaAllocator);
111 }
112 desc_set_manager.reset();
Tony-LunarG04717522019-10-17 10:41:17 -0600113}
114
115// 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 -0700116void DebugPrintf::PreCallRecordCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo,
117 const VkAllocationCallbacks *pAllocator, VkPipelineLayout *pPipelineLayout,
118 void *cpl_state_data) {
Tony-LunarG04717522019-10-17 10:41:17 -0600119 if (aborted) {
120 return;
121 }
122
123 create_pipeline_layout_api_state *cpl_state = reinterpret_cast<create_pipeline_layout_api_state *>(cpl_state_data);
124
125 if (cpl_state->modified_create_info.setLayoutCount >= adjusted_max_desc_sets) {
126 std::ostringstream strm;
127 strm << "Pipeline Layout conflict with validation's descriptor set at slot " << desc_set_bind_index << ". "
Tony-LunarGbbbed672020-03-04 10:51:11 -0700128 << "Application has too many descriptor sets in the pipeline layout to continue with debug printf. "
Tony-LunarG04717522019-10-17 10:41:17 -0600129 << "Not modifying the pipeline layout. "
130 << "Instrumented shaders are replaced with non-instrumented shaders.";
Tony-LunarG1dce2392019-10-23 16:49:29 -0600131 ReportSetupProblem(device, strm.str().c_str());
Tony-LunarG04717522019-10-17 10:41:17 -0600132 } else {
Tony-LunarGb5fae462020-03-05 12:43:25 -0700133 UtilPreCallRecordCreatePipelineLayout(cpl_state, this, pCreateInfo);
Tony-LunarG04717522019-10-17 10:41:17 -0600134 }
135}
136
Tony-LunarGb5fae462020-03-05 12:43:25 -0700137void DebugPrintf::PostCallRecordCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo,
138 const VkAllocationCallbacks *pAllocator, VkPipelineLayout *pPipelineLayout,
139 VkResult result) {
Tony-LunarG04717522019-10-17 10:41:17 -0600140 ValidationStateTracker::PostCallRecordCreatePipelineLayout(device, pCreateInfo, pAllocator, pPipelineLayout, result);
141 if (result != VK_SUCCESS) {
Tony-LunarG1dce2392019-10-23 16:49:29 -0600142 ReportSetupProblem(device, "Unable to create pipeline layout. Device could become unstable.");
Tony-LunarG04717522019-10-17 10:41:17 -0600143 aborted = true;
144 }
145}
146
147// Free the device memory and descriptor set associated with a command buffer.
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600148void DebugPrintf::DestroyBuffer(DPFBufferInfo &buffer_info) {
149 vmaDestroyBuffer(vmaAllocator, buffer_info.output_mem_block.buffer, buffer_info.output_mem_block.allocation);
150 if (buffer_info.desc_set != VK_NULL_HANDLE) {
151 desc_set_manager->PutBackDescriptorSet(buffer_info.desc_pool, buffer_info.desc_set);
Tony-LunarG04717522019-10-17 10:41:17 -0600152 }
Tony-LunarG04717522019-10-17 10:41:17 -0600153}
154
155// Just gives a warning about a possible deadlock.
Tony-LunarGb5fae462020-03-05 12:43:25 -0700156bool DebugPrintf::PreCallValidateCmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
157 VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask,
158 uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
159 uint32_t bufferMemoryBarrierCount,
160 const VkBufferMemoryBarrier *pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount,
161 const VkImageMemoryBarrier *pImageMemoryBarriers) const {
Tony-LunarG04717522019-10-17 10:41:17 -0600162 if (srcStageMask & VK_PIPELINE_STAGE_HOST_BIT) {
Tony-LunarG1dce2392019-10-23 16:49:29 -0600163 ReportSetupProblem(commandBuffer,
164 "CmdWaitEvents recorded with VK_PIPELINE_STAGE_HOST_BIT set. "
Tony-LunarGbbbed672020-03-04 10:51:11 -0700165 "Debug Printf waits on queue completion. "
Tony-LunarG1dce2392019-10-23 16:49:29 -0600166 "This wait could block the host's signaling of this event, resulting in deadlock.");
Tony-LunarG04717522019-10-17 10:41:17 -0600167 }
168 return false;
169}
170
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700171bool DebugPrintf::PreCallValidateCmdWaitEvents2KHR(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
172 const VkDependencyInfoKHR *pDependencyInfos) const {
173 VkPipelineStageFlags2KHR srcStageMask = 0;
174
175 for (uint32_t i = 0; i < eventCount; i++) {
176 auto stage_masks = sync_utils::GetGlobalStageMasks(pDependencyInfos[i]);
177 srcStageMask = stage_masks.src;
178 }
179
180 if (srcStageMask & VK_PIPELINE_STAGE_HOST_BIT) {
181 ReportSetupProblem(commandBuffer,
182 "CmdWaitEvents2KHR recorded with VK_PIPELINE_STAGE_HOST_BIT set. "
183 "Debug Printf waits on queue completion. "
184 "This wait could block the host's signaling of this event, resulting in deadlock.");
185 }
186 return false;
187}
188
Tony-LunarGb5fae462020-03-05 12:43:25 -0700189void DebugPrintf::PreCallRecordCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
190 const VkGraphicsPipelineCreateInfo *pCreateInfos,
191 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
192 void *cgpl_state_data) {
Tony-LunarG00e7b7d2021-06-30 12:59:43 -0600193 if (aborted) return;
Tony-LunarG04717522019-10-17 10:41:17 -0600194 std::vector<safe_VkGraphicsPipelineCreateInfo> new_pipeline_create_infos;
195 create_graphics_pipeline_api_state *cgpl_state = reinterpret_cast<create_graphics_pipeline_api_state *>(cgpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -0700196 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, cgpl_state->pipe_state,
197 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_GRAPHICS, this);
Tony-LunarG04717522019-10-17 10:41:17 -0600198 cgpl_state->printf_create_infos = new_pipeline_create_infos;
199 cgpl_state->pCreateInfos = reinterpret_cast<VkGraphicsPipelineCreateInfo *>(cgpl_state->printf_create_infos.data());
200}
201
Tony-LunarGb5fae462020-03-05 12:43:25 -0700202void DebugPrintf::PreCallRecordCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
203 const VkComputePipelineCreateInfo *pCreateInfos,
204 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
205 void *ccpl_state_data) {
Tony-LunarG00e7b7d2021-06-30 12:59:43 -0600206 if (aborted) return;
Tony-LunarG04717522019-10-17 10:41:17 -0600207 std::vector<safe_VkComputePipelineCreateInfo> new_pipeline_create_infos;
208 auto *ccpl_state = reinterpret_cast<create_compute_pipeline_api_state *>(ccpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -0700209 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, ccpl_state->pipe_state,
210 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_COMPUTE, this);
Tony-LunarG04717522019-10-17 10:41:17 -0600211 ccpl_state->printf_create_infos = new_pipeline_create_infos;
Tony-LunarG9b9dc022020-10-08 13:55:37 -0600212 ccpl_state->pCreateInfos = reinterpret_cast<VkComputePipelineCreateInfo *>(ccpl_state->printf_create_infos.data());
Tony-LunarG04717522019-10-17 10:41:17 -0600213}
214
Tony-LunarGb5fae462020-03-05 12:43:25 -0700215void DebugPrintf::PreCallRecordCreateRayTracingPipelinesNV(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
216 const VkRayTracingPipelineCreateInfoNV *pCreateInfos,
217 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
218 void *crtpl_state_data) {
Tony-LunarG00e7b7d2021-06-30 12:59:43 -0600219 if (aborted) return;
Tony-LunarG04717522019-10-17 10:41:17 -0600220 std::vector<safe_VkRayTracingPipelineCreateInfoCommon> new_pipeline_create_infos;
221 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_api_state *>(crtpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -0700222 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, crtpl_state->pipe_state,
223 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, this);
Tony-LunarG04717522019-10-17 10:41:17 -0600224 crtpl_state->printf_create_infos = new_pipeline_create_infos;
Tony-LunarG9b9dc022020-10-08 13:55:37 -0600225 crtpl_state->pCreateInfos = reinterpret_cast<VkRayTracingPipelineCreateInfoNV *>(crtpl_state->printf_create_infos.data());
Tony-LunarG04717522019-10-17 10:41:17 -0600226}
227
sourav parmarcd5fb182020-07-17 12:58:44 -0700228void DebugPrintf::PreCallRecordCreateRayTracingPipelinesKHR(VkDevice device, VkDeferredOperationKHR deferredOperation,
229 VkPipelineCache pipelineCache, uint32_t count,
Tony-LunarGb5fae462020-03-05 12:43:25 -0700230 const VkRayTracingPipelineCreateInfoKHR *pCreateInfos,
231 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
232 void *crtpl_state_data) {
Tony-LunarG00e7b7d2021-06-30 12:59:43 -0600233 if (aborted) return;
Tony-LunarG04717522019-10-17 10:41:17 -0600234 std::vector<safe_VkRayTracingPipelineCreateInfoCommon> new_pipeline_create_infos;
235 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_khr_api_state *>(crtpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -0700236 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, crtpl_state->pipe_state,
237 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, this);
Tony-LunarG9b9dc022020-10-08 13:55:37 -0600238 crtpl_state->printf_create_infos = new_pipeline_create_infos;
239 crtpl_state->pCreateInfos = reinterpret_cast<VkRayTracingPipelineCreateInfoKHR *>(crtpl_state->printf_create_infos.data());
Tony-LunarG04717522019-10-17 10:41:17 -0600240}
Tony-LunarG04717522019-10-17 10:41:17 -0600241
Tony-LunarGb5fae462020-03-05 12:43:25 -0700242void DebugPrintf::PostCallRecordCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
243 const VkGraphicsPipelineCreateInfo *pCreateInfos,
244 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
245 VkResult result, void *cgpl_state_data) {
Tony-LunarG04717522019-10-17 10:41:17 -0600246 ValidationStateTracker::PostCallRecordCreateGraphicsPipelines(device, pipelineCache, count, pCreateInfos, pAllocator,
247 pPipelines, result, cgpl_state_data);
Tony-LunarG00e7b7d2021-06-30 12:59:43 -0600248 if (aborted) return;
Tony-LunarGc876c6e2020-09-09 15:19:43 -0600249 create_graphics_pipeline_api_state *cgpl_state = reinterpret_cast<create_graphics_pipeline_api_state *>(cgpl_state_data);
250 UtilCopyCreatePipelineFeedbackData(count, pCreateInfos, cgpl_state->printf_create_infos.data());
Tony-LunarGb5fae462020-03-05 12:43:25 -0700251 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_GRAPHICS, this);
Tony-LunarG04717522019-10-17 10:41:17 -0600252}
253
Tony-LunarGb5fae462020-03-05 12:43:25 -0700254void DebugPrintf::PostCallRecordCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
255 const VkComputePipelineCreateInfo *pCreateInfos,
256 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
257 VkResult result, void *ccpl_state_data) {
Tony-LunarG04717522019-10-17 10:41:17 -0600258 ValidationStateTracker::PostCallRecordCreateComputePipelines(device, pipelineCache, count, pCreateInfos, pAllocator, pPipelines,
259 result, ccpl_state_data);
Tony-LunarG00e7b7d2021-06-30 12:59:43 -0600260 if (aborted) return;
Tony-LunarGc876c6e2020-09-09 15:19:43 -0600261 create_compute_pipeline_api_state *ccpl_state = reinterpret_cast<create_compute_pipeline_api_state *>(ccpl_state_data);
262 UtilCopyCreatePipelineFeedbackData(count, pCreateInfos, ccpl_state->printf_create_infos.data());
Tony-LunarGb5fae462020-03-05 12:43:25 -0700263 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_COMPUTE, this);
Tony-LunarG04717522019-10-17 10:41:17 -0600264}
265
Tony-LunarGb5fae462020-03-05 12:43:25 -0700266void DebugPrintf::PostCallRecordCreateRayTracingPipelinesNV(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
267 const VkRayTracingPipelineCreateInfoNV *pCreateInfos,
268 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
269 VkResult result, void *crtpl_state_data) {
Tony-LunarGc876c6e2020-09-09 15:19:43 -0600270 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_khr_api_state *>(crtpl_state_data);
Tony-LunarG04717522019-10-17 10:41:17 -0600271 ValidationStateTracker::PostCallRecordCreateRayTracingPipelinesNV(device, pipelineCache, count, pCreateInfos, pAllocator,
272 pPipelines, result, crtpl_state_data);
Tony-LunarG00e7b7d2021-06-30 12:59:43 -0600273 if (aborted) return;
Tony-LunarG9b9dc022020-10-08 13:55:37 -0600274 UtilCopyCreatePipelineFeedbackData(count, pCreateInfos, crtpl_state->printf_create_infos.data());
Tony-LunarGb5fae462020-03-05 12:43:25 -0700275 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, this);
Tony-LunarG04717522019-10-17 10:41:17 -0600276}
277
Tony-LunarGfb2ab872021-01-13 15:17:15 -0700278void DebugPrintf::PostCallRecordCreateRayTracingPipelinesKHR(VkDevice device, VkDeferredOperationKHR deferredOperation,
279 VkPipelineCache pipelineCache, uint32_t count,
280 const VkRayTracingPipelineCreateInfoKHR *pCreateInfos,
281 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
282 VkResult result, void *crtpl_state_data) {
283 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_khr_api_state *>(crtpl_state_data);
284 ValidationStateTracker::PostCallRecordCreateRayTracingPipelinesKHR(
285 device, deferredOperation, pipelineCache, count, pCreateInfos, pAllocator, pPipelines, result, crtpl_state_data);
Tony-LunarG00e7b7d2021-06-30 12:59:43 -0600286 if (aborted) return;
Tony-LunarGfb2ab872021-01-13 15:17:15 -0700287 UtilCopyCreatePipelineFeedbackData(count, pCreateInfos, crtpl_state->printf_create_infos.data());
288 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, this);
289}
290
Tony-LunarG04717522019-10-17 10:41:17 -0600291// Remove all the shader trackers associated with this destroyed pipeline.
Tony-LunarGb5fae462020-03-05 12:43:25 -0700292void DebugPrintf::PreCallRecordDestroyPipeline(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks *pAllocator) {
Tony-LunarG04717522019-10-17 10:41:17 -0600293 for (auto it = shader_map.begin(); it != shader_map.end();) {
294 if (it->second.pipeline == pipeline) {
295 it = shader_map.erase(it);
296 } else {
297 ++it;
298 }
299 }
300 ValidationStateTracker::PreCallRecordDestroyPipeline(device, pipeline, pAllocator);
301}
302// Call the SPIR-V Optimizer to run the instrumentation pass on the shader.
Tony-LunarGb5fae462020-03-05 12:43:25 -0700303bool DebugPrintf::InstrumentShader(const VkShaderModuleCreateInfo *pCreateInfo, std::vector<unsigned int> &new_pgm,
304 uint32_t *unique_shader_id) {
Tony-LunarG04717522019-10-17 10:41:17 -0600305 if (aborted) return false;
306 if (pCreateInfo->pCode[0] != spv::MagicNumber) return false;
307
308 // Load original shader SPIR-V
309 uint32_t num_words = static_cast<uint32_t>(pCreateInfo->codeSize / 4);
310 new_pgm.clear();
311 new_pgm.reserve(num_words);
312 new_pgm.insert(new_pgm.end(), &pCreateInfo->pCode[0], &pCreateInfo->pCode[num_words]);
313
314 // Call the optimizer to instrument the shader.
315 // Use the unique_shader_module_id as a shader ID so we can look up its handle later in the shader_map.
316 // If descriptor indexing is enabled, enable length checks and updated descriptor checks
317 using namespace spvtools;
sfricke-samsung45996a42021-09-16 13:45:27 -0700318 spv_target_env target_env = PickSpirvEnv(api_version, IsExtEnabled(device_extensions.vk_khr_spirv_1_4));
Tony-LunarGf29f77f2020-08-26 15:48:00 -0600319 spvtools::ValidatorOptions val_options;
320 AdjustValidatorOptions(device_extensions, enabled_features, val_options);
321 spvtools::OptimizerOptions opt_options;
322 opt_options.set_run_validator(true);
323 opt_options.set_validator_options(val_options);
Tony-LunarG04717522019-10-17 10:41:17 -0600324 Optimizer optimizer(target_env);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700325 const spvtools::MessageConsumer debug_printf_console_message_consumer =
Tony-LunarG79641702020-07-13 15:43:05 -0600326 [this](spv_message_level_t level, const char *, const spv_position_t &position, const char *message) -> void {
327 switch (level) {
328 case SPV_MSG_FATAL:
329 case SPV_MSG_INTERNAL_ERROR:
330 case SPV_MSG_ERROR:
331 this->LogError(this->device, "UNASSIGNED-Debug-Printf", "Error during shader instrumentation: line %zu: %s",
332 position.index, message);
333 break;
334 default:
335 break;
336 }
337 };
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700338 optimizer.SetMessageConsumer(debug_printf_console_message_consumer);
Tony-LunarG04717522019-10-17 10:41:17 -0600339 optimizer.RegisterPass(CreateInstDebugPrintfPass(desc_set_bind_index, unique_shader_module_id));
Tony-LunarGf29f77f2020-08-26 15:48:00 -0600340 bool pass = optimizer.Run(new_pgm.data(), new_pgm.size(), &new_pgm, opt_options);
Tony-LunarG04717522019-10-17 10:41:17 -0600341 if (!pass) {
Tony-LunarG1dce2392019-10-23 16:49:29 -0600342 ReportSetupProblem(device, "Failure to instrument shader. Proceeding with non-instrumented shader.");
Tony-LunarG04717522019-10-17 10:41:17 -0600343 }
344 *unique_shader_id = unique_shader_module_id++;
345 return pass;
346}
347// Create the instrumented shader data to provide to the driver.
Tony-LunarGb5fae462020-03-05 12:43:25 -0700348void DebugPrintf::PreCallRecordCreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo *pCreateInfo,
349 const VkAllocationCallbacks *pAllocator, VkShaderModule *pShaderModule,
350 void *csm_state_data) {
Tony-LunarG04717522019-10-17 10:41:17 -0600351 create_shader_module_api_state *csm_state = reinterpret_cast<create_shader_module_api_state *>(csm_state_data);
352 bool pass = InstrumentShader(pCreateInfo, csm_state->instrumented_pgm, &csm_state->unique_shader_id);
353 if (pass) {
354 csm_state->instrumented_create_info.pCode = csm_state->instrumented_pgm.data();
355 csm_state->instrumented_create_info.codeSize = csm_state->instrumented_pgm.size() * sizeof(unsigned int);
356 }
357}
Tony-LunarG04717522019-10-17 10:41:17 -0600358
359vartype vartype_lookup(char intype) {
360 switch (intype) {
361 case 'd':
362 case 'i':
363 return varsigned;
364 break;
365
366 case 'f':
367 case 'F':
368 case 'a':
369 case 'A':
370 case 'e':
371 case 'E':
372 case 'g':
373 case 'G':
374 return varfloat;
375 break;
376
377 case 'u':
378 case 'x':
379 case 'o':
380 default:
381 return varunsigned;
382 break;
383 }
384}
385
Tony-LunarGa19e31e2020-03-30 13:30:29 -0600386std::vector<DPFSubstring> DebugPrintf::ParseFormatString(const std::string format_string) {
387 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 -0700388 std::vector<DPFSubstring> parsed_strings;
Tony-LunarG04717522019-10-17 10:41:17 -0600389 size_t pos = 0;
390 size_t begin = 0;
391 size_t percent = 0;
392
393 while (begin < format_string.length()) {
Tony-LunarGb5fae462020-03-05 12:43:25 -0700394 DPFSubstring substring;
Tony-LunarG04717522019-10-17 10:41:17 -0600395
396 // Find a percent sign
397 pos = percent = format_string.find_first_of('%', pos);
398 if (pos == std::string::npos) {
399 // End of the format string Push the rest of the characters
400 substring.string = format_string.substr(begin, format_string.length());
401 substring.needs_value = false;
402 parsed_strings.push_back(substring);
403 break;
404 }
405 pos++;
406 if (format_string[pos] == '%') {
407 pos++;
408 continue; // %% - skip it
409 }
410 // Find the type of the value
411 pos = format_string.find_first_of(types, pos);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700412 if (pos == format_string.npos) {
Tony-LunarG04717522019-10-17 10:41:17 -0600413 // This really shouldn't happen with a legal value string
414 pos = format_string.length();
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700415 } else {
Tony-LunarG04717522019-10-17 10:41:17 -0600416 char tempstring[32];
417 int count = 0;
418 std::string specifier = {};
419
420 if (format_string[pos] == 'v') {
421 // Vector must be of size 2, 3, or 4
422 // and format %v<size><type>
423 specifier = format_string.substr(percent, pos - percent);
424 count = atoi(&format_string[pos + 1]);
425 pos += 2;
426
427 // skip v<count>, handle long
428 specifier.push_back(format_string[pos]);
429 if (format_string[pos + 1] == 'l') {
430 specifier.push_back('l');
431 pos++;
432 }
433
434 // Take the preceding characters, and the percent through the type
435 substring.string = format_string.substr(begin, percent - begin);
436 substring.string += specifier;
437 substring.needs_value = true;
438 substring.type = vartype_lookup(specifier.back());
439 parsed_strings.push_back(substring);
440
441 // Continue with a comma separated list
442 sprintf(tempstring, ", %s", specifier.c_str());
443 substring.string = tempstring;
444 for (int i = 0; i < (count - 1); i++) {
445 parsed_strings.push_back(substring);
446 }
447 } else {
448 // Single non-vector value
449 if (format_string[pos + 1] == 'l') pos++; // Save long size
450 substring.string = format_string.substr(begin, pos - begin + 1);
451 substring.needs_value = true;
452 substring.type = vartype_lookup(format_string[pos]);
453 parsed_strings.push_back(substring);
454 }
455 begin = pos + 1;
456 }
457 }
458 return parsed_strings;
459}
460
Tony-LunarGb5fae462020-03-05 12:43:25 -0700461std::string DebugPrintf::FindFormatString(std::vector<unsigned int> pgm, uint32_t string_id) {
Tony-LunarG04717522019-10-17 10:41:17 -0600462 std::string format_string;
Nathaniel Cesario77cd59b2021-10-11 23:52:24 -0600463 SHADER_MODULE_STATE shader(pgm);
Tony-LunarG04717522019-10-17 10:41:17 -0600464 if (shader.words.size() > 0) {
John Zulauf79f06582021-02-27 18:38:39 -0700465 for (const auto &insn : shader) {
Tony-LunarG04717522019-10-17 10:41:17 -0600466 if (insn.opcode() == spv::OpString) {
467 uint32_t offset = insn.offset();
468 if (pgm[offset + 1] == string_id) {
469 format_string = reinterpret_cast<char *>(&pgm[offset + 2]);
470 break;
471 }
472 }
473 }
474 }
475
476 return format_string;
477}
478
Corentin Wallez171ac5e2020-03-31 16:09:05 +0200479// GCC and clang don't like using variables as format strings in sprintf.
480// #pragma GCC is recognized by both compilers
481#if defined(__GNUC__) || defined(__clang__)
Tony-LunarG04717522019-10-17 10:41:17 -0600482#pragma GCC diagnostic push
483#pragma GCC diagnostic ignored "-Wformat-security"
484#endif
485
Tony-LunarGb5fae462020-03-05 12:43:25 -0700486void snprintf_with_malloc(std::stringstream &shader_message, DPFSubstring substring, size_t needed, void *values) {
Tony-LunarG04717522019-10-17 10:41:17 -0600487 char *buffer = static_cast<char *>(malloc((needed + 1) * sizeof(char))); // Add 1 for terminator
488 if (substring.longval) {
489 snprintf(buffer, needed, substring.string.c_str(), substring.longval);
490 } else if (!substring.needs_value) {
491 snprintf(buffer, needed, substring.string.c_str());
492 } else {
493 switch (substring.type) {
494 case varunsigned:
495 needed = snprintf(buffer, needed, substring.string.c_str(), *static_cast<uint32_t *>(values) - 1);
496 break;
497
498 case varsigned:
499 needed = snprintf(buffer, needed, substring.string.c_str(), *static_cast<int32_t *>(values) - 1);
500 break;
501
502 case varfloat:
503 needed = snprintf(buffer, needed, substring.string.c_str(), *static_cast<float *>(values) - 1);
504 break;
505 }
506 }
507 shader_message << buffer;
508 free(buffer);
509}
510
Tony-LunarG7de10e82020-11-24 11:31:55 -0700511void DebugPrintf::AnalyzeAndGenerateMessages(VkCommandBuffer command_buffer, VkQueue queue, DPFBufferInfo &buffer_info,
Tony-LunarGb5fae462020-03-05 12:43:25 -0700512 uint32_t operation_index, uint32_t *const debug_output_buffer) {
Tony-LunarG04717522019-10-17 10:41:17 -0600513 // Word Content
514 // 0 Size of output record, including this word
515 // 1 Shader ID
516 // 2 Instruction Position
517 // 3 Stage Ordinal
518 // 4 Stage - specific Info Word 0
519 // 5 Stage - specific Info Word 1
520 // 6 Stage - specific Info Word 2
521 // 7 Printf Format String Id
522 // 8 Printf Values Word 0 (optional)
523 // 9 Printf Values Word 1 (optional)
Tony-LunarG12a7ec32019-11-01 13:00:05 -0600524 uint32_t expect = debug_output_buffer[0];
525 if (!expect) return;
Tony-LunarG04717522019-10-17 10:41:17 -0600526
Tony-LunarG12a7ec32019-11-01 13:00:05 -0600527 uint32_t index = 1;
Tony-LunarG04717522019-10-17 10:41:17 -0600528 while (debug_output_buffer[index]) {
Tony-LunarG04717522019-10-17 10:41:17 -0600529 std::stringstream shader_message;
Tony-LunarG04717522019-10-17 10:41:17 -0600530 VkShaderModule shader_module_handle = VK_NULL_HANDLE;
531 VkPipeline pipeline_handle = VK_NULL_HANDLE;
532 std::vector<unsigned int> pgm;
533
Tony-LunarGb5fae462020-03-05 12:43:25 -0700534 DPFOutputRecord *debug_record = reinterpret_cast<DPFOutputRecord *>(&debug_output_buffer[index]);
Tony-LunarG04717522019-10-17 10:41:17 -0600535 // Lookup the VkShaderModule handle and SPIR-V code used to create the shader, using the unique shader ID value returned
536 // by the instrumented shader.
537 auto it = shader_map.find(debug_record->shader_id);
538 if (it != shader_map.end()) {
539 shader_module_handle = it->second.shader_module;
540 pipeline_handle = it->second.pipeline;
541 pgm = it->second.pgm;
542 }
543 // Search through the shader source for the printf format string for this invocation
544 auto format_string = FindFormatString(pgm, debug_record->format_string_id);
545 // Break the format string into strings with 1 or 0 value
546 auto format_substrings = ParseFormatString(format_string);
547 void *values = static_cast<void *>(&debug_record->values);
548 const uint32_t static_size = 1024;
549 // Sprintf each format substring into a temporary string then add that to the message
550 for (auto &substring : format_substrings) {
551 char temp_string[static_size];
552 size_t needed = 0;
Tony-LunarGef469c92021-05-14 06:33:22 -0600553 std::vector<std::string> format_strings = { "%ul", "%lu", "%lx" };
554 size_t ul_pos = 0;
555 bool print_hex = true;
556 for (auto ul_string : format_strings) {
557 ul_pos = substring.string.find(ul_string);
558 if (ul_pos != std::string::npos) {
559 if (ul_string == "%lu") print_hex = false;
560 break;
561 }
562 }
Tony-LunarG04717522019-10-17 10:41:17 -0600563 if (ul_pos != std::string::npos) {
564 // Unsigned 64 bit value
565 substring.longval = *static_cast<uint64_t *>(values);
566 values = static_cast<uint64_t *>(values) + 1;
Tony-LunarGef469c92021-05-14 06:33:22 -0600567 if (print_hex) {
568 substring.string.replace(ul_pos + 1, 2, PRIx64);
569 } else {
570 substring.string.replace(ul_pos + 1, 2, PRIu64);
571 }
Tony-LunarG04717522019-10-17 10:41:17 -0600572 needed = snprintf(temp_string, static_size, substring.string.c_str(), substring.longval);
573 } else {
574 if (substring.needs_value) {
575 switch (substring.type) {
576 case varunsigned:
577 needed = snprintf(temp_string, static_size, substring.string.c_str(), *static_cast<uint32_t *>(values));
578 break;
579
580 case varsigned:
581 needed = snprintf(temp_string, static_size, substring.string.c_str(), *static_cast<int32_t *>(values));
582 break;
583
584 case varfloat:
585 needed = snprintf(temp_string, static_size, substring.string.c_str(), *static_cast<float *>(values));
586 break;
587 }
588 values = static_cast<uint32_t *>(values) + 1;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700589 } else {
Tony-LunarG04717522019-10-17 10:41:17 -0600590 needed = snprintf(temp_string, static_size, substring.string.c_str());
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700591 }
Tony-LunarG04717522019-10-17 10:41:17 -0600592 }
593
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700594 if (needed < static_size) {
Tony-LunarG04717522019-10-17 10:41:17 -0600595 shader_message << temp_string;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700596 } else {
Tony-LunarG04717522019-10-17 10:41:17 -0600597 // Static buffer not big enough for message, use malloc to get enough
598 snprintf_with_malloc(shader_message, substring, needed, values);
599 }
600 }
Tony-LunarG43416b42019-10-31 16:47:24 -0600601
602 if (verbose) {
603 std::string stage_message;
604 std::string common_message;
605 std::string filename_message;
606 std::string source_message;
Tony-LunarGb5fae462020-03-05 12:43:25 -0700607 UtilGenerateStageMessage(&debug_output_buffer[index], stage_message);
608 UtilGenerateCommonMessage(report_data, command_buffer, &debug_output_buffer[index], shader_module_handle,
Tony-LunarG7de10e82020-11-24 11:31:55 -0700609 pipeline_handle, buffer_info.pipeline_bind_point, operation_index, common_message);
Tony-LunarGb5fae462020-03-05 12:43:25 -0700610 UtilGenerateSourceMessages(pgm, &debug_output_buffer[index], true, filename_message, source_message);
Tony-LunarG43416b42019-10-31 16:47:24 -0600611 if (use_stdout) {
Tony-LunarG5af54eb2020-03-27 15:32:51 -0600612 std::cout << "UNASSIGNED-DEBUG-PRINTF " << common_message.c_str() << " " << stage_message.c_str() << " "
Tony-LunarGb5fae462020-03-05 12:43:25 -0700613 << shader_message.str().c_str() << " " << filename_message.c_str() << " " << source_message.c_str();
Tony-LunarG43416b42019-10-31 16:47:24 -0600614 } else {
Tony-LunarG5af54eb2020-03-27 15:32:51 -0600615 LogInfo(queue, "UNASSIGNED-DEBUG-PRINTF", "%s %s %s %s%s", common_message.c_str(), stage_message.c_str(),
616 shader_message.str().c_str(), filename_message.c_str(), source_message.c_str());
Tony-LunarG43416b42019-10-31 16:47:24 -0600617 }
618 } else {
Tony-LunarG5af54eb2020-03-27 15:32:51 -0600619 if (use_stdout) {
Tony-LunarG43416b42019-10-31 16:47:24 -0600620 std::cout << shader_message.str();
Tony-LunarG5af54eb2020-03-27 15:32:51 -0600621 } else {
622 // Don't let LogInfo process any '%'s in the string
623 LogInfo(device, "UNASSIGNED-DEBUG-PRINTF", "%s", shader_message.str().c_str());
624 }
Tony-LunarG43416b42019-10-31 16:47:24 -0600625 }
Tony-LunarG04717522019-10-17 10:41:17 -0600626 index += debug_record->size;
627 }
Tony-LunarG12a7ec32019-11-01 13:00:05 -0600628 if ((index - 1) != expect) {
Tony-LunarG5af54eb2020-03-27 15:32:51 -0600629 LogWarning(device, "UNASSIGNED-DEBUG-PRINTF",
630 "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 -0600631 }
Tony-LunarG04717522019-10-17 10:41:17 -0600632 memset(debug_output_buffer, 0, 4 * (debug_output_buffer[0] + 1));
633}
Tony-LunarG43416b42019-10-31 16:47:24 -0600634
Tony-LunarG04717522019-10-17 10:41:17 -0600635#if defined(__GNUC__)
636#pragma GCC diagnostic pop
637#endif
638
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700639bool DebugPrintf::CommandBufferNeedsProcessing(VkCommandBuffer command_buffer) {
640 bool buffers_present = false;
641 auto cb_node = GetCBState(command_buffer);
Jeremy Gebben9f537102021-10-05 16:37:12 -0600642 if (GetBufferInfo(cb_node.get()).size()) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700643 buffers_present = true;
644 }
John Zulauf79f06582021-02-27 18:38:39 -0700645 for (const auto *secondaryCmdBuffer : cb_node->linkedCommandBuffers) {
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600646 if (GetBufferInfo(secondaryCmdBuffer).size()) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700647 buffers_present = true;
648 }
649 }
650 return buffers_present;
651}
652
653void DebugPrintf::ProcessCommandBuffer(VkQueue queue, VkCommandBuffer command_buffer) {
654 auto cb_node = GetCBState(command_buffer);
Jeremy Gebben9f537102021-10-05 16:37:12 -0600655 UtilProcessInstrumentationBuffer(queue, cb_node.get(), this);
John Zulauf79f06582021-02-27 18:38:39 -0700656 for (auto *secondary_cmd_buffer : cb_node->linkedCommandBuffers) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700657 UtilProcessInstrumentationBuffer(queue, secondary_cmd_buffer, this);
658 }
659}
660
Tony-LunarG04717522019-10-17 10:41:17 -0600661// Issue a memory barrier to make GPU-written data available to host.
662// Wait for the queue to complete execution.
663// Check the debug buffers for all the command buffers that were submitted.
Tony-LunarGb5fae462020-03-05 12:43:25 -0700664void DebugPrintf::PostCallRecordQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence,
665 VkResult result) {
Tony-LunarG04717522019-10-17 10:41:17 -0600666 ValidationStateTracker::PostCallRecordQueueSubmit(queue, submitCount, pSubmits, fence, result);
667
Mark Lobodzinski09379db2020-05-07 08:22:01 -0600668 if (aborted || (result != VK_SUCCESS)) return;
Tony-LunarG04717522019-10-17 10:41:17 -0600669 bool buffers_present = false;
670 // Don't QueueWaitIdle if there's nothing to process
671 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
672 const VkSubmitInfo *submit = &pSubmits[submit_idx];
673 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700674 buffers_present |= CommandBufferNeedsProcessing(submit->pCommandBuffers[i]);
Tony-LunarG04717522019-10-17 10:41:17 -0600675 }
676 }
677 if (!buffers_present) return;
678
Tony-LunarGb5fae462020-03-05 12:43:25 -0700679 UtilSubmitBarrier(queue, this);
Tony-LunarG04717522019-10-17 10:41:17 -0600680
681 DispatchQueueWaitIdle(queue);
682
683 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
684 const VkSubmitInfo *submit = &pSubmits[submit_idx];
685 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700686 ProcessCommandBuffer(queue, submit->pCommandBuffers[i]);
687 }
688 }
689}
690
691void DebugPrintf::PostCallRecordQueueSubmit2KHR(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2KHR *pSubmits,
692 VkFence fence, VkResult result) {
693 ValidationStateTracker::PostCallRecordQueueSubmit2KHR(queue, submitCount, pSubmits, fence, result);
694
695 if (aborted || (result != VK_SUCCESS)) return;
696 bool buffers_present = false;
697 // Don't QueueWaitIdle if there's nothing to process
698 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
699 const auto *submit = &pSubmits[submit_idx];
700 for (uint32_t i = 0; i < submit->commandBufferInfoCount; i++) {
701 buffers_present |= CommandBufferNeedsProcessing(submit->pCommandBufferInfos[i].commandBuffer);
702 }
703 }
704 if (!buffers_present) return;
705
706 UtilSubmitBarrier(queue, this);
707
708 DispatchQueueWaitIdle(queue);
709
710 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
711 const VkSubmitInfo2KHR *submit = &pSubmits[submit_idx];
712 for (uint32_t i = 0; i < submit->commandBufferInfoCount; i++) {
713 ProcessCommandBuffer(queue, submit->pCommandBufferInfos[i].commandBuffer);
Tony-LunarG04717522019-10-17 10:41:17 -0600714 }
715 }
716}
717
Tony-LunarGb5fae462020-03-05 12:43:25 -0700718void DebugPrintf::PreCallRecordCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
719 uint32_t firstVertex, uint32_t firstInstance) {
720 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
Tony-LunarG04717522019-10-17 10:41:17 -0600721}
722
Tony-LunarG745150c2021-07-02 15:07:31 -0600723void DebugPrintf::PreCallRecordCmdDrawMultiEXT(VkCommandBuffer commandBuffer, uint32_t drawCount,
724 const VkMultiDrawInfoEXT *pVertexInfo, uint32_t instanceCount,
725 uint32_t firstInstance, uint32_t stride) {
726 for(uint32_t i = 0; i < drawCount; i++) {
727 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
728 }
729}
730
Tony-LunarGb5fae462020-03-05 12:43:25 -0700731void DebugPrintf::PreCallRecordCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount,
732 uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) {
733 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
Tony-LunarG04717522019-10-17 10:41:17 -0600734}
735
Tony-LunarG745150c2021-07-02 15:07:31 -0600736void DebugPrintf::PreCallRecordCmdDrawMultiIndexedEXT(VkCommandBuffer commandBuffer, uint32_t drawCount,
737 const VkMultiDrawIndexedInfoEXT *pIndexInfo, uint32_t instanceCount,
738 uint32_t firstInstance, uint32_t stride, const int32_t *pVertexOffset) {
739 for (uint32_t i = 0; i < drawCount; i++) {
740 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
741 }
742}
743
Tony-LunarGb5fae462020-03-05 12:43:25 -0700744void DebugPrintf::PreCallRecordCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count,
745 uint32_t stride) {
746 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
Tony-LunarG04717522019-10-17 10:41:17 -0600747}
748
Tony-LunarGb5fae462020-03-05 12:43:25 -0700749void DebugPrintf::PreCallRecordCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
750 uint32_t count, uint32_t stride) {
751 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
Tony-LunarG04717522019-10-17 10:41:17 -0600752}
753
Tony-LunarGb5fae462020-03-05 12:43:25 -0700754void DebugPrintf::PreCallRecordCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
755 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE);
Tony-LunarG04717522019-10-17 10:41:17 -0600756}
757
Tony-LunarGb5fae462020-03-05 12:43:25 -0700758void DebugPrintf::PreCallRecordCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
759 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE);
Tony-LunarG04717522019-10-17 10:41:17 -0600760}
761
Tony-LunarGd13f9b52020-09-08 15:45:45 -0600762void DebugPrintf::PreCallRecordCmdDispatchBase(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY,
763 uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY,
764 uint32_t groupCountZ) {
765 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE);
766}
767
Tony-LunarG52c8c602020-09-10 16:29:56 -0600768void DebugPrintf::PreCallRecordCmdDispatchBaseKHR(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY,
769 uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY,
770 uint32_t groupCountZ) {
771 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE);
772}
773
Tony-LunarG2fb8ff02020-06-11 12:45:07 -0600774void DebugPrintf::PreCallRecordCmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
775 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
776 uint32_t stride) {
777 ValidationStateTracker::PreCallRecordCmdDrawIndirectCountKHR(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
778 maxDrawCount, stride);
779 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
780}
781
782void DebugPrintf::PreCallRecordCmdDrawIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
783 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
784 uint32_t stride) {
785 ValidationStateTracker::PreCallRecordCmdDrawIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
786 maxDrawCount, stride);
787 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
788}
789
790void DebugPrintf::PreCallRecordCmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
791 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
792 uint32_t maxDrawCount, uint32_t stride) {
793 ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirectCountKHR(commandBuffer, buffer, offset, countBuffer,
794 countBufferOffset, maxDrawCount, stride);
795 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
796}
797
798void DebugPrintf::PreCallRecordCmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
799 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
800 uint32_t maxDrawCount, uint32_t stride) {
801 ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
802 maxDrawCount, stride);
803 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
804}
805
Tony-LunarG54176fb2020-12-02 10:47:22 -0700806void DebugPrintf::PreCallRecordCmdDrawIndirectByteCountEXT(VkCommandBuffer commandBuffer, uint32_t instanceCount,
807 uint32_t firstInstance, VkBuffer counterBuffer,
808 VkDeviceSize counterBufferOffset, uint32_t counterOffset,
809 uint32_t vertexStride) {
810 ValidationStateTracker::PreCallRecordCmdDrawIndirectByteCountEXT(commandBuffer, instanceCount, firstInstance, counterBuffer,
811 counterBufferOffset, counterOffset, vertexStride);
812 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
813}
814
Tony-LunarG2fb8ff02020-06-11 12:45:07 -0600815void DebugPrintf::PreCallRecordCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask) {
816 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksNV(commandBuffer, taskCount, firstTask);
817 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
818}
819
820void DebugPrintf::PreCallRecordCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
821 uint32_t drawCount, uint32_t stride) {
822 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksIndirectNV(commandBuffer, buffer, offset, drawCount, stride);
823 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
824}
825
826void DebugPrintf::PreCallRecordCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
827 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
828 uint32_t maxDrawCount, uint32_t stride) {
829 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksIndirectCountNV(commandBuffer, buffer, offset, countBuffer,
830 countBufferOffset, maxDrawCount, stride);
831 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
832}
833
Tony-LunarGb5fae462020-03-05 12:43:25 -0700834void DebugPrintf::PreCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
835 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
836 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
837 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
838 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
839 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
840 uint32_t width, uint32_t height, uint32_t depth) {
841 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV);
842}
843
844void DebugPrintf::PostCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
Tony-LunarG04717522019-10-17 10:41:17 -0600845 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
846 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
847 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
848 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
849 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
850 uint32_t width, uint32_t height, uint32_t depth) {
Jeremy Gebben9f537102021-10-05 16:37:12 -0600851 auto cb_state = GetCBState(commandBuffer);
Tony-LunarG04717522019-10-17 10:41:17 -0600852 cb_state->hasTraceRaysCmd = true;
853}
854
Tony-LunarGb5fae462020-03-05 12:43:25 -0700855void DebugPrintf::PreCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -0700856 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
857 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
858 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
859 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable, uint32_t width,
Tony-LunarGb5fae462020-03-05 12:43:25 -0700860 uint32_t height, uint32_t depth) {
861 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR);
Tony-LunarG1dce2392019-10-23 16:49:29 -0600862}
863
Tony-LunarGb5fae462020-03-05 12:43:25 -0700864void DebugPrintf::PostCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -0700865 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
866 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
867 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
868 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable, uint32_t width,
Tony-LunarGb5fae462020-03-05 12:43:25 -0700869 uint32_t height, uint32_t depth) {
Jeremy Gebben9f537102021-10-05 16:37:12 -0600870 auto cb_state = GetCBState(commandBuffer);
Tony-LunarG1dce2392019-10-23 16:49:29 -0600871 cb_state->hasTraceRaysCmd = true;
872}
873
Tony-LunarGb5fae462020-03-05 12:43:25 -0700874void DebugPrintf::PreCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -0700875 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
876 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
877 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
878 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable,
Shannon McPherson54e1f892020-11-27 11:04:19 -0700879 VkDeviceAddress indirectDeviceAddress) {
Tony-LunarGb5fae462020-03-05 12:43:25 -0700880 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR);
Tony-LunarG1dce2392019-10-23 16:49:29 -0600881}
882
Tony-LunarGb5fae462020-03-05 12:43:25 -0700883void DebugPrintf::PostCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -0700884 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
885 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
886 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
887 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable,
Shannon McPherson54e1f892020-11-27 11:04:19 -0700888 VkDeviceAddress indirectDeviceAddress) {
Jeremy Gebben9f537102021-10-05 16:37:12 -0600889 auto cb_state = GetCBState(commandBuffer);
Tony-LunarG1dce2392019-10-23 16:49:29 -0600890 cb_state->hasTraceRaysCmd = true;
891}
892
Tony-LunarGb5fae462020-03-05 12:43:25 -0700893void DebugPrintf::AllocateDebugPrintfResources(const VkCommandBuffer cmd_buffer, const VkPipelineBindPoint bind_point) {
Tony-LunarG04717522019-10-17 10:41:17 -0600894 if (bind_point != VK_PIPELINE_BIND_POINT_GRAPHICS && bind_point != VK_PIPELINE_BIND_POINT_COMPUTE &&
895 bind_point != VK_PIPELINE_BIND_POINT_RAY_TRACING_NV) {
896 return;
897 }
898 VkResult result;
899
900 if (aborted) return;
901
902 std::vector<VkDescriptorSet> desc_sets;
903 VkDescriptorPool desc_pool = VK_NULL_HANDLE;
Tony-LunarG1dce2392019-10-23 16:49:29 -0600904 result = desc_set_manager->GetDescriptorSets(1, &desc_pool, debug_desc_layout, &desc_sets);
Tony-LunarG04717522019-10-17 10:41:17 -0600905 assert(result == VK_SUCCESS);
906 if (result != VK_SUCCESS) {
Tony-LunarG1dce2392019-10-23 16:49:29 -0600907 ReportSetupProblem(device, "Unable to allocate descriptor sets. Device could become unstable.");
Tony-LunarG04717522019-10-17 10:41:17 -0600908 aborted = true;
909 return;
910 }
911
912 VkDescriptorBufferInfo output_desc_buffer_info = {};
913 output_desc_buffer_info.range = output_buffer_size;
914
915 auto cb_node = GetCBState(cmd_buffer);
916 if (!cb_node) {
Tony-LunarG1dce2392019-10-23 16:49:29 -0600917 ReportSetupProblem(device, "Unrecognized command buffer");
Tony-LunarG04717522019-10-17 10:41:17 -0600918 aborted = true;
919 return;
920 }
921
922 // Allocate memory for the output block that the gpu will use to return values for printf
Tony-LunarGb5fae462020-03-05 12:43:25 -0700923 DPFDeviceMemoryBlock output_block = {};
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700924 VkBufferCreateInfo buffer_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
925 buffer_info.size = output_buffer_size;
926 buffer_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
927 VmaAllocationCreateInfo alloc_info = {};
928 alloc_info.usage = VMA_MEMORY_USAGE_GPU_TO_CPU;
929 result = vmaCreateBuffer(vmaAllocator, &buffer_info, &alloc_info, &output_block.buffer, &output_block.allocation, nullptr);
Tony-LunarG04717522019-10-17 10:41:17 -0600930 if (result != VK_SUCCESS) {
Tony-LunarG1dce2392019-10-23 16:49:29 -0600931 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
Tony-LunarG04717522019-10-17 10:41:17 -0600932 aborted = true;
933 return;
934 }
935
936 // Clear the output block to zeros so that only printf values from the gpu will be present
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700937 uint32_t *data;
938 result = vmaMapMemory(vmaAllocator, output_block.allocation, reinterpret_cast<void **>(&data));
Tony-LunarG04717522019-10-17 10:41:17 -0600939 if (result == VK_SUCCESS) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700940 memset(data, 0, output_buffer_size);
Tony-LunarG04717522019-10-17 10:41:17 -0600941 vmaUnmapMemory(vmaAllocator, output_block.allocation);
942 }
943
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600944 auto desc_writes = LvlInitStruct<VkWriteDescriptorSet>();
Tony-LunarG04717522019-10-17 10:41:17 -0600945 const uint32_t desc_count = 1;
946
947 // Write the descriptor
948 output_desc_buffer_info.buffer = output_block.buffer;
949 output_desc_buffer_info.offset = 0;
950
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600951 desc_writes.descriptorCount = 1;
952 desc_writes.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
953 desc_writes.pBufferInfo = &output_desc_buffer_info;
954 desc_writes.dstSet = desc_sets[0];
955 desc_writes.dstBinding = 3;
956 DispatchUpdateDescriptorSets(device, desc_count, &desc_writes, 0, NULL);
Tony-LunarG04717522019-10-17 10:41:17 -0600957
locke-lunargb8d7a7a2020-10-25 16:01:52 -0600958 const auto lv_bind_point = ConvertToLvlBindPoint(bind_point);
959 const auto *pipeline_state = cb_node->lastBound[lv_bind_point].pipeline_state;
960 if (pipeline_state) {
961 if (pipeline_state->pipeline_layout->set_layouts.size() <= desc_set_bind_index) {
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -0600962 DispatchCmdBindDescriptorSets(cmd_buffer, bind_point, pipeline_state->pipeline_layout->layout(), desc_set_bind_index, 1,
Tony-LunarG04717522019-10-17 10:41:17 -0600963 desc_sets.data(), 0, nullptr);
964 }
965 // Record buffer and memory info in CB state tracking
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600966 cb_node->buffer_infos.emplace_back(output_block, desc_sets[0], desc_pool, bind_point);
Tony-LunarG04717522019-10-17 10:41:17 -0600967 } else {
Tony-LunarG1dce2392019-10-23 16:49:29 -0600968 ReportSetupProblem(device, "Unable to find pipeline state");
Tony-LunarG04717522019-10-17 10:41:17 -0600969 vmaDestroyBuffer(vmaAllocator, output_block.buffer, output_block.allocation);
970 aborted = true;
971 return;
972 }
973}
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600974
975std::shared_ptr<CMD_BUFFER_STATE> DebugPrintf::CreateCmdBufferState(VkCommandBuffer cb,
976 const VkCommandBufferAllocateInfo *pCreateInfo,
Jeremy Gebbencd7fa282021-10-27 10:25:32 -0600977 const COMMAND_POOL_STATE *pool) {
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600978 return std::static_pointer_cast<CMD_BUFFER_STATE>(std::make_shared<CMD_BUFFER_STATE_PRINTF>(this, cb, pCreateInfo, pool));
979}
980
981CMD_BUFFER_STATE_PRINTF::CMD_BUFFER_STATE_PRINTF(DebugPrintf *dp, VkCommandBuffer cb,
Jeremy Gebbencd7fa282021-10-27 10:25:32 -0600982 const VkCommandBufferAllocateInfo *pCreateInfo, const COMMAND_POOL_STATE *pool)
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600983 : CMD_BUFFER_STATE(dp, cb, pCreateInfo, pool) {}
984
985void CMD_BUFFER_STATE_PRINTF::Reset() {
986 CMD_BUFFER_STATE::Reset();
987 auto debug_printf = static_cast<DebugPrintf *>(dev_data);
988 // Free the device memory and descriptor set(s) associated with a command buffer.
989 if (debug_printf->aborted) {
990 return;
991 }
992 for (auto &buffer_info : buffer_infos) {
993 debug_printf->DestroyBuffer(buffer_info);
994 }
995 buffer_infos.clear();
996}