diff --git a/GPU/Common/GPUStateUtils.cpp b/GPU/Common/GPUStateUtils.cpp index 9efde97ae6..7690156d9d 100644 --- a/GPU/Common/GPUStateUtils.cpp +++ b/GPU/Common/GPUStateUtils.cpp @@ -1058,8 +1058,10 @@ static void ConvertBlendState(GenericBlendState &blendState, bool forceReplaceBl ReplaceBlendType replaceBlend = ReplaceBlendWithShader(gstate_c.framebufFormat); if (forceReplaceBlend) { - replaceBlend = REPLACE_BLEND_READ_FRAMEBUFFER; + // Enforce blend replacement if enabled. If not, shouldn't do anything of course. + replaceBlend = gstate.isAlphaBlendEnabled() ? REPLACE_BLEND_READ_FRAMEBUFFER : REPLACE_BLEND_NO; } + blendState.replaceBlend = replaceBlend; blendState.simulateLogicOpType = SimulateLogicOpShaderTypeIfNeeded(); diff --git a/GPU/Common/GPUStateUtils.h b/GPU/Common/GPUStateUtils.h index 2055da4657..bc0c9ae7b1 100644 --- a/GPU/Common/GPUStateUtils.h +++ b/GPU/Common/GPUStateUtils.h @@ -245,7 +245,9 @@ struct ComputedPipelineState { void Convert(bool shaderBitOpsSupported); bool FramebufferRead() const { - return blendState.applyFramebufferRead; + // If blending is off, its applyFramebufferRead can be false even after state propagation. + // So it's not enough to check just that one. + return blendState.applyFramebufferRead || maskState.applyFramebufferRead || logicState.applyFramebufferRead; } }; diff --git a/GPU/Vulkan/ShaderManagerVulkan.cpp b/GPU/Vulkan/ShaderManagerVulkan.cpp index 9cb91e00c6..132b4fba20 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.cpp +++ b/GPU/Vulkan/ShaderManagerVulkan.cpp @@ -44,7 +44,8 @@ // Most drivers treat vkCreateShaderModule as pretty much a memcpy. What actually // takes time here, and makes this worthy of parallelization, is GLSLtoSPV. -Promise *CompileShaderModuleAsync(VulkanContext *vulkan, VkShaderStageFlagBits stage, const char *code) { +// Takes ownership over tag. +static Promise *CompileShaderModuleAsync(VulkanContext *vulkan, VkShaderStageFlagBits stage, const char *code, std::string *tag) { auto compile = [=] { PROFILE_THIS_SCOPE("shadercomp"); @@ -59,12 +60,13 @@ Promise *CompileShaderModuleAsync(VulkanContext *vulkan, VkShade } else { ERROR_LOG(G3D, "Error in shader compilation!"); } + std::string numberedSource = LineNumberString(code); ERROR_LOG(G3D, "Messages: %s", errorMessage.c_str()); - ERROR_LOG(G3D, "Shader source:\n%s", code); -#ifdef SHADERLOG - OutputDebugStringA(LineNumberString(code).c_str()); + ERROR_LOG(G3D, "Shader source:\n%s", numberedSource.c_str()); +#if PPSSPP_PLATFORM(WINDOWS) OutputDebugStringA("Error messages:\n"); OutputDebugStringA(errorMessage.c_str()); + OutputDebugStringA(numberedSource.c_str()); #endif Reporting::ReportMessage("Vulkan error in shader compilation: info: %s / code: %s", errorMessage.c_str(), code); } @@ -75,6 +77,10 @@ Promise *CompileShaderModuleAsync(VulkanContext *vulkan, VkShade #ifdef SHADERLOG OutputDebugStringA("OK"); #endif + if (tag) { + vulkan->SetDebugName(shaderModule, VK_OBJECT_TYPE_SHADER_MODULE, tag->c_str()); + delete tag; + } } return shaderModule; @@ -92,7 +98,7 @@ Promise *CompileShaderModuleAsync(VulkanContext *vulkan, VkShade VulkanFragmentShader::VulkanFragmentShader(VulkanContext *vulkan, FShaderID id, FragmentShaderFlags flags, const char *code) : vulkan_(vulkan), id_(id), flags_(flags) { source_ = code; - module_ = CompileShaderModuleAsync(vulkan, VK_SHADER_STAGE_FRAGMENT_BIT, source_.c_str()); + module_ = CompileShaderModuleAsync(vulkan, VK_SHADER_STAGE_FRAGMENT_BIT, source_.c_str(), new std::string(FragmentShaderDesc(id))); if (!module_) { failed_ = true; } else { @@ -122,7 +128,7 @@ std::string VulkanFragmentShader::GetShaderString(DebugShaderStringType type) co VulkanVertexShader::VulkanVertexShader(VulkanContext *vulkan, VShaderID id, const char *code, bool useHWTransform) : vulkan_(vulkan), useHWTransform_(useHWTransform), id_(id) { source_ = code; - module_ = CompileShaderModuleAsync(vulkan, VK_SHADER_STAGE_VERTEX_BIT, source_.c_str()); + module_ = CompileShaderModuleAsync(vulkan, VK_SHADER_STAGE_VERTEX_BIT, source_.c_str(), new std::string(VertexShaderDesc(id).c_str())); if (!module_) { failed_ = true; } else {