diff --git a/Common/Thread/Promise.h b/Common/Thread/Promise.h index 96c36f9605..e09e4c8174 100644 --- a/Common/Thread/Promise.h +++ b/Common/Thread/Promise.h @@ -78,6 +78,7 @@ public: } // Returns T if the data is ready, nullptr if it's not. + // Obviously, can only be used if T is nullable, otherwise it won't compile. T Poll() { std::lock_guard guard(readyMutex_); if (ready_) { diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 67d3876332..5543c15e37 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -581,7 +581,7 @@ std::string GPU_Vulkan::DebugGetShaderString(std::string id, DebugShaderType typ if (type == SHADER_TYPE_VERTEXLOADER) { return drawEngine_.DebugGetVertexLoaderString(id, stringType); } else if (type == SHADER_TYPE_PIPELINE) { - return pipelineManager_->DebugGetObjectString(id, type, stringType); + return pipelineManager_->DebugGetObjectString(id, type, stringType, shaderManagerVulkan_); } else if (type == SHADER_TYPE_TEXTURE) { return textureCache_->GetTextureShaderCache()->DebugGetShaderString(id, type, stringType); } else if (type == SHADER_TYPE_SAMPLER) { diff --git a/GPU/Vulkan/PipelineManagerVulkan.cpp b/GPU/Vulkan/PipelineManagerVulkan.cpp index 1d097e9f32..cb74b326e7 100644 --- a/GPU/Vulkan/PipelineManagerVulkan.cpp +++ b/GPU/Vulkan/PipelineManagerVulkan.cpp @@ -402,10 +402,10 @@ std::vector PipelineManagerVulkan::DebugGetObjectIDs(DebugShaderTyp } static const char *const topologies[8] = { - "POINTLIST", - "LINELIST", + "POINTS", + "LINES", "LINESTRIP", - "TRILIST", + "TRIS", "TRISTRIP", "TRIFAN", }; @@ -413,7 +413,7 @@ static const char *const topologies[8] = { static const char *const blendOps[8] = { "ADD", "SUB", - "REVSUB", + "RSUB", "MIN", "MAX", }; @@ -451,9 +451,9 @@ static const char *const logicOps[] = { static const char *const stencilOps[8] = { "KEEP", "ZERO", - "REPLACE", - "INC_CLAMP", - "DEC_CLAMP", + "REPL", + "INC_SAT", + "DEC_SAT", "INVERT", "INC_WRAP", "DEC_WRAP", @@ -462,26 +462,26 @@ static const char *const stencilOps[8] = { static const char *const blendFactors[19] = { "ZERO", "ONE", - "SRC_COLOR", - "ONE_MINUS_SRC_COLOR", - "DST_COLOR", - "ONE_MINUS_DST_COLOR", - "SRC_ALPHA", - "ONE_MINUS_SRC_ALPHA", - "DST_ALPHA", - "ONE_MINUS_DST_ALPHA", - "CONSTANT_COLOR", - "ONE_MINUS_CONSTANT_COLOR", - "CONSTANT_ALPHA", - "ONE_MINUS_CONSTANT_ALPHA", - "SRC_ALPHA_SATURATE", - "SRC1_COLOR", - "ONE_MINUS_SRC1_COLOR", - "SRC1_ALPHA", - "ONE_MINUS_SRC1_ALPHA", + "SRC_COL", + "INV_SRC_COL", + "DST_COL", + "INV_DST_COL", + "SRC_A", + "INV_SRC_A", + "DST_A", + "INV_DST_A", + "CONSTANT_COL", + "INV_CONST_COL", + "CONSTANT_A", + "INV_CONST_A", + "SRC_A_SAT", + "SRC1_COL", + "INV_SRC1_COL", + "SRC1_A", + "INV_SRC1_A", }; -std::string PipelineManagerVulkan::DebugGetObjectString(std::string id, DebugShaderType type, DebugShaderStringType stringType) { +std::string PipelineManagerVulkan::DebugGetObjectString(std::string id, DebugShaderType type, DebugShaderStringType stringType, ShaderManagerVulkan *shaderManager) { if (type != SHADER_TYPE_PIPELINE) return "N/A"; @@ -494,72 +494,94 @@ std::string PipelineManagerVulkan::DebugGetObjectString(std::string id, DebugSha } u32 variants = pipeline->GetVariantsBitmask(); - std::string keyDescription = pipelineKey.GetDescription(stringType); + std::string keyDescription = pipelineKey.GetDescription(stringType, shaderManager); return StringFromFormat("%s. v: %08x", keyDescription.c_str(), variants); } -std::string VulkanPipelineKey::GetDescription(DebugShaderStringType stringType) const { +std::string VulkanPipelineKey::GetRasterStateDesc(bool lineBreaks) const { + std::stringstream str; + str << topologies[raster.topology] << " "; + if (useHWTransform) { + str << "HWX "; + } + if (vtxFmtId) { + str << "Vfmt(" << StringFromFormat("%08x", vtxFmtId) << ") "; // TODO: Format nicer. + } else { + str << "SWX "; + } + if (lineBreaks) str << std::endl; + if (raster.blendEnable) { + str << "Blend(C:" << blendOps[raster.blendOpColor] << "/" + << blendFactors[raster.srcColor] << ":" << blendFactors[raster.destColor] << " "; + if (raster.blendOpAlpha != VK_BLEND_OP_ADD || + raster.srcAlpha != VK_BLEND_FACTOR_ONE || + raster.destAlpha != VK_BLEND_FACTOR_ZERO) { + str << "A:" << blendOps[raster.blendOpAlpha] << "/" + << blendFactors[raster.srcColor] << ":" << blendFactors[raster.destColor] << " "; + } + str << ") "; + if (lineBreaks) str << std::endl; + } + if (raster.colorWriteMask != 0xF) { + str << "Mask("; + for (int i = 0; i < 4; i++) { + if (raster.colorWriteMask & (1 << i)) { + str << "RGBA"[i]; + } else { + str << "_"; + } + } + str << ") "; + if (lineBreaks) str << std::endl; + } + if (raster.depthTestEnable) { + str << "Z("; + if (raster.depthWriteEnable) + str << "W, "; + if (raster.depthCompareOp) + str << compareOps[raster.depthCompareOp & 7]; + str << ") "; + if (lineBreaks) str << std::endl; + } + if (raster.stencilTestEnable) { + str << "Stenc("; + str << compareOps[raster.stencilCompareOp & 7] << " "; + str << stencilOps[raster.stencilPassOp & 7] << "/"; + str << stencilOps[raster.stencilFailOp & 7] << "/"; + str << stencilOps[raster.stencilDepthFailOp & 7]; + str << ") "; + if (lineBreaks) str << std::endl; + } + if (raster.logicOpEnable) { + str << "Logic(" << logicOps[raster.logicOp & 15] << ") "; + if (lineBreaks) str << std::endl; + } + return str.str(); +} + +std::string VulkanPipelineKey::GetDescription(DebugShaderStringType stringType, ShaderManagerVulkan *shaderManager) const { switch (stringType) { case SHADER_STRING_SHORT_DESC: - { - std::stringstream str; - str << topologies[raster.topology] << " "; - if (raster.blendEnable) { - str << "Blend(C:" << blendOps[raster.blendOpColor] << "/" - << blendFactors[raster.srcColor] << ":" << blendFactors[raster.destColor] << " "; - if (raster.blendOpAlpha != VK_BLEND_OP_ADD || - raster.srcAlpha != VK_BLEND_FACTOR_ONE || - raster.destAlpha != VK_BLEND_FACTOR_ZERO) { - str << "A:" << blendOps[raster.blendOpAlpha] << "/" - << blendFactors[raster.srcColor] << ":" << blendFactors[raster.destColor] << " "; - } - str << ") "; - } - if (raster.colorWriteMask != 0xF) { - str << "Mask("; - for (int i = 0; i < 4; i++) { - if (raster.colorWriteMask & (1 << i)) { - str << "RGBA"[i]; - } else { - str << "_"; - } - } - str << ") "; - } - if (raster.depthTestEnable) { - str << "Depth("; - if (raster.depthWriteEnable) - str << "W, "; - if (raster.depthCompareOp) - str << compareOps[raster.depthCompareOp & 7]; - str << ") "; - } - if (raster.stencilTestEnable) { - str << "Stencil("; - str << compareOps[raster.stencilCompareOp & 7] << " "; - str << stencilOps[raster.stencilPassOp & 7] << "/"; - str << stencilOps[raster.stencilFailOp & 7] << "/"; - str << stencilOps[raster.stencilDepthFailOp& 7]; - str << ") "; - } - if (raster.logicOpEnable) { - str << "Logic(" << logicOps[raster.logicOp & 15] << ") "; - } - if (useHWTransform) { - str << "HWX "; - } - if (vtxFmtId) { - str << "V(" << StringFromFormat("%08x", vtxFmtId) << ") "; // TODO: Format nicer. - } else { - str << "SWX "; - } - return str.str(); - } + // Just show the raster state. Also show brief VS/FS IDs? + return GetRasterStateDesc(false); case SHADER_STRING_SOURCE_CODE: { - return "N/A"; + // More detailed description of all the parts of the pipeline. + VkShaderModule fsModule = this->fShader->BlockUntilReady(); + VkShaderModule vsModule = this->vShader->BlockUntilReady(); + VkShaderModule gsModule = this->gShader ? this->gShader->BlockUntilReady() : VK_NULL_HANDLE; + + std::stringstream str; + str << "VS: " << VertexShaderDesc(shaderManager->GetVertexShaderFromModule(vsModule)->GetID()) << std::endl; + str << "FS: " << FragmentShaderDesc(shaderManager->GetFragmentShaderFromModule(fsModule)->GetID()) << std::endl; + if (gsModule) { + str << "GS: " << GeometryShaderDesc(shaderManager->GetGeometryShaderFromModule(gsModule)->GetID()) << std::endl; + } + str << GetRasterStateDesc(true); + return str.str(); } + default: return "N/A"; } diff --git a/GPU/Vulkan/PipelineManagerVulkan.h b/GPU/Vulkan/PipelineManagerVulkan.h index cb1cc4fb88..3331d1f606 100644 --- a/GPU/Vulkan/PipelineManagerVulkan.h +++ b/GPU/Vulkan/PipelineManagerVulkan.h @@ -32,6 +32,12 @@ struct VKRGraphicsPipeline; class VulkanRenderManager; +class VulkanContext; +class VulkanVertexShader; +class VulkanFragmentShader; +class VulkanGeometryShader; +class ShaderManagerVulkan; +class DrawEngineCommon; struct VulkanPipelineKey { VulkanPipelineRasterStateKey raster; // prim is included here @@ -49,7 +55,10 @@ struct VulkanPipelineKey { void FromString(const std::string &str) { memcpy(this, &str[0], sizeof(*this)); } - std::string GetDescription(DebugShaderStringType stringType) const; + std::string GetDescription(DebugShaderStringType stringType, ShaderManagerVulkan *shaderManager) const; + +private: + std::string GetRasterStateDesc(bool lineBreaks) const; }; // Simply wraps a Vulkan pipeline, providing some metadata. @@ -71,13 +80,6 @@ struct VulkanPipeline { u32 GetVariantsBitmask() const; }; -class VulkanContext; -class VulkanVertexShader; -class VulkanFragmentShader; -class VulkanGeometryShader; -class ShaderManagerVulkan; -class DrawEngineCommon; - class PipelineManagerVulkan { public: PipelineManagerVulkan(VulkanContext *ctx); @@ -94,7 +96,7 @@ public: void InvalidateMSAAPipelines(); - std::string DebugGetObjectString(std::string id, DebugShaderType type, DebugShaderStringType stringType); + std::string DebugGetObjectString(std::string id, DebugShaderType type, DebugShaderStringType stringType, ShaderManagerVulkan *shaderManager); std::vector DebugGetObjectIDs(DebugShaderType type) const; // Saves data for faster creation next time. diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index 568cc7c2fe..e54c1a76f6 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -1157,6 +1157,7 @@ int ShaderListScreen::ListShaders(DebugShaderType shaderType, UI::LinearLayout * for (const auto &id : shaderIds_) { Choice *choice = view->Add(new Choice(gpu->DebugGetShaderString(id, shaderType, SHADER_STRING_SHORT_DESC))); choice->SetTag(id); + choice->SetDrawTextFlags(FLAG_DYNAMIC_ASCII); choice->OnClick.Handle(this, &ShaderListScreen::OnShaderClick); count++; }