From a9d2a50082281303a3081578ceb01581420c4958 Mon Sep 17 00:00:00 2001 From: DrChat Date: Sat, 3 Mar 2018 12:34:19 -0600 Subject: [PATCH] [Vulkan] Add AMD shader statistics info support --- src/xenia/gpu/vulkan/pipeline_cache.cc | 54 +++++++++++++++++++++++++- src/xenia/gpu/vulkan/pipeline_cache.h | 2 + 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/src/xenia/gpu/vulkan/pipeline_cache.cc b/src/xenia/gpu/vulkan/pipeline_cache.cc index d9a6a598f..4d5594276 100644 --- a/src/xenia/gpu/vulkan/pipeline_cache.cc +++ b/src/xenia/gpu/vulkan/pipeline_cache.cc @@ -333,7 +333,12 @@ VkPipeline PipelineCache::GetPipeline(const RenderState* render_state, // Dump shader disassembly. if (FLAGS_vulkan_dump_disasm) { - DumpShaderDisasmNV(pipeline_info); + if (device_->HasEnabledExtension(VK_AMD_SHADER_INFO_EXTENSION_NAME)) { + DumpShaderDisasmAMD(pipeline); + } else if (device_->device_info().properties.vendorID == 0x10DE) { + // NVIDIA cards + DumpShaderDisasmNV(pipeline_info); + } } // Add to cache with the hash key for reuse. @@ -374,6 +379,53 @@ bool PipelineCache::TranslateShader(VulkanShader* shader, return shader->is_valid(); } +static void DumpShaderStatisticsAMD(const VkShaderStatisticsInfoAMD& stats) { + XELOGI(" - resource usage:"); + XELOGI(" numUsedVgprs: %d", stats.resourceUsage.numUsedVgprs); + XELOGI(" numUsedSgprs: %d", stats.resourceUsage.numUsedSgprs); + XELOGI(" ldsSizePerLocalWorkGroup: %d", + stats.resourceUsage.ldsSizePerLocalWorkGroup); + XELOGI(" ldsUsageSizeInBytes : %d", + stats.resourceUsage.ldsUsageSizeInBytes); + XELOGI(" scratchMemUsageInBytes : %d", + stats.resourceUsage.scratchMemUsageInBytes); + XELOGI("numPhysicalVgprs : %d", stats.numPhysicalVgprs); + XELOGI("numPhysicalSgprs : %d", stats.numPhysicalSgprs); + XELOGI("numAvailableVgprs: %d", stats.numAvailableVgprs); + XELOGI("numAvailableSgprs: %d", stats.numAvailableSgprs); +} + +void PipelineCache::DumpShaderDisasmAMD(VkPipeline pipeline) { + auto fn_GetShaderInfoAMD = (PFN_vkGetShaderInfoAMD)vkGetDeviceProcAddr( + *device_, "vkGetShaderInfoAMD"); + + VkResult status = VK_SUCCESS; + size_t data_size = 0; + + VkShaderStatisticsInfoAMD stats; + data_size = sizeof(stats); + + // Vertex shader + status = fn_GetShaderInfoAMD(*device_, pipeline, VK_SHADER_STAGE_VERTEX_BIT, + VK_SHADER_INFO_TYPE_STATISTICS_AMD, &data_size, + &stats); + if (status == VK_SUCCESS) { + XELOGI("AMD Vertex Shader Statistics:"); + DumpShaderStatisticsAMD(stats); + } + + // Fragment shader + status = fn_GetShaderInfoAMD(*device_, pipeline, VK_SHADER_STAGE_FRAGMENT_BIT, + VK_SHADER_INFO_TYPE_STATISTICS_AMD, &data_size, + &stats); + if (status == VK_SUCCESS) { + XELOGI("AMD Fragment Shader Statistics:"); + DumpShaderStatisticsAMD(stats); + } + + // TODO(DrChat): Eventually dump the disasm... +} + void PipelineCache::DumpShaderDisasmNV( const VkGraphicsPipelineCreateInfo& pipeline_info) { // !! HACK !!: This only works on NVidia drivers. Dumps shader disasm. diff --git a/src/xenia/gpu/vulkan/pipeline_cache.h b/src/xenia/gpu/vulkan/pipeline_cache.h index 4a40855a5..efb49f97c 100644 --- a/src/xenia/gpu/vulkan/pipeline_cache.h +++ b/src/xenia/gpu/vulkan/pipeline_cache.h @@ -80,6 +80,8 @@ class PipelineCache { VkPipeline GetPipeline(const RenderState* render_state, uint64_t hash_key); bool TranslateShader(VulkanShader* shader, xenos::xe_gpu_program_cntl_t cntl); + + void DumpShaderDisasmAMD(VkPipeline pipeline); void DumpShaderDisasmNV(const VkGraphicsPipelineCreateInfo& info); // Gets a geometry shader used to emulate the given primitive type.