summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/OGL/TextureCache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/VideoBackends/OGL/TextureCache.cpp')
-rw-r--r--Source/Core/VideoBackends/OGL/TextureCache.cpp177
1 files changed, 71 insertions, 106 deletions
diff --git a/Source/Core/VideoBackends/OGL/TextureCache.cpp b/Source/Core/VideoBackends/OGL/TextureCache.cpp
index ba945f8043..f370da7142 100644
--- a/Source/Core/VideoBackends/OGL/TextureCache.cpp
+++ b/Source/Core/VideoBackends/OGL/TextureCache.cpp
@@ -26,11 +26,44 @@
#include "VideoCommon/ImageWrite.h"
#include "VideoCommon/TextureConversionShader.h"
+#include "VideoCommon/TextureConverterShaderGen.h"
#include "VideoCommon/TextureDecoder.h"
+#include "VideoCommon/VideoCommon.h"
#include "VideoCommon/VideoConfig.h"
namespace OGL
{
+constexpr const char* vertex_program =
+ "out vec3 %c_uv0;\n"
+ "SAMPLER_BINDING(9) uniform sampler2DArray samp9;\n"
+ "uniform vec4 copy_position;\n" // left, top, right, bottom
+ "void main()\n"
+ "{\n"
+ " vec2 rawpos = vec2(gl_VertexID&1, gl_VertexID&2);\n"
+ " %c_uv0 = vec3(mix(copy_position.xy, copy_position.zw, rawpos) / vec2(textureSize(samp9, "
+ "0).xy), 0.0);\n"
+ " gl_Position = vec4(rawpos*2.0-1.0, 0.0, 1.0);\n"
+ "}\n";
+
+constexpr const char* geometry_program = "layout(triangles) in;\n"
+ "layout(triangle_strip, max_vertices = 6) out;\n"
+ "in vec3 v_uv0[3];\n"
+ "out vec3 f_uv0;\n"
+ "SAMPLER_BINDING(9) uniform sampler2DArray samp9;\n"
+ "void main()\n"
+ "{\n"
+ " int layers = textureSize(samp9, 0).z;\n"
+ " for (int layer = 0; layer < layers; ++layer) {\n"
+ " for (int i = 0; i < 3; ++i) {\n"
+ " f_uv0 = vec3(v_uv0[i].xy, layer);\n"
+ " gl_Position = gl_in[i].gl_Position;\n"
+ " gl_Layer = layer;\n"
+ " EmitVertex();\n"
+ " }\n"
+ " EndPrimitive();\n"
+ " }\n"
+ "}\n";
+
//#define TIME_TEXTURE_DECODING 1
void TextureCache::CopyEFB(u8* dst, const EFBCopyParams& params, u32 native_width,
@@ -124,101 +157,22 @@ bool TextureCache::CompileShaders()
" ocol0 = texcol;\n"
"}\n";
- constexpr const char* color_matrix_program =
- "SAMPLER_BINDING(9) uniform sampler2DArray samp9;\n"
- "uniform vec4 colmat[7];\n"
- "in vec3 f_uv0;\n"
- "out vec4 ocol0;\n"
- "\n"
- "void main(){\n"
- " vec4 texcol = texture(samp9, f_uv0);\n"
- " texcol = floor(texcol * colmat[5]) * colmat[6];\n"
- " ocol0 = texcol * mat4(colmat[0], colmat[1], colmat[2], colmat[3]) + colmat[4];\n"
- "}\n";
-
- constexpr const char* depth_matrix_program =
- "SAMPLER_BINDING(9) uniform sampler2DArray samp9;\n"
- "uniform vec4 colmat[5];\n"
- "in vec3 f_uv0;\n"
- "out vec4 ocol0;\n"
- "\n"
- "void main(){\n"
- " vec4 texcol = texture(samp9, vec3(f_uv0.xy, %s));\n"
- " int depth = int(texcol.x * 16777216.0);\n"
-
- // Convert to Z24 format
- " ivec4 workspace;\n"
- " workspace.r = (depth >> 16) & 255;\n"
- " workspace.g = (depth >> 8) & 255;\n"
- " workspace.b = depth & 255;\n"
-
- // Convert to Z4 format
- " workspace.a = (depth >> 16) & 0xF0;\n"
-
- // Normalize components to [0.0..1.0]
- " texcol = vec4(workspace) / 255.0;\n"
-
- " ocol0 = texcol * mat4(colmat[0], colmat[1], colmat[2], colmat[3]) + colmat[4];\n"
- "}\n";
-
- constexpr const char* vertex_program =
- "out vec3 %s_uv0;\n"
- "SAMPLER_BINDING(9) uniform sampler2DArray samp9;\n"
- "uniform vec4 copy_position;\n" // left, top, right, bottom
- "void main()\n"
- "{\n"
- " vec2 rawpos = vec2(gl_VertexID&1, gl_VertexID&2);\n"
- " %s_uv0 = vec3(mix(copy_position.xy, copy_position.zw, rawpos) / vec2(textureSize(samp9, "
- "0).xy), 0.0);\n"
- " gl_Position = vec4(rawpos*2.0-1.0, 0.0, 1.0);\n"
- "}\n";
-
- const std::string geo_program = g_ActiveConfig.stereo_mode != StereoMode::Off ?
- "layout(triangles) in;\n"
- "layout(triangle_strip, max_vertices = 6) out;\n"
- "in vec3 v_uv0[3];\n"
- "out vec3 f_uv0;\n"
- "SAMPLER_BINDING(9) uniform sampler2DArray samp9;\n"
- "void main()\n"
- "{\n"
- " int layers = textureSize(samp9, 0).z;\n"
- " for (int layer = 0; layer < layers; ++layer) {\n"
- " for (int i = 0; i < 3; ++i) {\n"
- " f_uv0 = vec3(v_uv0[i].xy, layer);\n"
- " gl_Position = gl_in[i].gl_Position;\n"
- " gl_Layer = layer;\n"
- " EmitVertex();\n"
- " }\n"
- " EndPrimitive();\n"
- " }\n"
- "}\n" :
- "";
-
- const char* prefix = geo_program.empty() ? "f" : "v";
- const char* depth_layer = g_ActiveConfig.bStereoEFBMonoDepth ? "0.0" : "f_uv0.z";
+ std::string geo_program = "";
+ char prefix = 'f';
+ if (g_ActiveConfig.stereo_mode != StereoMode::Off)
+ {
+ geo_program = geometry_program;
+ prefix = 'v';
+ }
if (!ProgramShaderCache::CompileShader(m_colorCopyProgram,
StringFromFormat(vertex_program, prefix, prefix),
- color_copy_program, geo_program) ||
- !ProgramShaderCache::CompileShader(m_colorMatrixProgram,
- StringFromFormat(vertex_program, prefix, prefix),
- color_matrix_program, geo_program) ||
- !ProgramShaderCache::CompileShader(
- m_depthMatrixProgram, StringFromFormat(vertex_program, prefix, prefix),
- StringFromFormat(depth_matrix_program, depth_layer), geo_program))
+ color_copy_program, geo_program))
{
return false;
}
- m_colorMatrixUniform = glGetUniformLocation(m_colorMatrixProgram.glprogid, "colmat");
- m_depthMatrixUniform = glGetUniformLocation(m_depthMatrixProgram.glprogid, "colmat");
- m_color_cbuf_id = UINT_MAX;
- m_depth_cbuf_id = UINT_MAX;
-
m_colorCopyPositionUniform = glGetUniformLocation(m_colorCopyProgram.glprogid, "copy_position");
- m_colorMatrixPositionUniform =
- glGetUniformLocation(m_colorMatrixProgram.glprogid, "copy_position");
- m_depthCopyPositionUniform = glGetUniformLocation(m_depthMatrixProgram.glprogid, "copy_position");
std::string palette_shader =
R"GLSL(
@@ -320,8 +274,9 @@ bool TextureCache::CompileShaders()
void TextureCache::DeleteShaders()
{
- m_colorMatrixProgram.Destroy();
- m_depthMatrixProgram.Destroy();
+ for (auto& it : m_efb_copy_programs)
+ it.second.shader.Destroy();
+ m_efb_copy_programs.clear();
if (g_ActiveConfig.backend_info.bSupportsPaletteConversion)
for (auto& shader : m_palette_shaders)
@@ -531,7 +486,8 @@ void TextureCache::DecodeTextureOnGPU(TCacheEntry* entry, u32 dst_level, const u
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)
{
auto* destination_texture = static_cast<OGLTexture*>(entry->texture.get());
g_renderer->ResetAPIState(); // reset any game specific settings
@@ -554,26 +510,35 @@ void TextureCache::CopyEFBToCacheEntry(TCacheEntry* entry, bool is_depth_copy,
glViewport(0, 0, destination_texture->GetConfig().width, destination_texture->GetConfig().height);
- GLuint uniform_location;
- if (is_depth_copy)
- {
- m_depthMatrixProgram.Bind();
- if (m_depth_cbuf_id != cbuf_id)
- glUniform4fv(m_depthMatrixUniform, 5, colmat);
- m_depth_cbuf_id = cbuf_id;
- uniform_location = m_depthCopyPositionUniform;
- }
- else
+ auto uid = GetTextureConverterShaderUid(dst_format, is_depth_copy, is_intensity, scale_by_half);
+
+ auto it = m_efb_copy_programs.emplace(uid, EFBCopyShader());
+ EFBCopyShader& shader = it.first->second;
+ bool created = it.second;
+
+ if (created)
{
- m_colorMatrixProgram.Bind();
- if (m_color_cbuf_id != cbuf_id)
- glUniform4fv(m_colorMatrixUniform, 7, colmat);
- m_color_cbuf_id = cbuf_id;
- uniform_location = m_colorMatrixPositionUniform;
+ ShaderCode code = GenerateTextureConverterShaderCode(APIType::OpenGL, uid.GetUidData());
+
+ std::string geo_program = "";
+ char prefix = 'f';
+ if (g_ActiveConfig.stereo_mode != StereoMode::Off)
+ {
+ geo_program = geometry_program;
+ prefix = 'v';
+ }
+
+ ProgramShaderCache::CompileShader(shader.shader,
+ StringFromFormat(vertex_program, prefix, prefix),
+ code.GetBuffer(), geo_program);
+
+ shader.position_uniform = glGetUniformLocation(shader.shader.glprogid, "copy_position");
}
+ shader.shader.Bind();
+
TargetRectangle R = g_renderer->ConvertEFBRectangle(src_rect);
- glUniform4f(uniform_location, static_cast<float>(R.left), static_cast<float>(R.top),
+ glUniform4f(shader.position_uniform, static_cast<float>(R.left), static_cast<float>(R.top),
static_cast<float>(R.right), static_cast<float>(R.bottom));
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);