From: Samuel Pitoiset Date: Thu, 20 Aug 2020 14:03:36 +0000 (+0200) Subject: radv: dump shader stats with VK_KHR_pipeline_executable_properties X-Git-Url: https://git.libre-soc.org/?p=mesa.git;a=commitdiff_plain;h=8301a43f272df7aa8c28e4143be1549bbef74e42 radv: dump shader stats with VK_KHR_pipeline_executable_properties Instead of duplicating shader statistics in two different parts in the driver. This also now reports the LDS size in bytes instead of blocks with VK_AMD_shader_info. Signed-off-by: Samuel Pitoiset Reviewed-by: Bas Nieuwenhuizen Part-of: --- diff --git a/src/amd/vulkan/radv_debug.c b/src/amd/vulkan/radv_debug.c index 0c9ed2752fb..d50480aa47f 100644 --- a/src/amd/vulkan/radv_debug.c +++ b/src/amd/vulkan/radv_debug.c @@ -444,7 +444,7 @@ radv_dump_shader(struct radv_pipeline *pipeline, shader->ir_string); fprintf(f, "DISASM:\n%s\n", shader->disasm_string); - radv_shader_dump_stats(pipeline->device, shader, stage, f); + radv_dump_shader_stats(pipeline->device, pipeline, stage, f); } static void diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c index 33d594f6c48..faae8252c93 100644 --- a/src/amd/vulkan/radv_pipeline.c +++ b/src/amd/vulkan/radv_pipeline.c @@ -3104,10 +3104,9 @@ VkResult radv_create_shaders(struct radv_pipeline *pipeline, if (nir[i]) { ralloc_free(nir[i]); - if (radv_can_dump_shader_stats(device, modules[i])) - radv_shader_dump_stats(device, - pipeline->shaders[i], - i, stderr); + if (radv_can_dump_shader_stats(device, modules[i])) { + radv_dump_shader_stats(device, pipeline, i, stderr); + } } } diff --git a/src/amd/vulkan/radv_shader.c b/src/amd/vulkan/radv_shader.c index 61369080997..b462393b118 100644 --- a/src/amd/vulkan/radv_shader.c +++ b/src/amd/vulkan/radv_shader.c @@ -47,8 +47,6 @@ #include "aco_interface.h" -#include "util/string_buffer.h" - static const struct nir_shader_compiler_options nir_options_llvm = { .vertex_id_zero_based = true, .lower_scmp = true, @@ -1507,66 +1505,6 @@ radv_get_max_waves(struct radv_device *device, return max_simd_waves; } -static void -generate_shader_stats(struct radv_device *device, - struct radv_shader_variant *variant, - gl_shader_stage stage, - struct _mesa_string_buffer *buf) -{ - struct ac_shader_config *conf = &variant->config; - unsigned max_simd_waves = radv_get_max_waves(device, variant, stage); - - if (stage == MESA_SHADER_FRAGMENT) { - _mesa_string_buffer_printf(buf, "*** SHADER CONFIG ***\n" - "SPI_PS_INPUT_ADDR = 0x%04x\n" - "SPI_PS_INPUT_ENA = 0x%04x\n", - conf->spi_ps_input_addr, conf->spi_ps_input_ena); - } - - _mesa_string_buffer_printf(buf, "*** SHADER STATS ***\n" - "SGPRS: %d\n" - "VGPRS: %d\n" - "Spilled SGPRs: %d\n" - "Spilled VGPRs: %d\n" - "PrivMem VGPRS: %d\n" - "Code Size: %d bytes\n" - "LDS: %d blocks\n" - "Scratch: %d bytes per wave\n" - "Max Waves: %d\n", - conf->num_sgprs, conf->num_vgprs, - conf->spilled_sgprs, conf->spilled_vgprs, - variant->info.private_mem_vgprs, variant->exec_size, - conf->lds_size, conf->scratch_bytes_per_wave, - max_simd_waves); - - if (variant->statistics) { - _mesa_string_buffer_printf(buf, "*** COMPILER STATS ***\n"); - for (unsigned i = 0; i < variant->statistics->count; i++) { - struct radv_compiler_statistic_info *info = &variant->statistics->infos[i]; - uint32_t value = variant->statistics->values[i]; - _mesa_string_buffer_printf(buf, "%s: %lu\n", info->name, value); - } - } - - _mesa_string_buffer_printf(buf, "********************\n\n\n"); -} - -void -radv_shader_dump_stats(struct radv_device *device, - struct radv_shader_variant *variant, - gl_shader_stage stage, - FILE *file) -{ - struct _mesa_string_buffer *buf = _mesa_string_buffer_create(NULL, 256); - - generate_shader_stats(device, variant, stage, buf); - - fprintf(file, "\n%s:\n", radv_get_shader_name(&variant->info, stage)); - fprintf(file, "%s", buf->buf); - - _mesa_string_buffer_destroy(buf); -} - VkResult radv_GetShaderInfoAMD(VkDevice _device, VkPipeline _pipeline, @@ -1579,7 +1517,6 @@ radv_GetShaderInfoAMD(VkDevice _device, RADV_FROM_HANDLE(radv_pipeline, pipeline, _pipeline); gl_shader_stage stage = vk_to_mesa_shader_stage(shaderStage); struct radv_shader_variant *variant = pipeline->shaders[stage]; - struct _mesa_string_buffer *buf; VkResult result = VK_SUCCESS; /* Spec doesn't indicate what to do if the stage is invalid, so just @@ -1631,16 +1568,19 @@ radv_GetShaderInfoAMD(VkDevice _device, } break; - case VK_SHADER_INFO_TYPE_DISASSEMBLY_AMD: - buf = _mesa_string_buffer_create(NULL, 1024); + case VK_SHADER_INFO_TYPE_DISASSEMBLY_AMD: { + char *out; + size_t outsize; + FILE *memf = open_memstream(&out, &outsize); - _mesa_string_buffer_printf(buf, "%s:\n", radv_get_shader_name(&variant->info, stage)); - _mesa_string_buffer_printf(buf, "%s\n\n", variant->ir_string); - _mesa_string_buffer_printf(buf, "%s\n\n", variant->disasm_string); - generate_shader_stats(device, variant, stage, buf); + fprintf(memf, "%s:\n", radv_get_shader_name(&variant->info, stage)); + fprintf(memf, "%s\n\n", variant->ir_string); + fprintf(memf, "%s\n\n", variant->disasm_string); + radv_dump_shader_stats(device, pipeline, stage, memf); + fclose(memf); /* Need to include the null terminator. */ - size_t length = buf->length + 1; + size_t length = outsize + 1; if (!pInfo) { *pInfoSize = length; @@ -1648,14 +1588,15 @@ radv_GetShaderInfoAMD(VkDevice _device, size_t size = *pInfoSize; *pInfoSize = length; - memcpy(pInfo, buf->buf, MIN2(size, length)); + memcpy(pInfo, out, MIN2(size, length)); if (size < length) result = VK_INCOMPLETE; } - _mesa_string_buffer_destroy(buf); + free(out); break; + } default: /* VK_SHADER_INFO_TYPE_BINARY_AMD unimplemented for now. */ result = VK_ERROR_FEATURE_NOT_PRESENT; @@ -1664,3 +1605,100 @@ radv_GetShaderInfoAMD(VkDevice _device, return result; } + +VkResult +radv_dump_shader_stats(struct radv_device *device, + struct radv_pipeline *pipeline, + gl_shader_stage stage, FILE *output) +{ + struct radv_shader_variant *shader = pipeline->shaders[stage]; + VkPipelineExecutablePropertiesKHR *props = NULL; + uint32_t prop_count = 0; + VkResult result; + + VkPipelineInfoKHR pipeline_info = {}; + pipeline_info.sType = VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR; + pipeline_info.pipeline = radv_pipeline_to_handle(pipeline); + + result = radv_GetPipelineExecutablePropertiesKHR(radv_device_to_handle(device), + &pipeline_info, + &prop_count, NULL); + if (result != VK_SUCCESS) + return result; + + props = calloc(prop_count, sizeof(*props)); + if (!props) + return VK_ERROR_OUT_OF_HOST_MEMORY; + + result = radv_GetPipelineExecutablePropertiesKHR(radv_device_to_handle(device), + &pipeline_info, + &prop_count, props); + if (result != VK_SUCCESS) + goto fail; + + for (unsigned i = 0; i < prop_count; i++) { + if (!(props[i].stages & mesa_to_vk_shader_stage(stage))) + continue; + + VkPipelineExecutableStatisticKHR *stats = NULL; + uint32_t stat_count = 0; + VkResult result; + + VkPipelineExecutableInfoKHR exec_info = {}; + exec_info.pipeline = radv_pipeline_to_handle(pipeline); + exec_info.executableIndex = i; + + result = radv_GetPipelineExecutableStatisticsKHR(radv_device_to_handle(device), + &exec_info, + &stat_count, NULL); + if (result != VK_SUCCESS) + goto fail; + + stats = calloc(stat_count, sizeof(*stats)); + if (!stats) { + result = VK_ERROR_OUT_OF_HOST_MEMORY; + goto fail; + } + + result = radv_GetPipelineExecutableStatisticsKHR(radv_device_to_handle(device), + &exec_info, + &stat_count, stats); + if (result != VK_SUCCESS) { + free(stats); + goto fail; + } + + fprintf(output, "\n%s:\n", + radv_get_shader_name(&shader->info, stage)); + fprintf(output, "*** SHADER STATS ***\n"); + + for (unsigned i = 0; i < stat_count; i++) { + fprintf(output, "%s: ", stats[i].name); + switch (stats[i].format) { + case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_BOOL32_KHR: + fprintf(output, "%s", stats[i].value.b32 == VK_TRUE ? "true" : "false"); + break; + case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_INT64_KHR: + fprintf(output, "%"PRIi64, stats[i].value.i64); + break; + case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR: + fprintf(output, "%"PRIu64, stats[i].value.u64); + break; + case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_FLOAT64_KHR: + fprintf(output, "%f", stats[i].value.f64); + break; + default: + unreachable("Invalid pipeline statistic format"); + } + fprintf(output, "\n"); + } + + fprintf(output, "********************\n\n\n"); + + free(stats); + } + +fail: + free(props); + return result; +} diff --git a/src/amd/vulkan/radv_shader.h b/src/amd/vulkan/radv_shader.h index 1638614091c..81f62014009 100644 --- a/src/amd/vulkan/radv_shader.h +++ b/src/amd/vulkan/radv_shader.h @@ -510,12 +510,6 @@ const char * radv_get_shader_name(struct radv_shader_info *info, gl_shader_stage stage); -void -radv_shader_dump_stats(struct radv_device *device, - struct radv_shader_variant *variant, - gl_shader_stage stage, - FILE *file); - bool radv_can_dump_shader(struct radv_device *device, struct radv_shader_module *module, @@ -525,6 +519,11 @@ bool radv_can_dump_shader_stats(struct radv_device *device, struct radv_shader_module *module); +VkResult +radv_dump_shader_stats(struct radv_device *device, + struct radv_pipeline *pipeline, + gl_shader_stage stage, FILE *output); + static inline unsigned shader_io_get_unique_index(gl_varying_slot slot) {