summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/OGL/TextureCache.cpp
diff options
context:
space:
mode:
authorMarkus Wick <markus@selfnet.de>2017-08-04 17:56:24 +0200
committerdegasus <wickmarkus@web.de>2017-12-02 15:17:39 +0100
commit491c10ec96e4cb58724f0768a76e0cece63f2b07 (patch)
tree2bfcf3ff639a9f33fe3f22aa40aa4d443623f65a /Source/Core/VideoBackends/OGL/TextureCache.cpp
parent2b2941d0c9274ea04a2f6c5f816f2bf804d25407 (diff)
VideoBackends: Use VideoCommon shader generators for efb2tex copies.
This will generate one shader per copy format. For now, it is the same shader with the colmat hard coded. So it should already improve the GPU performance a bit, but a rewrite of the shader generator is suggested. Half of the patch is done by linkmauve1: VideoCommon: Reorganise the shader writes.
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);