summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/Vulkan/TextureCache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/VideoBackends/Vulkan/TextureCache.cpp')
-rw-r--r--Source/Core/VideoBackends/Vulkan/TextureCache.cpp109
1 files changed, 25 insertions, 84 deletions
diff --git a/Source/Core/VideoBackends/Vulkan/TextureCache.cpp b/Source/Core/VideoBackends/Vulkan/TextureCache.cpp
index 5a396ee4b2..130a494bb2 100644
--- a/Source/Core/VideoBackends/Vulkan/TextureCache.cpp
+++ b/Source/Core/VideoBackends/Vulkan/TextureCache.cpp
@@ -237,80 +237,12 @@ bool TextureCache::CompileShaders()
}
)";
- static const char EFB_COLOR_TO_TEX_SOURCE[] = R"(
- SAMPLER_BINDING(0) uniform sampler2DArray samp0;
-
- layout(std140, push_constant) uniform PSBlock
- {
- vec4 colmat[7];
- } C;
-
- layout(location = 0) in vec3 uv0;
- layout(location = 1) in vec4 col0;
- layout(location = 0) out vec4 ocol0;
-
- void main()
- {
- float4 texcol = texture(samp0, uv0);
- texcol = floor(texcol * C.colmat[5]) * C.colmat[6];
- ocol0 = texcol * mat4(C.colmat[0], C.colmat[1], C.colmat[2], C.colmat[3]) + C.colmat[4];
- }
- )";
-
- static const char EFB_DEPTH_TO_TEX_SOURCE[] = R"(
- SAMPLER_BINDING(0) uniform sampler2DArray samp0;
-
- layout(std140, push_constant) uniform PSBlock
- {
- vec4 colmat[5];
- } C;
-
- layout(location = 0) in vec3 uv0;
- layout(location = 1) in vec4 col0;
- layout(location = 0) out vec4 ocol0;
-
- void main()
- {
- #if MONO_DEPTH
- vec4 texcol = texture(samp0, vec3(uv0.xy, 0.0f));
- #else
- vec4 texcol = texture(samp0, uv0);
- #endif
- int depth = int((1.0 - texcol.x) * 16777216.0);
-
- // Convert to Z24 format
- ivec4 workspace;
- workspace.r = (depth >> 16) & 255;
- workspace.g = (depth >> 8) & 255;
- workspace.b = depth & 255;
-
- // Convert to Z4 format
- workspace.a = (depth >> 16) & 0xF0;
-
- // Normalize components to [0.0..1.0]
- texcol = vec4(workspace) / 255.0;
-
- ocol0 = texcol * mat4(C.colmat[0], C.colmat[1], C.colmat[2], C.colmat[3]) + C.colmat[4];
- }
- )";
-
std::string header = g_shader_cache->GetUtilityShaderHeader();
- std::string source;
+ std::string source = header + COPY_SHADER_SOURCE;
- source = header + COPY_SHADER_SOURCE;
m_copy_shader = Util::CompileAndCreateFragmentShader(source);
- source = header + EFB_COLOR_TO_TEX_SOURCE;
- m_efb_color_to_tex_shader = Util::CompileAndCreateFragmentShader(source);
-
- if (g_ActiveConfig.bStereoEFBMonoDepth)
- source = header + "#define MONO_DEPTH 1\n" + EFB_DEPTH_TO_TEX_SOURCE;
- else
- source = header + EFB_DEPTH_TO_TEX_SOURCE;
- m_efb_depth_to_tex_shader = Util::CompileAndCreateFragmentShader(source);
-
- return m_copy_shader != VK_NULL_HANDLE && m_efb_color_to_tex_shader != VK_NULL_HANDLE &&
- m_efb_depth_to_tex_shader != VK_NULL_HANDLE;
+ return m_copy_shader != VK_NULL_HANDLE;
}
void TextureCache::DeleteShaders()
@@ -324,21 +256,18 @@ void TextureCache::DeleteShaders()
vkDestroyShaderModule(g_vulkan_context->GetDevice(), m_copy_shader, nullptr);
m_copy_shader = VK_NULL_HANDLE;
}
- if (m_efb_color_to_tex_shader != VK_NULL_HANDLE)
- {
- vkDestroyShaderModule(g_vulkan_context->GetDevice(), m_efb_color_to_tex_shader, nullptr);
- m_efb_color_to_tex_shader = VK_NULL_HANDLE;
- }
- if (m_efb_depth_to_tex_shader != VK_NULL_HANDLE)
+
+ for (auto& shader : m_efb_copy_to_tex_shaders)
{
- vkDestroyShaderModule(g_vulkan_context->GetDevice(), m_efb_depth_to_tex_shader, nullptr);
- m_efb_depth_to_tex_shader = VK_NULL_HANDLE;
+ vkDestroyShaderModule(g_vulkan_context->GetDevice(), shader.second, nullptr);
}
+ m_efb_copy_to_tex_shaders.clear();
}
void TextureCache::CopyEFBToCacheEntry(TCacheEntry* entry, bool is_depth_copy,
const EFBRectangle& src_rect, bool scale_by_half,
- unsigned int cbuf_id, const float* colmat)
+ unsigned int cbuf_id, const float* colmat,
+ EFBCopyFormat dst_format, bool is_intensity)
{
VKTexture* texture = static_cast<VKTexture*>(entry->texture.get());
@@ -378,13 +307,25 @@ void TextureCache::CopyEFBToCacheEntry(TCacheEntry* entry, bool is_depth_copy,
texture->GetRawTexIdentifier()->TransitionToLayout(command_buffer,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+ auto uid = GetTextureConverterShaderUid(dst_format, is_depth_copy, is_intensity, scale_by_half);
+
+ auto it = m_efb_copy_to_tex_shaders.emplace(uid, VkShaderModule(VK_NULL_HANDLE));
+ VkShaderModule& shader = it.first->second;
+ bool created = it.second;
+
+ if (created)
+ {
+ std::string source = g_shader_cache->GetUtilityShaderHeader();
+ source += GenerateTextureConverterShaderCode(APIType::Vulkan, uid.GetUidData()).GetBuffer();
+
+ shader = Util::CompileAndCreateFragmentShader(source);
+ }
+
UtilityShaderDraw draw(command_buffer,
- g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_PUSH_CONSTANT),
- m_render_pass, g_shader_cache->GetPassthroughVertexShader(),
- g_shader_cache->GetPassthroughGeometryShader(),
- is_depth_copy ? m_efb_depth_to_tex_shader : m_efb_color_to_tex_shader);
+ g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_STANDARD), m_render_pass,
+ g_shader_cache->GetPassthroughVertexShader(),
+ g_shader_cache->GetPassthroughGeometryShader(), shader);
- draw.SetPushConstants(colmat, (is_depth_copy ? sizeof(float) * 20 : sizeof(float) * 28));
draw.SetPSSampler(0, src_texture->GetView(), src_sampler);
VkRect2D dest_region = {{0, 0}, {texture->GetConfig().width, texture->GetConfig().height}};