diff --git a/Source/Core/VideoBackends/Vulkan/PaletteTextureConverter.cpp b/Source/Core/VideoBackends/Vulkan/PaletteTextureConverter.cpp index f67ed33b28..b9a135cd7e 100644 --- a/Source/Core/VideoBackends/Vulkan/PaletteTextureConverter.cpp +++ b/Source/Core/VideoBackends/Vulkan/PaletteTextureConverter.cpp @@ -62,7 +62,9 @@ bool PaletteTextureConverter::Initialize() return true; } -void PaletteTextureConverter::ConvertTexture(StateTracker* state_tracker, VkRenderPass render_pass, +void PaletteTextureConverter::ConvertTexture(StateTracker* state_tracker, + VkCommandBuffer command_buffer, + VkRenderPass render_pass, VkFramebuffer dst_framebuffer, Texture2D* src_texture, u32 width, u32 height, void* palette, TlutFormat format) @@ -113,14 +115,14 @@ void PaletteTextureConverter::ConvertTexture(StateTracker* state_tracker, VkRend &m_palette_buffer_view}; vkUpdateDescriptorSets(g_vulkan_context->GetDevice(), 1, &texel_set_write, 0, nullptr); - Util::BufferMemoryBarrier(g_command_buffer_mgr->GetCurrentInitCommandBuffer(), - m_palette_stream_buffer->GetBuffer(), VK_ACCESS_HOST_WRITE_BIT, - VK_ACCESS_SHADER_READ_BIT, palette_offset, palette_size, - VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); + Util::BufferMemoryBarrier(command_buffer, m_palette_stream_buffer->GetBuffer(), + VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, palette_offset, + palette_size, VK_PIPELINE_STAGE_HOST_BIT, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); // Set up draw - UtilityShaderDraw draw(g_command_buffer_mgr->GetCurrentInitCommandBuffer(), m_pipeline_layout, - render_pass, g_object_cache->GetScreenQuadVertexShader(), VK_NULL_HANDLE, + UtilityShaderDraw draw(command_buffer, m_pipeline_layout, render_pass, + g_object_cache->GetScreenQuadVertexShader(), VK_NULL_HANDLE, m_shaders[format]); VkRect2D region = {{0, 0}, {width, height}}; @@ -138,8 +140,7 @@ void PaletteTextureConverter::ConvertTexture(StateTracker* state_tracker, VkRend draw.SetPSSampler(0, src_texture->GetView(), g_object_cache->GetPointSampler()); // We have to bind the texel buffer descriptor set separately. - vkCmdBindDescriptorSets(g_command_buffer_mgr->GetCurrentInitCommandBuffer(), - VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_layout, 0, 1, + vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_layout, 0, 1, &texel_buffer_descriptor_set, 0, nullptr); // Draw diff --git a/Source/Core/VideoBackends/Vulkan/PaletteTextureConverter.h b/Source/Core/VideoBackends/Vulkan/PaletteTextureConverter.h index 537b029595..e611e65b84 100644 --- a/Source/Core/VideoBackends/Vulkan/PaletteTextureConverter.h +++ b/Source/Core/VideoBackends/Vulkan/PaletteTextureConverter.h @@ -26,9 +26,10 @@ public: bool Initialize(); - void ConvertTexture(StateTracker* state_tracker, VkRenderPass render_pass, - VkFramebuffer dst_framebuffer, Texture2D* src_texture, u32 width, u32 height, - void* palette, TlutFormat format); + void ConvertTexture(StateTracker* state_tracker, VkCommandBuffer command_buffer, + VkRenderPass render_pass, VkFramebuffer dst_framebuffer, + Texture2D* src_texture, u32 width, u32 height, void* palette, + TlutFormat format); private: static const size_t NUM_PALETTE_CONVERSION_SHADERS = 3; diff --git a/Source/Core/VideoBackends/Vulkan/TextureCache.cpp b/Source/Core/VideoBackends/Vulkan/TextureCache.cpp index 4b83a76b59..1a882716ce 100644 --- a/Source/Core/VideoBackends/Vulkan/TextureCache.cpp +++ b/Source/Core/VideoBackends/Vulkan/TextureCache.cpp @@ -92,9 +92,26 @@ void TextureCache::ConvertTexture(TCacheEntryBase* base_entry, TCacheEntryBase* TCacheEntry* unconverted = static_cast(base_unconverted); _assert_(entry->config.rendertarget); + // EFB copies can be used as paletted textures as well. For these, we can't assume them to be + // contain the correct data before the frame begins (when the init command buffer is executed), + // so we must convert them at the appropriate time, during the drawing command buffer. + VkCommandBuffer command_buffer; + if (unconverted->IsEfbCopy()) + { + command_buffer = g_command_buffer_mgr->GetCurrentCommandBuffer(); + m_state_tracker->EndRenderPass(); + m_state_tracker->SetPendingRebind(); + } + else + { + // Use initialization command buffer and perform conversion before the drawing commands. + command_buffer = g_command_buffer_mgr->GetCurrentInitCommandBuffer(); + } + m_palette_texture_converter->ConvertTexture( - m_state_tracker, GetRenderPassForTextureUpdate(entry->GetTexture()), entry->GetFramebuffer(), - unconverted->GetTexture(), entry->config.width, entry->config.height, palette, format); + m_state_tracker, command_buffer, GetRenderPassForTextureUpdate(entry->GetTexture()), + entry->GetFramebuffer(), unconverted->GetTexture(), entry->config.width, entry->config.height, + palette, format); // Render pass transitions to SHADER_READ_ONLY. entry->GetTexture()->OverrideImageLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);