diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index ff03cf67fd..d75e1e8b3d 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -426,9 +426,9 @@ static void BarrierComputeImage(VkCommandBuffer cmd, VkImage image) { batch.Flush(cmd); } -void TextureCacheVulkan::LoadConstantBuffer(VulkanContext *vulkan, VkCommandBuffer cmdInit) { +bool TextureCacheVulkan::LoadConstantBuffer(VulkanContext *vulkan, VkCommandBuffer cmdInit) { if (cbufferInited_) { - return; + return true; } _dbg_assert_(!cbufferPath_.empty()); @@ -437,8 +437,12 @@ void TextureCacheVulkan::LoadConstantBuffer(VulkanContext *vulkan, VkCommandBuff size_t constantsSize; uint8_t *contents = g_VFS.ReadFile(cbufferPath_.c_str(), &constantsSize); if (!contents) { - ERROR_LOG(Log::G3D, "Failed to read constant buffer file '%s'", cbufferPath_.c_str()); - return; + ERROR_LOG(Log::G3D, "Failed to read constant buffer file '%s' - disabling hardware scaling", cbufferPath_.c_str()); + // The scaling shaders declare the constant buffer, so dispatching them without it would leave + // a statically used descriptor binding unwritten. Drop the shaders instead, which makes + // HasScalingShader() false so following textures take the CPU scaling path. + ClearScalingShaders(vulkan); + return false; } textureScaleCBuffer_.Create(vulkan, "TextureScale CBuffer", constantsSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT); VulkanPushPool *pushPool = drawEngine_->GetPushBufferForTextureData(); @@ -453,6 +457,7 @@ void TextureCacheVulkan::LoadConstantBuffer(VulkanContext *vulkan, VkCommandBuff delete[] contents; cbufferInited_ = true; + return true; } bool TextureCacheVulkan::RunMultipassCompute(VulkanContext *vulkan, VkCommandBuffer cmdInit, VkImageView dstView, VkBuffer texBuf, uint32_t bufferOffset, int srcSize, int srcWidth, int srcHeight, int dstWidth, int dstHeight) { @@ -462,7 +467,9 @@ bool TextureCacheVulkan::RunMultipassCompute(VulkanContext *vulkan, VkCommandBuf std::vector> scratchTextures; scratchTextures.reserve(multipassScratchDescs_.size()); - LoadConstantBuffer(vulkan, cmdInit); + if (!LoadConstantBuffer(vulkan, cmdInit)) { + return false; + } for (const MultipassScratchDesc &scratchDesc : multipassScratchDescs_) { auto scratch = std::make_unique(vulkan, scratchDesc.tag); @@ -537,7 +544,9 @@ bool TextureCacheVulkan::ScaleBufferToImage(VulkanContext *vulkan, VkCommandBuff return false; } - LoadConstantBuffer(vulkan, cmdInit); + if (!LoadConstantBuffer(vulkan, cmdInit)) { + return false; + } switch (textureScalePipeline_) { case TextureScalePipelineType::SINGLE_PASS: { diff --git a/GPU/Vulkan/TextureCacheVulkan.h b/GPU/Vulkan/TextureCacheVulkan.h index 5fc2ac80df..72b15b585f 100644 --- a/GPU/Vulkan/TextureCacheVulkan.h +++ b/GPU/Vulkan/TextureCacheVulkan.h @@ -128,7 +128,8 @@ private: bool RunMultipassCompute(VulkanContext *vulkan, VkCommandBuffer cmdInit, VkImageView dstView, VkBuffer texBuf, uint32_t bufferOffset, int srcSize, int srcWidth, int srcHeight, int dstWidth, int dstHeight); bool ScaleBufferToImage(VulkanContext *vulkan, VkCommandBuffer cmdInit, VkImageView dstView, VkBuffer texBuf, uint32_t bufferOffset, int srcSize, int srcWidth, int srcHeight, int dstWidth, int dstHeight); - void LoadConstantBuffer(VulkanContext *vulkan, VkCommandBuffer cmdInit); + // Returns false if the constant buffer couldn't be loaded, in which case hardware scaling gets disabled. + bool LoadConstantBuffer(VulkanContext *vulkan, VkCommandBuffer cmdInit); VulkanComputeShaderManager computeShaderManager_;