diff --git a/layers/VkLayer_khronos_validation.json.in b/layers/VkLayer_khronos_validation.json.in index 721bc0653b4..7fedd094789 100644 --- a/layers/VkLayer_khronos_validation.json.in +++ b/layers/VkLayer_khronos_validation.json.in @@ -1301,6 +1301,26 @@ } ] } + }, + { + "key": "gpuav_debug_print_instrumentation_info", + "label": "Print instrument info", + "description": "Prints verbose information about the instrumentation of the SPIR-V", + "type": "BOOL", + "default": false, + "platforms": [ + "WINDOWS", + "LINUX" + ], + "dependence": { + "mode": "ALL", + "settings": [ + { + "key": "validate_gpu_based", + "value": "GPU_BASED_GPU_ASSISTED" + } + ] + } } ] } diff --git a/layers/gpu/core/gpu_settings.h b/layers/gpu/core/gpu_settings.h index 99bf9b29c5a..6682b5ed3fd 100644 --- a/layers/gpu/core/gpu_settings.h +++ b/layers/gpu/core/gpu_settings.h @@ -41,6 +41,7 @@ struct GpuAVSettings { bool debug_validate_instrumented_shaders = false; bool debug_dump_instrumented_shaders = false; uint32_t debug_max_instrumented_count = 0; // zero is same as "unlimited" + bool debug_print_instrumentation_info = false; bool IsShaderInstrumentationEnabled() const { return validate_descriptors || validate_bda || validate_ray_query; } // Also disables shader caching and select shader instrumentation diff --git a/layers/gpu/instrumentation/gpuav_instrumentation.cpp b/layers/gpu/instrumentation/gpuav_instrumentation.cpp index 42e0bd60ed0..71a529a7c37 100644 --- a/layers/gpu/instrumentation/gpuav_instrumentation.cpp +++ b/layers/gpu/instrumentation/gpuav_instrumentation.cpp @@ -79,7 +79,8 @@ bool Validator::InstrumentShader(const vvl::span &input, uint32_ spv_target_env target_env = PickSpirvEnv(api_version, IsExtEnabled(device_extensions.vk_khr_spirv_1_4)); // Use the unique_shader_id as a shader ID so we can look up its handle later in the shader_map. - spirv::Module module(binaries[0], unique_shader_id, desc_set_bind_index_, gpuav_settings.debug_max_instrumented_count); + spirv::Module module(binaries[0], unique_shader_id, desc_set_bind_index_, gpuav_settings.debug_print_instrumentation_info, + gpuav_settings.debug_max_instrumented_count); // If descriptor indexing is enabled, enable length checks and updated descriptor checks if (gpuav_settings.validate_descriptors) { diff --git a/layers/gpu/spirv/module.cpp b/layers/gpu/spirv/module.cpp index 071294bf9ed..4b43a32b4d4 100644 --- a/layers/gpu/spirv/module.cpp +++ b/layers/gpu/spirv/module.cpp @@ -24,12 +24,13 @@ namespace gpuav { namespace spirv { -Module::Module(std::vector words, uint32_t shader_id, uint32_t output_buffer_descriptor_set, +Module::Module(std::vector words, uint32_t shader_id, uint32_t output_buffer_descriptor_set, bool print_info, uint32_t max_instrumented_count) : type_manager_(*this), max_instrumented_count_(max_instrumented_count), shader_id_(shader_id), - output_buffer_descriptor_set_(output_buffer_descriptor_set) { + output_buffer_descriptor_set_(output_buffer_descriptor_set), + print_info_(print_info) { uint32_t instruction_count = 0; std::vector::const_iterator it = words.cbegin(); header_.magic_number = *it++; @@ -227,16 +228,25 @@ void Module::AddExtension(const char* extension) { void Module::RunPassBindlessDescriptor() { BindlessDescriptorPass pass(*this); pass.Run(); + if (print_info_) { + printf("BindlessDescriptorPass\n\tinstrumentation count: %u\n", pass.GetInstrumentedCount()); + } } void Module::RunPassBufferDeviceAddress() { BufferDeviceAddressPass pass(*this); pass.Run(); + if (print_info_) { + printf("BufferDeviceAddressPass\n\tinstrumentation count: %u\n", pass.GetInstrumentedCount()); + } } void Module::RunPassRayQuery() { RayQueryPass pass(*this); pass.Run(); + if (print_info_) { + printf("RayQueryPass\n\tinstrumentation count: %u\n", pass.GetInstrumentedCount()); + } } uint32_t Module::TakeNextId() { diff --git a/layers/gpu/spirv/module.h b/layers/gpu/spirv/module.h index ec1fe8163fb..7475dc8c43d 100644 --- a/layers/gpu/spirv/module.h +++ b/layers/gpu/spirv/module.h @@ -37,7 +37,7 @@ struct ModuleHeader { // There are other helper classes that are charge of handling the various parts of the module. class Module { public: - Module(std::vector words, uint32_t shader_id, uint32_t output_buffer_descriptor_set, + Module(std::vector words, uint32_t shader_id, uint32_t output_buffer_descriptor_set, bool print_info, uint32_t max_instrumented_count = 0); // Memory that holds all the actual SPIR-V data, replicate the "Logical Layout of a Module" of SPIR-V. @@ -89,6 +89,9 @@ class Module { // Will replace the "OpDecorate DescriptorSet" for the output buffer in the incoming linked module // This allows anything to be set in the GLSL for the set value, as we change it at runtime const uint32_t output_buffer_descriptor_set_; + + // Used to help debug + bool print_info_; }; } // namespace spirv diff --git a/layers/gpu/spirv/pass.h b/layers/gpu/spirv/pass.h index 615df5c9685..848bf5b1a07 100644 --- a/layers/gpu/spirv/pass.h +++ b/layers/gpu/spirv/pass.h @@ -50,6 +50,8 @@ class Pass { uint32_t ConvertTo32(uint32_t id, BasicBlock& block, InstructionIt* inst_it = nullptr); uint32_t CastToUint32(uint32_t id, BasicBlock& block, InstructionIt* inst_it = nullptr); + uint32_t GetInstrumentedCount() { return instrumented_count_; } + protected: Pass(Module& module, bool conditional_function_check) : module_(module), conditional_function_check_(conditional_function_check) {} diff --git a/layers/layer_options.cpp b/layers/layer_options.cpp index 566ee7864a1..22a2ec5e91f 100644 --- a/layers/layer_options.cpp +++ b/layers/layer_options.cpp @@ -175,6 +175,7 @@ const char *VK_LAYER_GPUAV_DEBUG_DISABLE_ALL = "gpuav_debug_disable_all"; const char *VK_LAYER_GPUAV_DEBUG_VALIDATE_INSTRUMENTED_SHADERS = "gpuav_debug_validate_instrumented_shaders"; const char *VK_LAYER_GPUAV_DEBUG_DUMP_INSTRUMENTED_SHADERS = "gpuav_debug_dump_instrumented_shaders"; const char *VK_LAYER_GPUAV_DEBUG_MAX_INSTRUMENTED_COUNT = "gpuav_debug_max_instrumented_count"; +const char *VK_LAYER_GPUAV_DEBUG_PRINT_INSTRUMENTATION_INFO = "gpuav_debug_print_instrumentation_info"; // SyncVal // --- @@ -652,6 +653,11 @@ void ProcessConfigAndEnvSettings(ConfigAndEnvSettings *settings_data) { gpuav_settings.debug_max_instrumented_count); } + if (vkuHasLayerSetting(layer_setting_set, VK_LAYER_GPUAV_DEBUG_PRINT_INSTRUMENTATION_INFO)) { + vkuGetLayerSettingValue(layer_setting_set, VK_LAYER_GPUAV_DEBUG_PRINT_INSTRUMENTATION_INFO, + gpuav_settings.debug_print_instrumentation_info); + } + SyncValSettings &syncval_settings = *settings_data->syncval_settings; if (vkuHasLayerSetting(layer_setting_set, VK_LAYER_SYNCVAL_SUBMIT_TIME_VALIDATION)) { vkuGetLayerSettingValue(layer_setting_set, VK_LAYER_SYNCVAL_SUBMIT_TIME_VALIDATION, diff --git a/tests/spirv/instrumentation.cpp b/tests/spirv/instrumentation.cpp index 0f68c573284..c507ba9bc06 100644 --- a/tests/spirv/instrumentation.cpp +++ b/tests/spirv/instrumentation.cpp @@ -123,7 +123,8 @@ int main(int argc, char** argv) { start_time = std::chrono::high_resolution_clock::now(); } - gpuav::spirv::Module module(spirv_data, kDefaultShaderId, kInstDefaultDescriptorSet); + // Always print information as this file is only used for debugging/testing + gpuav::spirv::Module module(spirv_data, kDefaultShaderId, kInstDefaultDescriptorSet, true); if (all_passes || bindless_descriptor_pass) { module.RunPassBindlessDescriptor(); }