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.cpp116
1 files changed, 74 insertions, 42 deletions
diff --git a/Source/Core/VideoBackends/OGL/TextureCache.cpp b/Source/Core/VideoBackends/OGL/TextureCache.cpp
index 5f14704cae..66f633c6e3 100644
--- a/Source/Core/VideoBackends/OGL/TextureCache.cpp
+++ b/Source/Core/VideoBackends/OGL/TextureCache.cpp
@@ -98,14 +98,14 @@ void TextureCache::TCacheEntry::Bind(unsigned int stage)
s_ActiveTexture = stage;
}
- glBindTexture(GL_TEXTURE_2D, texture);
+ glBindTexture(GL_TEXTURE_2D_ARRAY, texture);
s_Textures[stage] = texture;
}
}
bool TextureCache::TCacheEntry::Save(const std::string& filename, unsigned int level)
{
- return SaveTexture(filename, GL_TEXTURE_2D, texture, virtual_width, virtual_height, level);
+ return SaveTexture(filename, GL_TEXTURE_2D_ARRAY, texture, virtual_width, virtual_height, level);
}
TextureCache::TCacheEntryBase* TextureCache::CreateTexture(unsigned int width,
@@ -172,8 +172,8 @@ TextureCache::TCacheEntryBase* TextureCache::CreateTexture(unsigned int width,
entry.pcfmt = pcfmt;
glActiveTexture(GL_TEXTURE0+9);
- glBindTexture(GL_TEXTURE_2D, entry.texture);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, tex_levels - 1);
+ glBindTexture(GL_TEXTURE_2D_ARRAY, entry.texture);
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, tex_levels - 1);
entry.Load(width, height, expanded_width, 0);
@@ -189,12 +189,12 @@ void TextureCache::TCacheEntry::Load(unsigned int width, unsigned int height,
if (pcfmt != PC_TEX_FMT_DXT1)
{
glActiveTexture(GL_TEXTURE0+9);
- glBindTexture(GL_TEXTURE_2D, texture);
+ glBindTexture(GL_TEXTURE_2D_ARRAY, texture);
if (expanded_width != width)
glPixelStorei(GL_UNPACK_ROW_LENGTH, expanded_width);
- glTexImage2D(GL_TEXTURE_2D, level, gl_iformat, width, height, 0, gl_format, gl_type, temp);
+ glTexImage3D(GL_TEXTURE_2D_ARRAY, level, gl_iformat, width, height, 1, 0, gl_format, gl_type, temp);
if (expanded_width != width)
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
@@ -213,21 +213,20 @@ TextureCache::TCacheEntryBase* TextureCache::CreateRenderTargetTexture(
{
TCacheEntry *const entry = new TCacheEntry;
glActiveTexture(GL_TEXTURE0+9);
- glBindTexture(GL_TEXTURE_2D, entry->texture);
+ glBindTexture(GL_TEXTURE_2D_ARRAY, entry->texture);
const GLenum
gl_format = GL_RGBA,
gl_iformat = GL_RGBA,
gl_type = GL_UNSIGNED_BYTE;
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
-
- glTexImage2D(GL_TEXTURE_2D, 0, gl_iformat, scaled_tex_w, scaled_tex_h, 0, gl_format, gl_type, nullptr);
- glBindTexture(GL_TEXTURE_2D, 0);
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 0);
+ glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, gl_iformat, scaled_tex_w, scaled_tex_h, FramebufferManager::GetEFBLayers(), 0, gl_format, gl_type, nullptr);
+ glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
glGenFramebuffers(1, &entry->framebuffer);
FramebufferManager::SetFramebuffer(entry->framebuffer);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, entry->texture, 0);
+ glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, entry->texture, 0);
SetStage();
@@ -251,7 +250,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
FramebufferManager::SetFramebuffer(framebuffer);
glActiveTexture(GL_TEXTURE0+9);
- glBindTexture(GL_TEXTURE_2D, read_texture);
+ glBindTexture(GL_TEXTURE_2D_ARRAY, read_texture);
glViewport(0, 0, virtual_width, virtual_height);
@@ -309,7 +308,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
{
static int count = 0;
SaveTexture(StringFromFormat("%sefb_frame_%i.png", File::GetUserPath(D_DUMPTEXTURES_IDX).c_str(),
- count++), GL_TEXTURE_2D, texture, virtual_width, virtual_height, 0);
+ count++), GL_TEXTURE_2D_ARRAY, texture, virtual_width, virtual_height, 0);
}
g_renderer->RestoreAPIState();
@@ -317,26 +316,52 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
TextureCache::TextureCache()
{
+ CompileShaders();
+
+ s_ActiveTexture = -1;
+ for (auto& gtex : s_Textures)
+ gtex = -1;
+}
+
+
+TextureCache::~TextureCache()
+{
+ DeleteShaders();
+}
+
+void TextureCache::DisableStage(unsigned int stage)
+{
+}
+
+void TextureCache::SetStage()
+{
+ // -1 is the initial value as we don't know which texture should be bound
+ if (s_ActiveTexture != (u32)-1)
+ glActiveTexture(GL_TEXTURE0 + s_ActiveTexture);
+}
+
+void TextureCache::CompileShaders()
+{
const char *pColorMatrixProg =
- "SAMPLER_BINDING(9) uniform sampler2D samp9;\n"
+ "SAMPLER_BINDING(9) uniform sampler2DArray samp9;\n"
"uniform vec4 colmat[7];\n"
- "in vec2 uv0;\n"
+ "in vec3 f_uv0;\n"
"out vec4 ocol0;\n"
"\n"
"void main(){\n"
- " vec4 texcol = texture(samp9, uv0);\n"
+ " vec4 texcol = texture(samp9, f_uv0);\n"
" texcol = round(texcol * colmat[5]) * colmat[6];\n"
" ocol0 = texcol * mat4(colmat[0], colmat[1], colmat[2], colmat[3]) + colmat[4];\n"
"}\n";
const char *pDepthMatrixProg =
- "SAMPLER_BINDING(9) uniform sampler2D samp9;\n"
+ "SAMPLER_BINDING(9) uniform sampler2DArray samp9;\n"
"uniform vec4 colmat[5];\n"
- "in vec2 uv0;\n"
+ "in vec3 f_uv0;\n"
"out vec4 ocol0;\n"
"\n"
"void main(){\n"
- " vec4 texcol = texture(samp9, uv0);\n"
+ " vec4 texcol = texture(samp9, vec3(f_uv0.xy, %s));\n"
// 255.99998474121 = 16777215/16777216*256
" float workspace = texcol.x * 255.99998474121;\n"
@@ -363,18 +388,41 @@ TextureCache::TextureCache()
"}\n";
const char *VProgram =
- "out vec2 uv0;\n"
- "SAMPLER_BINDING(9) uniform sampler2D samp9;\n"
+ "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"
- " uv0 = mix(copy_position.xy, copy_position.zw, rawpos) / vec2(textureSize(samp9, 0));\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";
- ProgramShaderCache::CompileShader(s_ColorMatrixProgram, VProgram, pColorMatrixProg);
- ProgramShaderCache::CompileShader(s_DepthMatrixProgram, VProgram, pDepthMatrixProg);
+ const char *GProgram = (g_ActiveConfig.iStereoMode > 0) ?
+ "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" : nullptr;
+
+ const char* prefix = (GProgram == nullptr) ? "f" : "v";
+ const char* depth_layer = (g_ActiveConfig.bStereoMonoEFBDepth) ? "0" : "f_uv0.z";
+
+ ProgramShaderCache::CompileShader(s_ColorMatrixProgram, StringFromFormat(VProgram, prefix, prefix).c_str(), pColorMatrixProg, GProgram);
+ ProgramShaderCache::CompileShader(s_DepthMatrixProgram, StringFromFormat(VProgram, prefix, prefix).c_str(), StringFromFormat(pDepthMatrixProg, depth_layer).c_str(), GProgram);
s_ColorMatrixUniform = glGetUniformLocation(s_ColorMatrixProgram.glprogid, "colmat");
s_DepthMatrixUniform = glGetUniformLocation(s_DepthMatrixProgram.glprogid, "colmat");
@@ -383,28 +431,12 @@ TextureCache::TextureCache()
s_ColorCopyPositionUniform = glGetUniformLocation(s_ColorMatrixProgram.glprogid, "copy_position");
s_DepthCopyPositionUniform = glGetUniformLocation(s_DepthMatrixProgram.glprogid, "copy_position");
-
- s_ActiveTexture = -1;
- for (auto& gtex : s_Textures)
- gtex = -1;
}
-
-TextureCache::~TextureCache()
+void TextureCache::DeleteShaders()
{
s_ColorMatrixProgram.Destroy();
s_DepthMatrixProgram.Destroy();
}
-void TextureCache::DisableStage(unsigned int stage)
-{
-}
-
-void TextureCache::SetStage ()
-{
- // -1 is the initial value as we don't know which texture should be bound
- if (s_ActiveTexture != (u32)-1)
- glActiveTexture(GL_TEXTURE0 + s_ActiveTexture);
-}
-
}