summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/Vulkan/TextureConverter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/VideoBackends/Vulkan/TextureConverter.cpp')
-rw-r--r--Source/Core/VideoBackends/Vulkan/TextureConverter.cpp75
1 files changed, 36 insertions, 39 deletions
diff --git a/Source/Core/VideoBackends/Vulkan/TextureConverter.cpp b/Source/Core/VideoBackends/Vulkan/TextureConverter.cpp
index 7765647b1f..1bc173d4ee 100644
--- a/Source/Core/VideoBackends/Vulkan/TextureConverter.cpp
+++ b/Source/Core/VideoBackends/Vulkan/TextureConverter.cpp
@@ -27,6 +27,7 @@
#include "VideoCommon/TextureConversionShader.h"
#include "VideoCommon/TextureDecoder.h"
+#include "VideoCommon/VideoConfig.h"
namespace Vulkan
{
@@ -57,11 +58,8 @@ TextureConverter::~TextureConverter()
if (m_encoding_render_framebuffer != VK_NULL_HANDLE)
vkDestroyFramebuffer(g_vulkan_context->GetDevice(), m_encoding_render_framebuffer, nullptr);
- for (VkShaderModule shader : m_encoding_shaders)
- {
- if (shader != VK_NULL_HANDLE)
- vkDestroyShaderModule(g_vulkan_context->GetDevice(), shader, nullptr);
- }
+ for (auto& it : m_encoding_shaders)
+ vkDestroyShaderModule(g_vulkan_context->GetDevice(), it.second, nullptr);
for (const auto& it : m_decoding_pipelines)
{
@@ -89,12 +87,6 @@ bool TextureConverter::Initialize()
return false;
}
- if (!CompileEncodingShaders())
- {
- PanicAlert("Failed to compile texture encoding shaders");
- return false;
- }
-
if (!CreateEncodingRenderPass())
{
PanicAlert("Failed to create encode render pass");
@@ -221,15 +213,17 @@ void TextureConverter::ConvertTexture(TextureCache::TCacheEntry* dst_entry,
draw.EndRenderPass();
}
-void TextureConverter::EncodeTextureToMemory(VkImageView src_texture, u8* dest_ptr, u32 format,
- u32 native_width, u32 bytes_per_row, u32 num_blocks_y,
- u32 memory_stride, bool is_depth_copy,
- bool is_intensity, int scale_by_half,
- const EFBRectangle& src_rect)
+void TextureConverter::EncodeTextureToMemory(VkImageView src_texture, u8* dest_ptr,
+ const EFBCopyFormat& format, u32 native_width,
+ u32 bytes_per_row, u32 num_blocks_y, u32 memory_stride,
+ bool is_depth_copy, const EFBRectangle& src_rect,
+ bool scale_by_half)
{
- if (m_encoding_shaders[format] == VK_NULL_HANDLE)
+ VkShaderModule shader = GetEncodingShader(format);
+ if (shader == VK_NULL_HANDLE)
{
- ERROR_LOG(VIDEO, "Missing encoding fragment shader for format %u", format);
+ ERROR_LOG(VIDEO, "Missing encoding fragment shader for format %u->%u", format.efb_format,
+ static_cast<u32>(format.copy_format));
return;
}
@@ -242,17 +236,19 @@ void TextureConverter::EncodeTextureToMemory(VkImageView src_texture, u8* dest_p
UtilityShaderDraw draw(g_command_buffer_mgr->GetCurrentCommandBuffer(),
g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_PUSH_CONSTANT),
m_encoding_render_pass, g_object_cache->GetScreenQuadVertexShader(),
- VK_NULL_HANDLE, m_encoding_shaders[format]);
+ VK_NULL_HANDLE, shader);
// Uniform - int4 of left,top,native_width,scale
s32 position_uniform[4] = {src_rect.left, src_rect.top, static_cast<s32>(native_width),
scale_by_half ? 2 : 1};
draw.SetPushConstants(position_uniform, sizeof(position_uniform));
- // Doesn't make sense to linear filter depth values
- draw.SetPSSampler(0, src_texture, (scale_by_half && !is_depth_copy) ?
- g_object_cache->GetLinearSampler() :
- g_object_cache->GetPointSampler());
+ // We also linear filtering for both box filtering and downsampling higher resolutions to 1x
+ // TODO: This only produces perfect downsampling for 1.5x and 2x IR, other resolution will
+ // need more complex down filtering to average all pixels and produce the correct result.
+ bool linear_filter = (scale_by_half && !is_depth_copy) || g_ActiveConfig.iEFBScale != SCALE_1X;
+ draw.SetPSSampler(0, src_texture, linear_filter ? g_object_cache->GetLinearSampler() :
+ g_object_cache->GetPointSampler());
u32 render_width = bytes_per_row / sizeof(u32);
u32 render_height = num_blocks_y;
@@ -681,24 +677,25 @@ bool TextureConverter::CompilePaletteConversionShaders()
m_palette_conversion_shaders[GX_TL_RGB5A3] != VK_NULL_HANDLE;
}
-bool TextureConverter::CompileEncodingShaders()
+VkShaderModule TextureConverter::CompileEncodingShader(const EFBCopyFormat& format)
{
- // Texture encoding shaders
- static const u32 texture_encoding_shader_formats[] = {
- GX_TF_I4, GX_TF_I8, GX_TF_IA4, GX_TF_IA8, GX_TF_RGB565, GX_TF_RGB5A3, GX_TF_RGBA8,
- GX_CTF_R4, GX_CTF_RA4, GX_CTF_RA8, GX_CTF_A8, GX_CTF_R8, GX_CTF_G8, GX_CTF_B8,
- GX_CTF_RG8, GX_CTF_GB8, GX_CTF_Z8H, GX_TF_Z8, GX_CTF_Z16R, GX_TF_Z16, GX_TF_Z24X8,
- GX_CTF_Z4, GX_CTF_Z8M, GX_CTF_Z8L, GX_CTF_Z16L};
- for (u32 format : texture_encoding_shader_formats)
- {
- const char* shader_source =
- TextureConversionShader::GenerateEncodingShader(format, APIType::Vulkan);
- m_encoding_shaders[format] = Util::CompileAndCreateFragmentShader(shader_source);
- if (m_encoding_shaders[format] == VK_NULL_HANDLE)
- return false;
- }
+ const char* shader = TextureConversionShader::GenerateEncodingShader(format, APIType::Vulkan);
+ VkShaderModule module = Util::CompileAndCreateFragmentShader(shader);
+ if (module == VK_NULL_HANDLE)
+ PanicAlert("Failed to compile texture encoding shader.");
- return true;
+ return module;
+}
+
+VkShaderModule TextureConverter::GetEncodingShader(const EFBCopyFormat& format)
+{
+ auto iter = m_encoding_shaders.find(format);
+ if (iter != m_encoding_shaders.end())
+ return iter->second;
+
+ VkShaderModule shader = CompileEncodingShader(format);
+ m_encoding_shaders.emplace(format, shader);
+ return shader;
}
bool TextureConverter::CreateEncodingRenderPass()