From f8ad621df5f830d4bb486ea82af4e18a16f06649 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 8 Mar 2021 00:12:38 +0100 Subject: [PATCH] PipelineManagerVulkan: Log shader source when pipeline creation fails. --- GPU/Vulkan/PipelineManagerVulkan.cpp | 36 ++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/GPU/Vulkan/PipelineManagerVulkan.cpp b/GPU/Vulkan/PipelineManagerVulkan.cpp index e8d5538f25..5c707baa9f 100644 --- a/GPU/Vulkan/PipelineManagerVulkan.cpp +++ b/GPU/Vulkan/PipelineManagerVulkan.cpp @@ -138,6 +138,26 @@ static bool UsesBlendConstant(int factor) { } } +static std::string CutFromMain(std::string str) { + std::vector lines; + SplitString(str, '\n', lines); + + std::string rebuilt; + bool foundStart = false; + int c = 0; + for (const std::string &str : lines) { + if (startsWith(str, "void main")) { + foundStart = true; + rebuilt += StringFromFormat("... (cut %d lines)\n", c); + } + if (foundStart) { + rebuilt += str + "\n"; + } + c++; + } + return rebuilt; +} + static VulkanPipeline *CreateVulkanPipeline(VkDevice device, VkPipelineCache pipelineCache, VkPipelineLayout layout, VkRenderPass renderPass, const VulkanPipelineRasterStateKey &key, const DecVtxFormat *decFmt, VulkanVertexShader *vs, VulkanFragmentShader *fs, bool useHwTransform, float lineWidth) { @@ -303,13 +323,15 @@ static VulkanPipeline *CreateVulkanPipeline(VkDevice device, VkPipelineCache pip VkPipeline pipeline; VkResult result = vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipe, nullptr, &pipeline); if (result != VK_SUCCESS) { + ERROR_LOG(G3D, "Failed creating graphics pipeline! result='%s'", VulkanResultToString(result)); if (result == VK_INCOMPLETE) { - // Bad return value seen on Adreno in Burnout :( Try to ignore? - // TODO: Log all the information we can here! + // Typical Adreno return value. It'll usually also log something vague, like "Failed to link shaders". + // Let's log some stuff and try to stumble along. + ERROR_LOG(G3D, "VS source code:\n%s\n", CutFromMain(vs->GetShaderString(SHADER_STRING_SOURCE_CODE)).c_str()); + ERROR_LOG(G3D, "FS source code:\n%s\n", CutFromMain(fs->GetShaderString(SHADER_STRING_SOURCE_CODE)).c_str()); } else { _dbg_assert_msg_(false, "Failed creating graphics pipeline! result='%s'", VulkanResultToString(result)); } - ERROR_LOG(G3D, "Failed creating graphics pipeline! result='%s'", VulkanResultToString(result)); // Create a placeholder to avoid creating over and over if something is broken. VulkanPipeline *nullPipeline = new VulkanPipeline(); nullPipeline->pipeline = VK_NULL_HANDLE; @@ -732,6 +754,7 @@ bool PipelineManagerVulkan::LoadCache(FILE *file, bool loadRawPipelineCache, Sha bool failed = fread(&size, sizeof(size), 1, file) != 1; NOTICE_LOG(G3D, "Creating %d pipelines...", size); + int pipelineCreateFailCount = 0; for (uint32_t i = 0; i < size; i++) { if (failed || cancelCache_) { break; @@ -759,11 +782,14 @@ bool PipelineManagerVulkan::LoadCache(FILE *file, bool loadRawPipelineCache, Sha DecVtxFormat fmt; fmt.InitializeFromID(key.vtxFmtId); - GetOrCreatePipeline(layout, rp, key.raster, + VulkanPipeline *pipeline = GetOrCreatePipeline(layout, rp, key.raster, key.useHWTransform ? &fmt : 0, vs, fs, key.useHWTransform); + if (!pipeline) { + pipelineCreateFailCount += 1; + } } - NOTICE_LOG(G3D, "Recreated Vulkan pipeline cache (%d pipelines).", (int)size); + NOTICE_LOG(G3D, "Recreated Vulkan pipeline cache (%d pipelines, %d failed).", (int)size, pipelineCreateFailCount); return true; }