blob: f0f100d18de7ed648bbccfdb97d8ee219eb34daf [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-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) {
Jeremy Gebben36a3b832022-03-23 10:54:18 -060042 // Use a local variable to query features since this method runs in the instance validation object.
43 // To avoid confusion and race conditions about which physical device's features are stored in the
44 // 'supported_devices' member variable, it will only be set in the device validation objects.
45 // See CreateDevice() below.
46 VkPhysicalDeviceFeatures gpu_supported_features;
47 DispatchGetPhysicalDeviceFeatures(gpu, &gpu_supported_features);
Tony-LunarG1dce2392019-10-23 16:49:29 -060048 VkPhysicalDeviceFeatures features = {};
49 features.vertexPipelineStoresAndAtomics = true;
50 features.fragmentStoresAndAtomics = true;
Jeremy Gebben36a3b832022-03-23 10:54:18 -060051 UtilPreCallRecordCreateDevice(gpu, reinterpret_cast<safe_VkDeviceCreateInfo *>(modified_create_info), gpu_supported_features,
Mark Lobodzinskib588cd42020-09-30 11:03:34 -060052 features);
Tony-LunarG04717522019-10-17 10:41:17 -060053}
Tony-LunarG1dce2392019-10-23 16:49:29 -060054
Tony-LunarG04717522019-10-17 10:41:17 -060055// Perform initializations that can be done at Create Device time.
Jeremy Gebben36a3b832022-03-23 10:54:18 -060056void DebugPrintf::CreateDevice(const VkDeviceCreateInfo *pCreateInfo) {
57 ValidationStateTracker::CreateDevice(pCreateInfo);
Tony-LunarG43416b42019-10-31 16:47:24 -060058
59 const char *size_string = getLayerOption("khronos_validation.printf_buffer_size");
Jeremy Gebben36a3b832022-03-23 10:54:18 -060060 output_buffer_size = *size_string ? atoi(size_string) : 1024;
Tony-LunarGc99dbef2021-06-14 15:11:50 -060061
62 std::string verbose_string = getLayerOption("khronos_validation.printf_verbose");
63 transform(verbose_string.begin(), verbose_string.end(), verbose_string.begin(), ::tolower);
Jeremy Gebben36a3b832022-03-23 10:54:18 -060064 verbose = verbose_string.length() ? !verbose_string.compare("true") : false;
Tony-LunarGc99dbef2021-06-14 15:11:50 -060065
66 std::string stdout_string = getLayerOption("khronos_validation.printf_to_stdout");
67 transform(stdout_string.begin(), stdout_string.end(), stdout_string.begin(), ::tolower);
Jeremy Gebben36a3b832022-03-23 10:54:18 -060068 use_stdout = stdout_string.length() ? !stdout_string.compare("true") : false;
69 if (getenv("DEBUG_PRINTF_TO_STDOUT")) use_stdout = true;
Tony-LunarG04717522019-10-17 10:41:17 -060070
Jeremy Gebben36a3b832022-03-23 10:54:18 -060071 if (phys_dev_props.apiVersion < VK_API_VERSION_1_1) {
Tony-LunarGbbbed672020-03-04 10:51:11 -070072 ReportSetupProblem(device, "Debug Printf requires Vulkan 1.1 or later. Debug Printf disabled.");
Jeremy Gebben36a3b832022-03-23 10:54:18 -060073 aborted = true;
Tony-LunarG04717522019-10-17 10:41:17 -060074 return;
75 }
76
Jeremy Gebben36a3b832022-03-23 10:54:18 -060077 DispatchGetPhysicalDeviceFeatures(physical_device, &supported_features);
Tony-LunarG04717522019-10-17 10:41:17 -060078 if (!supported_features.fragmentStoresAndAtomics || !supported_features.vertexPipelineStoresAndAtomics) {
Tony-LunarG1dce2392019-10-23 16:49:29 -060079 ReportSetupProblem(device,
Tony-LunarGbbbed672020-03-04 10:51:11 -070080 "Debug Printf requires fragmentStoresAndAtomics and vertexPipelineStoresAndAtomics. "
81 "Debug Printf disabled.");
Jeremy Gebben36a3b832022-03-23 10:54:18 -060082 aborted = true;
Tony-LunarG04717522019-10-17 10:41:17 -060083 return;
84 }
Tony-LunarG9586e732020-03-04 10:50:30 -070085
Mark Lobodzinski90eea5b2020-05-15 12:54:00 -060086 if (enabled[gpu_validation]) {
Tony-LunarG9586e732020-03-04 10:50:30 -070087 ReportSetupProblem(device,
88 "Debug Printf cannot be enabled when gpu assisted validation is enabled. "
89 "Debug Printf disabled.");
Jeremy Gebben36a3b832022-03-23 10:54:18 -060090 aborted = true;
Tony-LunarG9586e732020-03-04 10:50:30 -070091 return;
92 }
93
Tony-LunarG1dce2392019-10-23 16:49:29 -060094 std::vector<VkDescriptorSetLayoutBinding> bindings;
95 VkDescriptorSetLayoutBinding binding = {3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
Tony-LunarGc7ed2082020-06-11 14:00:04 -060096 VK_SHADER_STAGE_ALL_GRAPHICS | VK_SHADER_STAGE_MESH_BIT_NV |
97 VK_SHADER_STAGE_TASK_BIT_NV | VK_SHADER_STAGE_COMPUTE_BIT |
98 kShaderStageAllRayTracing,
Tony-LunarG1dce2392019-10-23 16:49:29 -060099 NULL};
100 bindings.push_back(binding);
Jeremy Gebben36a3b832022-03-23 10:54:18 -0600101 UtilPostCallRecordCreateDevice(pCreateInfo, bindings, this, phys_dev_props);
Tony-LunarG04717522019-10-17 10:41:17 -0600102}
103
Tony-LunarGb5fae462020-03-05 12:43:25 -0700104void DebugPrintf::PreCallRecordDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
105 UtilPreCallRecordDestroyDevice(this);
Tony-LunarG0a863bc2020-09-16 09:50:04 -0600106 ValidationStateTracker::PreCallRecordDestroyDevice(device, pAllocator);
107 // State Tracker can end up making vma calls through callbacks - don't destroy allocator until ST is done
108 if (vmaAllocator) {
109 vmaDestroyAllocator(vmaAllocator);
110 }
111 desc_set_manager.reset();
Tony-LunarG04717522019-10-17 10:41:17 -0600112}
113
114// 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 -0700115void DebugPrintf::PreCallRecordCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo,
116 const VkAllocationCallbacks *pAllocator, VkPipelineLayout *pPipelineLayout,
117 void *cpl_state_data) {
Tony-LunarG04717522019-10-17 10:41:17 -0600118 if (aborted) {
119 return;
120 }
121
122 create_pipeline_layout_api_state *cpl_state = reinterpret_cast<create_pipeline_layout_api_state *>(cpl_state_data);
123
124 if (cpl_state->modified_create_info.setLayoutCount >= adjusted_max_desc_sets) {
125 std::ostringstream strm;
126 strm << "Pipeline Layout conflict with validation's descriptor set at slot " << desc_set_bind_index << ". "
Tony-LunarGbbbed672020-03-04 10:51:11 -0700127 << "Application has too many descriptor sets in the pipeline layout to continue with debug printf. "
Tony-LunarG04717522019-10-17 10:41:17 -0600128 << "Not modifying the pipeline layout. "
129 << "Instrumented shaders are replaced with non-instrumented shaders.";
Tony-LunarG1dce2392019-10-23 16:49:29 -0600130 ReportSetupProblem(device, strm.str().c_str());
Tony-LunarG04717522019-10-17 10:41:17 -0600131 } else {
Tony-LunarGb5fae462020-03-05 12:43:25 -0700132 UtilPreCallRecordCreatePipelineLayout(cpl_state, this, pCreateInfo);
Tony-LunarG04717522019-10-17 10:41:17 -0600133 }
134}
135
Tony-LunarGb5fae462020-03-05 12:43:25 -0700136void DebugPrintf::PostCallRecordCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo,
137 const VkAllocationCallbacks *pAllocator, VkPipelineLayout *pPipelineLayout,
138 VkResult result) {
Tony-LunarG04717522019-10-17 10:41:17 -0600139 ValidationStateTracker::PostCallRecordCreatePipelineLayout(device, pCreateInfo, pAllocator, pPipelineLayout, result);
140 if (result != VK_SUCCESS) {
Tony-LunarG1dce2392019-10-23 16:49:29 -0600141 ReportSetupProblem(device, "Unable to create pipeline layout. Device could become unstable.");
Tony-LunarG04717522019-10-17 10:41:17 -0600142 aborted = true;
143 }
144}
145
146// Free the device memory and descriptor set associated with a command buffer.
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600147void DebugPrintf::DestroyBuffer(DPFBufferInfo &buffer_info) {
148 vmaDestroyBuffer(vmaAllocator, buffer_info.output_mem_block.buffer, buffer_info.output_mem_block.allocation);
149 if (buffer_info.desc_set != VK_NULL_HANDLE) {
150 desc_set_manager->PutBackDescriptorSet(buffer_info.desc_pool, buffer_info.desc_set);
Tony-LunarG04717522019-10-17 10:41:17 -0600151 }
Tony-LunarG04717522019-10-17 10:41:17 -0600152}
153
154// Just gives a warning about a possible deadlock.
Tony-LunarGb5fae462020-03-05 12:43:25 -0700155bool DebugPrintf::PreCallValidateCmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
156 VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask,
157 uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
158 uint32_t bufferMemoryBarrierCount,
159 const VkBufferMemoryBarrier *pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount,
160 const VkImageMemoryBarrier *pImageMemoryBarriers) const {
Tony-LunarG04717522019-10-17 10:41:17 -0600161 if (srcStageMask & VK_PIPELINE_STAGE_HOST_BIT) {
Tony-LunarG1dce2392019-10-23 16:49:29 -0600162 ReportSetupProblem(commandBuffer,
163 "CmdWaitEvents recorded with VK_PIPELINE_STAGE_HOST_BIT set. "
Tony-LunarGbbbed672020-03-04 10:51:11 -0700164 "Debug Printf waits on queue completion. "
Tony-LunarG1dce2392019-10-23 16:49:29 -0600165 "This wait could block the host's signaling of this event, resulting in deadlock.");
Tony-LunarG04717522019-10-17 10:41:17 -0600166 }
167 return false;
168}
169
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700170bool DebugPrintf::PreCallValidateCmdWaitEvents2KHR(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
171 const VkDependencyInfoKHR *pDependencyInfos) const {
Jeremy Gebbenf18d4362022-01-27 14:37:25 -0700172 VkPipelineStageFlags2KHR src_stage_mask = 0;
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700173
174 for (uint32_t i = 0; i < eventCount; i++) {
175 auto stage_masks = sync_utils::GetGlobalStageMasks(pDependencyInfos[i]);
Jeremy Gebbenf18d4362022-01-27 14:37:25 -0700176 src_stage_mask |= stage_masks.src;
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700177 }
178
Jeremy Gebbenf18d4362022-01-27 14:37:25 -0700179 if (src_stage_mask & VK_PIPELINE_STAGE_HOST_BIT) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700180 ReportSetupProblem(commandBuffer,
181 "CmdWaitEvents2KHR recorded with VK_PIPELINE_STAGE_HOST_BIT set. "
182 "Debug Printf waits on queue completion. "
183 "This wait could block the host's signaling of this event, resulting in deadlock.");
184 }
185 return false;
186}
187
Tony-LunarG1364cf52021-11-17 16:10:11 -0700188bool DebugPrintf::PreCallValidateCmdWaitEvents2(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
189 const VkDependencyInfo *pDependencyInfos) const {
Jeremy Gebbenf18d4362022-01-27 14:37:25 -0700190 VkPipelineStageFlags2 src_stage_mask = 0;
Tony-LunarG1364cf52021-11-17 16:10:11 -0700191
192 for (uint32_t i = 0; i < eventCount; i++) {
193 auto stage_masks = sync_utils::GetGlobalStageMasks(pDependencyInfos[i]);
Jeremy Gebbenf18d4362022-01-27 14:37:25 -0700194 src_stage_mask |= stage_masks.src;
Tony-LunarG1364cf52021-11-17 16:10:11 -0700195 }
196
Jeremy Gebbenf18d4362022-01-27 14:37:25 -0700197 if (src_stage_mask & VK_PIPELINE_STAGE_HOST_BIT) {
Tony-LunarG1364cf52021-11-17 16:10:11 -0700198 ReportSetupProblem(commandBuffer,
199 "CmdWaitEvents2 recorded with VK_PIPELINE_STAGE_HOST_BIT set. "
200 "Debug Printf waits on queue completion. "
201 "This wait could block the host's signaling of this event, resulting in deadlock.");
202 }
203 return false;
204}
205
Tony-LunarGb5fae462020-03-05 12:43:25 -0700206void DebugPrintf::PreCallRecordCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
207 const VkGraphicsPipelineCreateInfo *pCreateInfos,
208 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
209 void *cgpl_state_data) {
Tony-LunarG00e7b7d2021-06-30 12:59:43 -0600210 if (aborted) return;
Tony-LunarG04717522019-10-17 10:41:17 -0600211 std::vector<safe_VkGraphicsPipelineCreateInfo> new_pipeline_create_infos;
212 create_graphics_pipeline_api_state *cgpl_state = reinterpret_cast<create_graphics_pipeline_api_state *>(cgpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -0700213 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, cgpl_state->pipe_state,
214 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_GRAPHICS, this);
Tony-LunarG04717522019-10-17 10:41:17 -0600215 cgpl_state->printf_create_infos = new_pipeline_create_infos;
216 cgpl_state->pCreateInfos = reinterpret_cast<VkGraphicsPipelineCreateInfo *>(cgpl_state->printf_create_infos.data());
217}
218
Tony-LunarGb5fae462020-03-05 12:43:25 -0700219void DebugPrintf::PreCallRecordCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
220 const VkComputePipelineCreateInfo *pCreateInfos,
221 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
222 void *ccpl_state_data) {
Tony-LunarG00e7b7d2021-06-30 12:59:43 -0600223 if (aborted) return;
Tony-LunarG04717522019-10-17 10:41:17 -0600224 std::vector<safe_VkComputePipelineCreateInfo> new_pipeline_create_infos;
225 auto *ccpl_state = reinterpret_cast<create_compute_pipeline_api_state *>(ccpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -0700226 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, ccpl_state->pipe_state,
227 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_COMPUTE, this);
Tony-LunarG04717522019-10-17 10:41:17 -0600228 ccpl_state->printf_create_infos = new_pipeline_create_infos;
Tony-LunarG9b9dc022020-10-08 13:55:37 -0600229 ccpl_state->pCreateInfos = reinterpret_cast<VkComputePipelineCreateInfo *>(ccpl_state->printf_create_infos.data());
Tony-LunarG04717522019-10-17 10:41:17 -0600230}
231
Tony-LunarGb5fae462020-03-05 12:43:25 -0700232void DebugPrintf::PreCallRecordCreateRayTracingPipelinesNV(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
233 const VkRayTracingPipelineCreateInfoNV *pCreateInfos,
234 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
235 void *crtpl_state_data) {
Tony-LunarG00e7b7d2021-06-30 12:59:43 -0600236 if (aborted) return;
Tony-LunarG04717522019-10-17 10:41:17 -0600237 std::vector<safe_VkRayTracingPipelineCreateInfoCommon> new_pipeline_create_infos;
238 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_api_state *>(crtpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -0700239 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, crtpl_state->pipe_state,
240 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, this);
Tony-LunarG04717522019-10-17 10:41:17 -0600241 crtpl_state->printf_create_infos = new_pipeline_create_infos;
Tony-LunarG9b9dc022020-10-08 13:55:37 -0600242 crtpl_state->pCreateInfos = reinterpret_cast<VkRayTracingPipelineCreateInfoNV *>(crtpl_state->printf_create_infos.data());
Tony-LunarG04717522019-10-17 10:41:17 -0600243}
244
sourav parmarcd5fb182020-07-17 12:58:44 -0700245void DebugPrintf::PreCallRecordCreateRayTracingPipelinesKHR(VkDevice device, VkDeferredOperationKHR deferredOperation,
246 VkPipelineCache pipelineCache, uint32_t count,
Tony-LunarGb5fae462020-03-05 12:43:25 -0700247 const VkRayTracingPipelineCreateInfoKHR *pCreateInfos,
248 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
249 void *crtpl_state_data) {
Tony-LunarG00e7b7d2021-06-30 12:59:43 -0600250 if (aborted) return;
Tony-LunarG04717522019-10-17 10:41:17 -0600251 std::vector<safe_VkRayTracingPipelineCreateInfoCommon> new_pipeline_create_infos;
252 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_khr_api_state *>(crtpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -0700253 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, crtpl_state->pipe_state,
254 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, this);
Tony-LunarG9b9dc022020-10-08 13:55:37 -0600255 crtpl_state->printf_create_infos = new_pipeline_create_infos;
256 crtpl_state->pCreateInfos = reinterpret_cast<VkRayTracingPipelineCreateInfoKHR *>(crtpl_state->printf_create_infos.data());
Tony-LunarG04717522019-10-17 10:41:17 -0600257}
Tony-LunarG04717522019-10-17 10:41:17 -0600258
Tony-LunarGb5fae462020-03-05 12:43:25 -0700259void DebugPrintf::PostCallRecordCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
260 const VkGraphicsPipelineCreateInfo *pCreateInfos,
261 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
262 VkResult result, void *cgpl_state_data) {
Tony-LunarG04717522019-10-17 10:41:17 -0600263 ValidationStateTracker::PostCallRecordCreateGraphicsPipelines(device, pipelineCache, count, pCreateInfos, pAllocator,
264 pPipelines, result, cgpl_state_data);
Tony-LunarG00e7b7d2021-06-30 12:59:43 -0600265 if (aborted) return;
Tony-LunarGc876c6e2020-09-09 15:19:43 -0600266 create_graphics_pipeline_api_state *cgpl_state = reinterpret_cast<create_graphics_pipeline_api_state *>(cgpl_state_data);
267 UtilCopyCreatePipelineFeedbackData(count, pCreateInfos, cgpl_state->printf_create_infos.data());
Tony-LunarGb5fae462020-03-05 12:43:25 -0700268 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_GRAPHICS, this);
Tony-LunarG04717522019-10-17 10:41:17 -0600269}
270
Tony-LunarGb5fae462020-03-05 12:43:25 -0700271void DebugPrintf::PostCallRecordCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
272 const VkComputePipelineCreateInfo *pCreateInfos,
273 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
274 VkResult result, void *ccpl_state_data) {
Tony-LunarG04717522019-10-17 10:41:17 -0600275 ValidationStateTracker::PostCallRecordCreateComputePipelines(device, pipelineCache, count, pCreateInfos, pAllocator, pPipelines,
276 result, ccpl_state_data);
Tony-LunarG00e7b7d2021-06-30 12:59:43 -0600277 if (aborted) return;
Tony-LunarGc876c6e2020-09-09 15:19:43 -0600278 create_compute_pipeline_api_state *ccpl_state = reinterpret_cast<create_compute_pipeline_api_state *>(ccpl_state_data);
279 UtilCopyCreatePipelineFeedbackData(count, pCreateInfos, ccpl_state->printf_create_infos.data());
Tony-LunarGb5fae462020-03-05 12:43:25 -0700280 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_COMPUTE, this);
Tony-LunarG04717522019-10-17 10:41:17 -0600281}
282
Tony-LunarGb5fae462020-03-05 12:43:25 -0700283void DebugPrintf::PostCallRecordCreateRayTracingPipelinesNV(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
284 const VkRayTracingPipelineCreateInfoNV *pCreateInfos,
285 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
286 VkResult result, void *crtpl_state_data) {
Tony-LunarGc876c6e2020-09-09 15:19:43 -0600287 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_khr_api_state *>(crtpl_state_data);
Tony-LunarG04717522019-10-17 10:41:17 -0600288 ValidationStateTracker::PostCallRecordCreateRayTracingPipelinesNV(device, pipelineCache, count, pCreateInfos, pAllocator,
289 pPipelines, result, crtpl_state_data);
Tony-LunarG00e7b7d2021-06-30 12:59:43 -0600290 if (aborted) return;
Tony-LunarG9b9dc022020-10-08 13:55:37 -0600291 UtilCopyCreatePipelineFeedbackData(count, pCreateInfos, crtpl_state->printf_create_infos.data());
Tony-LunarGb5fae462020-03-05 12:43:25 -0700292 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, this);
Tony-LunarG04717522019-10-17 10:41:17 -0600293}
294
Tony-LunarGfb2ab872021-01-13 15:17:15 -0700295void DebugPrintf::PostCallRecordCreateRayTracingPipelinesKHR(VkDevice device, VkDeferredOperationKHR deferredOperation,
296 VkPipelineCache pipelineCache, uint32_t count,
297 const VkRayTracingPipelineCreateInfoKHR *pCreateInfos,
298 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
299 VkResult result, void *crtpl_state_data) {
300 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_khr_api_state *>(crtpl_state_data);
301 ValidationStateTracker::PostCallRecordCreateRayTracingPipelinesKHR(
302 device, deferredOperation, pipelineCache, count, pCreateInfos, pAllocator, pPipelines, result, crtpl_state_data);
Tony-LunarG00e7b7d2021-06-30 12:59:43 -0600303 if (aborted) return;
Tony-LunarGfb2ab872021-01-13 15:17:15 -0700304 UtilCopyCreatePipelineFeedbackData(count, pCreateInfos, crtpl_state->printf_create_infos.data());
305 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, this);
306}
307
Tony-LunarG04717522019-10-17 10:41:17 -0600308// Remove all the shader trackers associated with this destroyed pipeline.
Tony-LunarGb5fae462020-03-05 12:43:25 -0700309void DebugPrintf::PreCallRecordDestroyPipeline(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks *pAllocator) {
Tony-LunarG04717522019-10-17 10:41:17 -0600310 for (auto it = shader_map.begin(); it != shader_map.end();) {
311 if (it->second.pipeline == pipeline) {
312 it = shader_map.erase(it);
313 } else {
314 ++it;
315 }
316 }
317 ValidationStateTracker::PreCallRecordDestroyPipeline(device, pipeline, pAllocator);
318}
319// Call the SPIR-V Optimizer to run the instrumentation pass on the shader.
sfricke-samsung7fac88a2022-01-26 11:44:22 -0800320bool DebugPrintf::InstrumentShader(const VkShaderModuleCreateInfo *pCreateInfo, std::vector<uint32_t> &new_pgm,
Tony-LunarGb5fae462020-03-05 12:43:25 -0700321 uint32_t *unique_shader_id) {
Tony-LunarG04717522019-10-17 10:41:17 -0600322 if (aborted) return false;
323 if (pCreateInfo->pCode[0] != spv::MagicNumber) return false;
324
325 // Load original shader SPIR-V
326 uint32_t num_words = static_cast<uint32_t>(pCreateInfo->codeSize / 4);
327 new_pgm.clear();
328 new_pgm.reserve(num_words);
329 new_pgm.insert(new_pgm.end(), &pCreateInfo->pCode[0], &pCreateInfo->pCode[num_words]);
330
331 // Call the optimizer to instrument the shader.
332 // Use the unique_shader_module_id as a shader ID so we can look up its handle later in the shader_map.
333 // If descriptor indexing is enabled, enable length checks and updated descriptor checks
334 using namespace spvtools;
sfricke-samsung45996a42021-09-16 13:45:27 -0700335 spv_target_env target_env = PickSpirvEnv(api_version, IsExtEnabled(device_extensions.vk_khr_spirv_1_4));
Tony-LunarGf29f77f2020-08-26 15:48:00 -0600336 spvtools::ValidatorOptions val_options;
337 AdjustValidatorOptions(device_extensions, enabled_features, val_options);
338 spvtools::OptimizerOptions opt_options;
339 opt_options.set_run_validator(true);
340 opt_options.set_validator_options(val_options);
Tony-LunarG04717522019-10-17 10:41:17 -0600341 Optimizer optimizer(target_env);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700342 const spvtools::MessageConsumer debug_printf_console_message_consumer =
Tony-LunarG79641702020-07-13 15:43:05 -0600343 [this](spv_message_level_t level, const char *, const spv_position_t &position, const char *message) -> void {
344 switch (level) {
345 case SPV_MSG_FATAL:
346 case SPV_MSG_INTERNAL_ERROR:
347 case SPV_MSG_ERROR:
348 this->LogError(this->device, "UNASSIGNED-Debug-Printf", "Error during shader instrumentation: line %zu: %s",
349 position.index, message);
350 break;
351 default:
352 break;
353 }
354 };
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700355 optimizer.SetMessageConsumer(debug_printf_console_message_consumer);
Tony-LunarG04717522019-10-17 10:41:17 -0600356 optimizer.RegisterPass(CreateInstDebugPrintfPass(desc_set_bind_index, unique_shader_module_id));
Tony-LunarGf29f77f2020-08-26 15:48:00 -0600357 bool pass = optimizer.Run(new_pgm.data(), new_pgm.size(), &new_pgm, opt_options);
Tony-LunarG04717522019-10-17 10:41:17 -0600358 if (!pass) {
Tony-LunarG1dce2392019-10-23 16:49:29 -0600359 ReportSetupProblem(device, "Failure to instrument shader. Proceeding with non-instrumented shader.");
Tony-LunarG04717522019-10-17 10:41:17 -0600360 }
361 *unique_shader_id = unique_shader_module_id++;
362 return pass;
363}
364// Create the instrumented shader data to provide to the driver.
Tony-LunarGb5fae462020-03-05 12:43:25 -0700365void DebugPrintf::PreCallRecordCreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo *pCreateInfo,
366 const VkAllocationCallbacks *pAllocator, VkShaderModule *pShaderModule,
367 void *csm_state_data) {
Tony-LunarG04717522019-10-17 10:41:17 -0600368 create_shader_module_api_state *csm_state = reinterpret_cast<create_shader_module_api_state *>(csm_state_data);
369 bool pass = InstrumentShader(pCreateInfo, csm_state->instrumented_pgm, &csm_state->unique_shader_id);
370 if (pass) {
371 csm_state->instrumented_create_info.pCode = csm_state->instrumented_pgm.data();
sfricke-samsung7fac88a2022-01-26 11:44:22 -0800372 csm_state->instrumented_create_info.codeSize = csm_state->instrumented_pgm.size() * sizeof(uint32_t);
Tony-LunarG04717522019-10-17 10:41:17 -0600373 }
374}
Tony-LunarG04717522019-10-17 10:41:17 -0600375
376vartype vartype_lookup(char intype) {
377 switch (intype) {
378 case 'd':
379 case 'i':
380 return varsigned;
381 break;
382
383 case 'f':
384 case 'F':
385 case 'a':
386 case 'A':
387 case 'e':
388 case 'E':
389 case 'g':
390 case 'G':
391 return varfloat;
392 break;
393
394 case 'u':
395 case 'x':
396 case 'o':
397 default:
398 return varunsigned;
399 break;
400 }
401}
402
Tony-LunarGa19e31e2020-03-30 13:30:29 -0600403std::vector<DPFSubstring> DebugPrintf::ParseFormatString(const std::string format_string) {
404 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 -0700405 std::vector<DPFSubstring> parsed_strings;
Tony-LunarG04717522019-10-17 10:41:17 -0600406 size_t pos = 0;
407 size_t begin = 0;
408 size_t percent = 0;
409
410 while (begin < format_string.length()) {
Tony-LunarGb5fae462020-03-05 12:43:25 -0700411 DPFSubstring substring;
Tony-LunarG04717522019-10-17 10:41:17 -0600412
413 // Find a percent sign
414 pos = percent = format_string.find_first_of('%', pos);
415 if (pos == std::string::npos) {
416 // End of the format string Push the rest of the characters
417 substring.string = format_string.substr(begin, format_string.length());
418 substring.needs_value = false;
419 parsed_strings.push_back(substring);
420 break;
421 }
422 pos++;
423 if (format_string[pos] == '%') {
424 pos++;
425 continue; // %% - skip it
426 }
427 // Find the type of the value
428 pos = format_string.find_first_of(types, pos);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700429 if (pos == format_string.npos) {
Tony-LunarG04717522019-10-17 10:41:17 -0600430 // This really shouldn't happen with a legal value string
431 pos = format_string.length();
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700432 } else {
Tony-LunarG04717522019-10-17 10:41:17 -0600433 char tempstring[32];
434 int count = 0;
435 std::string specifier = {};
436
437 if (format_string[pos] == 'v') {
438 // Vector must be of size 2, 3, or 4
439 // and format %v<size><type>
440 specifier = format_string.substr(percent, pos - percent);
441 count = atoi(&format_string[pos + 1]);
442 pos += 2;
443
444 // skip v<count>, handle long
445 specifier.push_back(format_string[pos]);
446 if (format_string[pos + 1] == 'l') {
447 specifier.push_back('l');
448 pos++;
449 }
450
451 // Take the preceding characters, and the percent through the type
452 substring.string = format_string.substr(begin, percent - begin);
453 substring.string += specifier;
454 substring.needs_value = true;
455 substring.type = vartype_lookup(specifier.back());
456 parsed_strings.push_back(substring);
457
458 // Continue with a comma separated list
459 sprintf(tempstring, ", %s", specifier.c_str());
460 substring.string = tempstring;
461 for (int i = 0; i < (count - 1); i++) {
462 parsed_strings.push_back(substring);
463 }
464 } else {
465 // Single non-vector value
466 if (format_string[pos + 1] == 'l') pos++; // Save long size
467 substring.string = format_string.substr(begin, pos - begin + 1);
468 substring.needs_value = true;
469 substring.type = vartype_lookup(format_string[pos]);
470 parsed_strings.push_back(substring);
471 }
472 begin = pos + 1;
473 }
474 }
475 return parsed_strings;
476}
477
sfricke-samsung7fac88a2022-01-26 11:44:22 -0800478std::string DebugPrintf::FindFormatString(std::vector<uint32_t> pgm, uint32_t string_id) {
Tony-LunarG04717522019-10-17 10:41:17 -0600479 std::string format_string;
sfricke-samsungef15e482022-01-26 11:32:49 -0800480 SHADER_MODULE_STATE module_state(pgm);
481 if (module_state.words.size() > 0) {
482 for (const auto &insn : module_state) {
Tony-LunarG04717522019-10-17 10:41:17 -0600483 if (insn.opcode() == spv::OpString) {
484 uint32_t offset = insn.offset();
485 if (pgm[offset + 1] == string_id) {
486 format_string = reinterpret_cast<char *>(&pgm[offset + 2]);
487 break;
488 }
489 }
490 }
491 }
492
493 return format_string;
494}
495
Corentin Wallez171ac5e2020-03-31 16:09:05 +0200496// GCC and clang don't like using variables as format strings in sprintf.
497// #pragma GCC is recognized by both compilers
498#if defined(__GNUC__) || defined(__clang__)
Tony-LunarG04717522019-10-17 10:41:17 -0600499#pragma GCC diagnostic push
500#pragma GCC diagnostic ignored "-Wformat-security"
501#endif
502
Tony-LunarGb5fae462020-03-05 12:43:25 -0700503void snprintf_with_malloc(std::stringstream &shader_message, DPFSubstring substring, size_t needed, void *values) {
Tony-LunarG04717522019-10-17 10:41:17 -0600504 char *buffer = static_cast<char *>(malloc((needed + 1) * sizeof(char))); // Add 1 for terminator
505 if (substring.longval) {
506 snprintf(buffer, needed, substring.string.c_str(), substring.longval);
507 } else if (!substring.needs_value) {
508 snprintf(buffer, needed, substring.string.c_str());
509 } else {
510 switch (substring.type) {
511 case varunsigned:
512 needed = snprintf(buffer, needed, substring.string.c_str(), *static_cast<uint32_t *>(values) - 1);
513 break;
514
515 case varsigned:
516 needed = snprintf(buffer, needed, substring.string.c_str(), *static_cast<int32_t *>(values) - 1);
517 break;
518
519 case varfloat:
520 needed = snprintf(buffer, needed, substring.string.c_str(), *static_cast<float *>(values) - 1);
521 break;
522 }
523 }
524 shader_message << buffer;
525 free(buffer);
526}
527
Tony-LunarG7de10e82020-11-24 11:31:55 -0700528void DebugPrintf::AnalyzeAndGenerateMessages(VkCommandBuffer command_buffer, VkQueue queue, DPFBufferInfo &buffer_info,
Tony-LunarGb5fae462020-03-05 12:43:25 -0700529 uint32_t operation_index, uint32_t *const debug_output_buffer) {
Tony-LunarG04717522019-10-17 10:41:17 -0600530 // Word Content
531 // 0 Size of output record, including this word
532 // 1 Shader ID
533 // 2 Instruction Position
534 // 3 Stage Ordinal
535 // 4 Stage - specific Info Word 0
536 // 5 Stage - specific Info Word 1
537 // 6 Stage - specific Info Word 2
538 // 7 Printf Format String Id
539 // 8 Printf Values Word 0 (optional)
540 // 9 Printf Values Word 1 (optional)
Tony-LunarG12a7ec32019-11-01 13:00:05 -0600541 uint32_t expect = debug_output_buffer[0];
542 if (!expect) return;
Tony-LunarG04717522019-10-17 10:41:17 -0600543
Tony-LunarG12a7ec32019-11-01 13:00:05 -0600544 uint32_t index = 1;
Tony-LunarG04717522019-10-17 10:41:17 -0600545 while (debug_output_buffer[index]) {
Tony-LunarG04717522019-10-17 10:41:17 -0600546 std::stringstream shader_message;
Tony-LunarG04717522019-10-17 10:41:17 -0600547 VkShaderModule shader_module_handle = VK_NULL_HANDLE;
548 VkPipeline pipeline_handle = VK_NULL_HANDLE;
sfricke-samsung7fac88a2022-01-26 11:44:22 -0800549 std::vector<uint32_t> pgm;
Tony-LunarG04717522019-10-17 10:41:17 -0600550
Tony-LunarGb5fae462020-03-05 12:43:25 -0700551 DPFOutputRecord *debug_record = reinterpret_cast<DPFOutputRecord *>(&debug_output_buffer[index]);
Tony-LunarG04717522019-10-17 10:41:17 -0600552 // Lookup the VkShaderModule handle and SPIR-V code used to create the shader, using the unique shader ID value returned
553 // by the instrumented shader.
554 auto it = shader_map.find(debug_record->shader_id);
555 if (it != shader_map.end()) {
556 shader_module_handle = it->second.shader_module;
557 pipeline_handle = it->second.pipeline;
558 pgm = it->second.pgm;
559 }
560 // Search through the shader source for the printf format string for this invocation
561 auto format_string = FindFormatString(pgm, debug_record->format_string_id);
562 // Break the format string into strings with 1 or 0 value
563 auto format_substrings = ParseFormatString(format_string);
564 void *values = static_cast<void *>(&debug_record->values);
565 const uint32_t static_size = 1024;
566 // Sprintf each format substring into a temporary string then add that to the message
567 for (auto &substring : format_substrings) {
568 char temp_string[static_size];
569 size_t needed = 0;
Tony-LunarGef469c92021-05-14 06:33:22 -0600570 std::vector<std::string> format_strings = { "%ul", "%lu", "%lx" };
571 size_t ul_pos = 0;
572 bool print_hex = true;
573 for (auto ul_string : format_strings) {
574 ul_pos = substring.string.find(ul_string);
575 if (ul_pos != std::string::npos) {
576 if (ul_string == "%lu") print_hex = false;
577 break;
578 }
579 }
Tony-LunarG04717522019-10-17 10:41:17 -0600580 if (ul_pos != std::string::npos) {
581 // Unsigned 64 bit value
582 substring.longval = *static_cast<uint64_t *>(values);
583 values = static_cast<uint64_t *>(values) + 1;
Tony-LunarGef469c92021-05-14 06:33:22 -0600584 if (print_hex) {
585 substring.string.replace(ul_pos + 1, 2, PRIx64);
586 } else {
587 substring.string.replace(ul_pos + 1, 2, PRIu64);
588 }
Tony-LunarG04717522019-10-17 10:41:17 -0600589 needed = snprintf(temp_string, static_size, substring.string.c_str(), substring.longval);
590 } else {
591 if (substring.needs_value) {
592 switch (substring.type) {
593 case varunsigned:
594 needed = snprintf(temp_string, static_size, substring.string.c_str(), *static_cast<uint32_t *>(values));
595 break;
596
597 case varsigned:
598 needed = snprintf(temp_string, static_size, substring.string.c_str(), *static_cast<int32_t *>(values));
599 break;
600
601 case varfloat:
602 needed = snprintf(temp_string, static_size, substring.string.c_str(), *static_cast<float *>(values));
603 break;
604 }
605 values = static_cast<uint32_t *>(values) + 1;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700606 } else {
Tony-LunarG04717522019-10-17 10:41:17 -0600607 needed = snprintf(temp_string, static_size, substring.string.c_str());
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700608 }
Tony-LunarG04717522019-10-17 10:41:17 -0600609 }
610
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700611 if (needed < static_size) {
Tony-LunarG04717522019-10-17 10:41:17 -0600612 shader_message << temp_string;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700613 } else {
Tony-LunarG04717522019-10-17 10:41:17 -0600614 // Static buffer not big enough for message, use malloc to get enough
615 snprintf_with_malloc(shader_message, substring, needed, values);
616 }
617 }
Tony-LunarG43416b42019-10-31 16:47:24 -0600618
619 if (verbose) {
620 std::string stage_message;
621 std::string common_message;
622 std::string filename_message;
623 std::string source_message;
Tony-LunarGb5fae462020-03-05 12:43:25 -0700624 UtilGenerateStageMessage(&debug_output_buffer[index], stage_message);
625 UtilGenerateCommonMessage(report_data, command_buffer, &debug_output_buffer[index], shader_module_handle,
Tony-LunarG7de10e82020-11-24 11:31:55 -0700626 pipeline_handle, buffer_info.pipeline_bind_point, operation_index, common_message);
Tony-LunarGb5fae462020-03-05 12:43:25 -0700627 UtilGenerateSourceMessages(pgm, &debug_output_buffer[index], true, filename_message, source_message);
Tony-LunarG43416b42019-10-31 16:47:24 -0600628 if (use_stdout) {
Tony-LunarG5af54eb2020-03-27 15:32:51 -0600629 std::cout << "UNASSIGNED-DEBUG-PRINTF " << common_message.c_str() << " " << stage_message.c_str() << " "
Tony-LunarGb5fae462020-03-05 12:43:25 -0700630 << shader_message.str().c_str() << " " << filename_message.c_str() << " " << source_message.c_str();
Tony-LunarG43416b42019-10-31 16:47:24 -0600631 } else {
Tony-LunarG5af54eb2020-03-27 15:32:51 -0600632 LogInfo(queue, "UNASSIGNED-DEBUG-PRINTF", "%s %s %s %s%s", common_message.c_str(), stage_message.c_str(),
633 shader_message.str().c_str(), filename_message.c_str(), source_message.c_str());
Tony-LunarG43416b42019-10-31 16:47:24 -0600634 }
635 } else {
Tony-LunarG5af54eb2020-03-27 15:32:51 -0600636 if (use_stdout) {
Tony-LunarG43416b42019-10-31 16:47:24 -0600637 std::cout << shader_message.str();
Tony-LunarG5af54eb2020-03-27 15:32:51 -0600638 } else {
639 // Don't let LogInfo process any '%'s in the string
640 LogInfo(device, "UNASSIGNED-DEBUG-PRINTF", "%s", shader_message.str().c_str());
641 }
Tony-LunarG43416b42019-10-31 16:47:24 -0600642 }
Tony-LunarG04717522019-10-17 10:41:17 -0600643 index += debug_record->size;
644 }
Tony-LunarG12a7ec32019-11-01 13:00:05 -0600645 if ((index - 1) != expect) {
Tony-LunarG5af54eb2020-03-27 15:32:51 -0600646 LogWarning(device, "UNASSIGNED-DEBUG-PRINTF",
647 "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 -0600648 }
Tony-LunarG04717522019-10-17 10:41:17 -0600649 memset(debug_output_buffer, 0, 4 * (debug_output_buffer[0] + 1));
650}
Tony-LunarG43416b42019-10-31 16:47:24 -0600651
Tony-LunarG04717522019-10-17 10:41:17 -0600652#if defined(__GNUC__)
653#pragma GCC diagnostic pop
654#endif
655
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700656bool DebugPrintf::CommandBufferNeedsProcessing(VkCommandBuffer command_buffer) {
657 bool buffers_present = false;
Jeremy Gebben37c5c5d2022-03-21 07:16:03 -0600658 auto cb_node = Get<debug_printf_state::CommandBuffer>(command_buffer);
Jeremy Gebben9f537102021-10-05 16:37:12 -0600659 if (GetBufferInfo(cb_node.get()).size()) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700660 buffers_present = true;
661 }
John Zulauf79f06582021-02-27 18:38:39 -0700662 for (const auto *secondaryCmdBuffer : cb_node->linkedCommandBuffers) {
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600663 if (GetBufferInfo(secondaryCmdBuffer).size()) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700664 buffers_present = true;
665 }
666 }
667 return buffers_present;
668}
669
670void DebugPrintf::ProcessCommandBuffer(VkQueue queue, VkCommandBuffer command_buffer) {
Jeremy Gebben37c5c5d2022-03-21 07:16:03 -0600671 auto cb_node = Get<debug_printf_state::CommandBuffer>(command_buffer);
Jeremy Gebben9f537102021-10-05 16:37:12 -0600672 UtilProcessInstrumentationBuffer(queue, cb_node.get(), this);
John Zulauf79f06582021-02-27 18:38:39 -0700673 for (auto *secondary_cmd_buffer : cb_node->linkedCommandBuffers) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700674 UtilProcessInstrumentationBuffer(queue, secondary_cmd_buffer, this);
675 }
676}
677
Tony-LunarG04717522019-10-17 10:41:17 -0600678// Issue a memory barrier to make GPU-written data available to host.
679// Wait for the queue to complete execution.
680// Check the debug buffers for all the command buffers that were submitted.
Tony-LunarGb5fae462020-03-05 12:43:25 -0700681void DebugPrintf::PostCallRecordQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence,
682 VkResult result) {
Tony-LunarG04717522019-10-17 10:41:17 -0600683 ValidationStateTracker::PostCallRecordQueueSubmit(queue, submitCount, pSubmits, fence, result);
684
Mark Lobodzinski09379db2020-05-07 08:22:01 -0600685 if (aborted || (result != VK_SUCCESS)) return;
Tony-LunarG04717522019-10-17 10:41:17 -0600686 bool buffers_present = false;
687 // Don't QueueWaitIdle if there's nothing to process
688 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
689 const VkSubmitInfo *submit = &pSubmits[submit_idx];
690 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700691 buffers_present |= CommandBufferNeedsProcessing(submit->pCommandBuffers[i]);
Tony-LunarG04717522019-10-17 10:41:17 -0600692 }
693 }
694 if (!buffers_present) return;
695
Tony-LunarGb5fae462020-03-05 12:43:25 -0700696 UtilSubmitBarrier(queue, this);
Tony-LunarG04717522019-10-17 10:41:17 -0600697
698 DispatchQueueWaitIdle(queue);
699
700 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
701 const VkSubmitInfo *submit = &pSubmits[submit_idx];
702 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700703 ProcessCommandBuffer(queue, submit->pCommandBuffers[i]);
704 }
705 }
706}
707
Tony-LunarG26fe2842021-11-16 14:07:59 -0700708void DebugPrintf::RecordQueueSubmit2(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2 *pSubmits, VkFence fence,
709 VkResult result) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700710 if (aborted || (result != VK_SUCCESS)) return;
711 bool buffers_present = false;
712 // Don't QueueWaitIdle if there's nothing to process
713 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
714 const auto *submit = &pSubmits[submit_idx];
715 for (uint32_t i = 0; i < submit->commandBufferInfoCount; i++) {
716 buffers_present |= CommandBufferNeedsProcessing(submit->pCommandBufferInfos[i].commandBuffer);
717 }
718 }
719 if (!buffers_present) return;
720
721 UtilSubmitBarrier(queue, this);
722
723 DispatchQueueWaitIdle(queue);
724
725 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
Tony-LunarG26fe2842021-11-16 14:07:59 -0700726 const VkSubmitInfo2 *submit = &pSubmits[submit_idx];
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700727 for (uint32_t i = 0; i < submit->commandBufferInfoCount; i++) {
728 ProcessCommandBuffer(queue, submit->pCommandBufferInfos[i].commandBuffer);
Tony-LunarG04717522019-10-17 10:41:17 -0600729 }
730 }
731}
732
Tony-LunarG26fe2842021-11-16 14:07:59 -0700733void DebugPrintf::PostCallRecordQueueSubmit2KHR(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2KHR *pSubmits,
734 VkFence fence, VkResult result) {
735 ValidationStateTracker::PostCallRecordQueueSubmit2KHR(queue, submitCount, pSubmits, fence, result);
736 RecordQueueSubmit2(queue, submitCount, pSubmits, fence, result);
737}
738
739void DebugPrintf::PostCallRecordQueueSubmit2(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2 *pSubmits, VkFence fence,
740 VkResult result) {
741 ValidationStateTracker::PostCallRecordQueueSubmit2(queue, submitCount, pSubmits, fence, result);
742 RecordQueueSubmit2(queue, submitCount, pSubmits, fence, result);
743}
744
Tony-LunarGb5fae462020-03-05 12:43:25 -0700745void DebugPrintf::PreCallRecordCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
746 uint32_t firstVertex, uint32_t firstInstance) {
747 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
Tony-LunarG04717522019-10-17 10:41:17 -0600748}
749
Tony-LunarG745150c2021-07-02 15:07:31 -0600750void DebugPrintf::PreCallRecordCmdDrawMultiEXT(VkCommandBuffer commandBuffer, uint32_t drawCount,
751 const VkMultiDrawInfoEXT *pVertexInfo, uint32_t instanceCount,
752 uint32_t firstInstance, uint32_t stride) {
753 for(uint32_t i = 0; i < drawCount; i++) {
754 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
755 }
756}
757
Tony-LunarGb5fae462020-03-05 12:43:25 -0700758void DebugPrintf::PreCallRecordCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount,
759 uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) {
760 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
Tony-LunarG04717522019-10-17 10:41:17 -0600761}
762
Tony-LunarG745150c2021-07-02 15:07:31 -0600763void DebugPrintf::PreCallRecordCmdDrawMultiIndexedEXT(VkCommandBuffer commandBuffer, uint32_t drawCount,
764 const VkMultiDrawIndexedInfoEXT *pIndexInfo, uint32_t instanceCount,
765 uint32_t firstInstance, uint32_t stride, const int32_t *pVertexOffset) {
766 for (uint32_t i = 0; i < drawCount; i++) {
767 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
768 }
769}
770
Tony-LunarGb5fae462020-03-05 12:43:25 -0700771void DebugPrintf::PreCallRecordCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count,
772 uint32_t stride) {
773 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
Tony-LunarG04717522019-10-17 10:41:17 -0600774}
775
Tony-LunarGb5fae462020-03-05 12:43:25 -0700776void DebugPrintf::PreCallRecordCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
777 uint32_t count, uint32_t stride) {
778 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
Tony-LunarG04717522019-10-17 10:41:17 -0600779}
780
Tony-LunarGb5fae462020-03-05 12:43:25 -0700781void DebugPrintf::PreCallRecordCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
782 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE);
Tony-LunarG04717522019-10-17 10:41:17 -0600783}
784
Tony-LunarGb5fae462020-03-05 12:43:25 -0700785void DebugPrintf::PreCallRecordCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
786 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE);
Tony-LunarG04717522019-10-17 10:41:17 -0600787}
788
Tony-LunarGd13f9b52020-09-08 15:45:45 -0600789void DebugPrintf::PreCallRecordCmdDispatchBase(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY,
790 uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY,
791 uint32_t groupCountZ) {
792 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE);
793}
794
Tony-LunarG52c8c602020-09-10 16:29:56 -0600795void DebugPrintf::PreCallRecordCmdDispatchBaseKHR(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY,
796 uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY,
797 uint32_t groupCountZ) {
798 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE);
799}
800
Tony-LunarG2fb8ff02020-06-11 12:45:07 -0600801void DebugPrintf::PreCallRecordCmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
802 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
803 uint32_t stride) {
804 ValidationStateTracker::PreCallRecordCmdDrawIndirectCountKHR(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
805 maxDrawCount, stride);
806 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
807}
808
809void DebugPrintf::PreCallRecordCmdDrawIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
810 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
811 uint32_t stride) {
812 ValidationStateTracker::PreCallRecordCmdDrawIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
813 maxDrawCount, stride);
814 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
815}
816
817void DebugPrintf::PreCallRecordCmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
818 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
819 uint32_t maxDrawCount, uint32_t stride) {
820 ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirectCountKHR(commandBuffer, buffer, offset, countBuffer,
821 countBufferOffset, maxDrawCount, stride);
822 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
823}
824
825void DebugPrintf::PreCallRecordCmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
826 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
827 uint32_t maxDrawCount, uint32_t stride) {
828 ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
829 maxDrawCount, stride);
830 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
831}
832
Tony-LunarG54176fb2020-12-02 10:47:22 -0700833void DebugPrintf::PreCallRecordCmdDrawIndirectByteCountEXT(VkCommandBuffer commandBuffer, uint32_t instanceCount,
834 uint32_t firstInstance, VkBuffer counterBuffer,
835 VkDeviceSize counterBufferOffset, uint32_t counterOffset,
836 uint32_t vertexStride) {
837 ValidationStateTracker::PreCallRecordCmdDrawIndirectByteCountEXT(commandBuffer, instanceCount, firstInstance, counterBuffer,
838 counterBufferOffset, counterOffset, vertexStride);
839 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
840}
841
Tony-LunarG2fb8ff02020-06-11 12:45:07 -0600842void DebugPrintf::PreCallRecordCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask) {
843 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksNV(commandBuffer, taskCount, firstTask);
844 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
845}
846
847void DebugPrintf::PreCallRecordCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
848 uint32_t drawCount, uint32_t stride) {
849 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksIndirectNV(commandBuffer, buffer, offset, drawCount, stride);
850 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
851}
852
853void DebugPrintf::PreCallRecordCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
854 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
855 uint32_t maxDrawCount, uint32_t stride) {
856 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksIndirectCountNV(commandBuffer, buffer, offset, countBuffer,
857 countBufferOffset, maxDrawCount, stride);
858 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
859}
860
Tony-LunarGb5fae462020-03-05 12:43:25 -0700861void DebugPrintf::PreCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
862 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
863 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
864 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
865 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
866 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
867 uint32_t width, uint32_t height, uint32_t depth) {
868 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV);
869}
870
871void DebugPrintf::PostCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
Tony-LunarG04717522019-10-17 10:41:17 -0600872 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
873 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
874 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
875 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
876 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
877 uint32_t width, uint32_t height, uint32_t depth) {
Jeremy Gebben37c5c5d2022-03-21 07:16:03 -0600878 auto cb_state = Get<debug_printf_state::CommandBuffer>(commandBuffer);
Tony-LunarG04717522019-10-17 10:41:17 -0600879 cb_state->hasTraceRaysCmd = true;
880}
881
Tony-LunarGb5fae462020-03-05 12:43:25 -0700882void DebugPrintf::PreCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -0700883 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
884 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
885 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
886 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable, uint32_t width,
Tony-LunarGb5fae462020-03-05 12:43:25 -0700887 uint32_t height, uint32_t depth) {
888 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR);
Tony-LunarG1dce2392019-10-23 16:49:29 -0600889}
890
Tony-LunarGb5fae462020-03-05 12:43:25 -0700891void DebugPrintf::PostCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -0700892 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
893 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
894 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
895 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable, uint32_t width,
Tony-LunarGb5fae462020-03-05 12:43:25 -0700896 uint32_t height, uint32_t depth) {
Jeremy Gebben37c5c5d2022-03-21 07:16:03 -0600897 auto cb_state = Get<debug_printf_state::CommandBuffer>(commandBuffer);
Tony-LunarG1dce2392019-10-23 16:49:29 -0600898 cb_state->hasTraceRaysCmd = true;
899}
900
Tony-LunarGb5fae462020-03-05 12:43:25 -0700901void DebugPrintf::PreCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -0700902 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
903 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
904 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
905 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable,
Shannon McPherson54e1f892020-11-27 11:04:19 -0700906 VkDeviceAddress indirectDeviceAddress) {
Tony-LunarGb5fae462020-03-05 12:43:25 -0700907 AllocateDebugPrintfResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR);
Tony-LunarG1dce2392019-10-23 16:49:29 -0600908}
909
Tony-LunarGb5fae462020-03-05 12:43:25 -0700910void DebugPrintf::PostCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -0700911 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
912 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
913 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
914 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable,
Shannon McPherson54e1f892020-11-27 11:04:19 -0700915 VkDeviceAddress indirectDeviceAddress) {
Jeremy Gebben37c5c5d2022-03-21 07:16:03 -0600916 auto cb_state = Get<debug_printf_state::CommandBuffer>(commandBuffer);
Tony-LunarG1dce2392019-10-23 16:49:29 -0600917 cb_state->hasTraceRaysCmd = true;
918}
919
Tony-LunarGb5fae462020-03-05 12:43:25 -0700920void DebugPrintf::AllocateDebugPrintfResources(const VkCommandBuffer cmd_buffer, const VkPipelineBindPoint bind_point) {
Tony-LunarG04717522019-10-17 10:41:17 -0600921 if (bind_point != VK_PIPELINE_BIND_POINT_GRAPHICS && bind_point != VK_PIPELINE_BIND_POINT_COMPUTE &&
922 bind_point != VK_PIPELINE_BIND_POINT_RAY_TRACING_NV) {
923 return;
924 }
925 VkResult result;
926
927 if (aborted) return;
928
929 std::vector<VkDescriptorSet> desc_sets;
930 VkDescriptorPool desc_pool = VK_NULL_HANDLE;
Tony-LunarG1dce2392019-10-23 16:49:29 -0600931 result = desc_set_manager->GetDescriptorSets(1, &desc_pool, debug_desc_layout, &desc_sets);
Tony-LunarG04717522019-10-17 10:41:17 -0600932 assert(result == VK_SUCCESS);
933 if (result != VK_SUCCESS) {
Tony-LunarG1dce2392019-10-23 16:49:29 -0600934 ReportSetupProblem(device, "Unable to allocate descriptor sets. Device could become unstable.");
Tony-LunarG04717522019-10-17 10:41:17 -0600935 aborted = true;
936 return;
937 }
938
939 VkDescriptorBufferInfo output_desc_buffer_info = {};
940 output_desc_buffer_info.range = output_buffer_size;
941
Jeremy Gebben37c5c5d2022-03-21 07:16:03 -0600942 auto cb_node = Get<debug_printf_state::CommandBuffer>(cmd_buffer);
Tony-LunarG04717522019-10-17 10:41:17 -0600943 if (!cb_node) {
Tony-LunarG1dce2392019-10-23 16:49:29 -0600944 ReportSetupProblem(device, "Unrecognized command buffer");
Tony-LunarG04717522019-10-17 10:41:17 -0600945 aborted = true;
946 return;
947 }
948
949 // Allocate memory for the output block that the gpu will use to return values for printf
Tony-LunarGb5fae462020-03-05 12:43:25 -0700950 DPFDeviceMemoryBlock output_block = {};
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700951 VkBufferCreateInfo buffer_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
952 buffer_info.size = output_buffer_size;
953 buffer_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
954 VmaAllocationCreateInfo alloc_info = {};
955 alloc_info.usage = VMA_MEMORY_USAGE_GPU_TO_CPU;
956 result = vmaCreateBuffer(vmaAllocator, &buffer_info, &alloc_info, &output_block.buffer, &output_block.allocation, nullptr);
Tony-LunarG04717522019-10-17 10:41:17 -0600957 if (result != VK_SUCCESS) {
Tony-LunarG1dce2392019-10-23 16:49:29 -0600958 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
Tony-LunarG04717522019-10-17 10:41:17 -0600959 aborted = true;
960 return;
961 }
962
963 // Clear the output block to zeros so that only printf values from the gpu will be present
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700964 uint32_t *data;
965 result = vmaMapMemory(vmaAllocator, output_block.allocation, reinterpret_cast<void **>(&data));
Tony-LunarG04717522019-10-17 10:41:17 -0600966 if (result == VK_SUCCESS) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700967 memset(data, 0, output_buffer_size);
Tony-LunarG04717522019-10-17 10:41:17 -0600968 vmaUnmapMemory(vmaAllocator, output_block.allocation);
969 }
970
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600971 auto desc_writes = LvlInitStruct<VkWriteDescriptorSet>();
Tony-LunarG04717522019-10-17 10:41:17 -0600972 const uint32_t desc_count = 1;
973
974 // Write the descriptor
975 output_desc_buffer_info.buffer = output_block.buffer;
976 output_desc_buffer_info.offset = 0;
977
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600978 desc_writes.descriptorCount = 1;
979 desc_writes.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
980 desc_writes.pBufferInfo = &output_desc_buffer_info;
981 desc_writes.dstSet = desc_sets[0];
982 desc_writes.dstBinding = 3;
983 DispatchUpdateDescriptorSets(device, desc_count, &desc_writes, 0, NULL);
Tony-LunarG04717522019-10-17 10:41:17 -0600984
locke-lunargb8d7a7a2020-10-25 16:01:52 -0600985 const auto lv_bind_point = ConvertToLvlBindPoint(bind_point);
986 const auto *pipeline_state = cb_node->lastBound[lv_bind_point].pipeline_state;
987 if (pipeline_state) {
988 if (pipeline_state->pipeline_layout->set_layouts.size() <= desc_set_bind_index) {
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -0600989 DispatchCmdBindDescriptorSets(cmd_buffer, bind_point, pipeline_state->pipeline_layout->layout(), desc_set_bind_index, 1,
Tony-LunarG04717522019-10-17 10:41:17 -0600990 desc_sets.data(), 0, nullptr);
991 }
992 // Record buffer and memory info in CB state tracking
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600993 cb_node->buffer_infos.emplace_back(output_block, desc_sets[0], desc_pool, bind_point);
Tony-LunarG04717522019-10-17 10:41:17 -0600994 } else {
Tony-LunarG1dce2392019-10-23 16:49:29 -0600995 ReportSetupProblem(device, "Unable to find pipeline state");
Tony-LunarG04717522019-10-17 10:41:17 -0600996 vmaDestroyBuffer(vmaAllocator, output_block.buffer, output_block.allocation);
997 aborted = true;
998 return;
999 }
1000}
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06001001
1002std::shared_ptr<CMD_BUFFER_STATE> DebugPrintf::CreateCmdBufferState(VkCommandBuffer cb,
1003 const VkCommandBufferAllocateInfo *pCreateInfo,
Jeremy Gebbencd7fa282021-10-27 10:25:32 -06001004 const COMMAND_POOL_STATE *pool) {
Jeremy Gebben37c5c5d2022-03-21 07:16:03 -06001005 return std::static_pointer_cast<CMD_BUFFER_STATE>(
1006 std::make_shared<debug_printf_state::CommandBuffer>(this, cb, pCreateInfo, pool));
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06001007}
1008
Jeremy Gebben37c5c5d2022-03-21 07:16:03 -06001009debug_printf_state::CommandBuffer::CommandBuffer(DebugPrintf *dp, VkCommandBuffer cb,
Jeremy Gebbencd7fa282021-10-27 10:25:32 -06001010 const VkCommandBufferAllocateInfo *pCreateInfo, const COMMAND_POOL_STATE *pool)
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06001011 : CMD_BUFFER_STATE(dp, cb, pCreateInfo, pool) {}
1012
Jeremy Gebben37c5c5d2022-03-21 07:16:03 -06001013void debug_printf_state::CommandBuffer::Reset() {
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06001014 CMD_BUFFER_STATE::Reset();
1015 auto debug_printf = static_cast<DebugPrintf *>(dev_data);
1016 // Free the device memory and descriptor set(s) associated with a command buffer.
1017 if (debug_printf->aborted) {
1018 return;
1019 }
1020 for (auto &buffer_info : buffer_infos) {
1021 debug_printf->DestroyBuffer(buffer_info);
1022 }
1023 buffer_infos.clear();
1024}