diff options
Diffstat (limited to 'Source/Core/VideoBackends/OGL/TextureCache.cpp')
| -rw-r--r-- | Source/Core/VideoBackends/OGL/TextureCache.cpp | 177 |
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); |
