summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/OGL/TextureCache.cpp
diff options
context:
space:
mode:
authorStenzek <stenzek@gmail.com>2018-04-29 18:52:30 +1000
committerStenzek <stenzek@gmail.com>2018-04-29 19:05:20 +1000
commit9e798eec94a8ebe94c1ef8270b504b5698b2a0f5 (patch)
tree4265b19082fd65555dd795703e09abb94811c65a /Source/Core/VideoBackends/OGL/TextureCache.cpp
parenta192a3bb3043c921ec897186c2a927b33050dffc (diff)
Implement EFB copy filter and gamma in hardware backends
Also makes y_scale a dynamic parameter for EFB copies, as it doesn't make sense to keep it as part of the uid, otherwise we're generating redundant shaders.
Diffstat (limited to 'Source/Core/VideoBackends/OGL/TextureCache.cpp')
-rw-r--r--Source/Core/VideoBackends/OGL/TextureCache.cpp30
1 files changed, 27 insertions, 3 deletions
diff --git a/Source/Core/VideoBackends/OGL/TextureCache.cpp b/Source/Core/VideoBackends/OGL/TextureCache.cpp
index 24f94e39db..086d0f29f2 100644
--- a/Source/Core/VideoBackends/OGL/TextureCache.cpp
+++ b/Source/Core/VideoBackends/OGL/TextureCache.cpp
@@ -68,10 +68,18 @@ constexpr const char* geometry_program = "layout(triangles) in;\n"
void TextureCache::CopyEFB(u8* dst, const EFBCopyParams& params, u32 native_width,
u32 bytes_per_row, u32 num_blocks_y, u32 memory_stride,
- const EFBRectangle& src_rect, bool scale_by_half)
+ const EFBRectangle& src_rect, bool scale_by_half, float y_scale,
+ float gamma, bool clamp_top, bool clamp_bottom,
+ const CopyFilterCoefficientArray& filter_coefficients)
{
+ // Flip top/bottom due to lower-left coordinate system.
+ float clamp_top_val =
+ clamp_bottom ? (1.0f - src_rect.bottom / static_cast<float>(EFB_HEIGHT)) : 0.0f;
+ float clamp_bottom_val =
+ clamp_top ? (1.0f - src_rect.top / static_cast<float>(EFB_HEIGHT)) : 0.0f;
TextureConverter::EncodeToRamFromTexture(dst, params, native_width, bytes_per_row, num_blocks_y,
- memory_stride, src_rect, scale_by_half);
+ memory_stride, src_rect, scale_by_half, y_scale, gamma,
+ clamp_top_val, clamp_bottom_val, filter_coefficients);
}
TextureCache::TextureCache()
@@ -483,7 +491,9 @@ 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,
- EFBCopyFormat dst_format, bool is_intensity)
+ EFBCopyFormat dst_format, bool is_intensity, float gamma,
+ bool clamp_top, bool clamp_bottom,
+ const CopyFilterCoefficientArray& filter_coefficients)
{
auto* destination_texture = static_cast<OGLTexture*>(entry->texture.get());
g_renderer->ResetAPIState(); // reset any game specific settings
@@ -528,6 +538,11 @@ void TextureCache::CopyEFBToCacheEntry(TCacheEntry* entry, bool is_depth_copy,
code.GetBuffer(), geo_program);
shader.position_uniform = glGetUniformLocation(shader.shader.glprogid, "copy_position");
+ shader.pixel_height_uniform = glGetUniformLocation(shader.shader.glprogid, "pixel_height");
+ shader.gamma_rcp_uniform = glGetUniformLocation(shader.shader.glprogid, "gamma_rcp");
+ shader.clamp_tb_uniform = glGetUniformLocation(shader.shader.glprogid, "clamp_tb");
+ shader.filter_coefficients_uniform =
+ glGetUniformLocation(shader.shader.glprogid, "filter_coefficients");
}
shader.shader.Bind();
@@ -535,6 +550,15 @@ void TextureCache::CopyEFBToCacheEntry(TCacheEntry* entry, bool is_depth_copy,
TargetRectangle R = g_renderer->ConvertEFBRectangle(src_rect);
glUniform4f(shader.position_uniform, static_cast<float>(R.left), static_cast<float>(R.top),
static_cast<float>(R.right), static_cast<float>(R.bottom));
+ glUniform1f(shader.pixel_height_uniform, g_ActiveConfig.bCopyEFBScaled ?
+ 1.0f / g_renderer->GetTargetHeight() :
+ 1.0f / EFB_HEIGHT);
+ glUniform1f(shader.gamma_rcp_uniform, 1.0f / gamma);
+ glUniform2f(shader.clamp_tb_uniform,
+ clamp_bottom ? (1.0f - src_rect.bottom / static_cast<float>(EFB_HEIGHT)) : 0.0f,
+ clamp_top ? (1.0f - src_rect.top / static_cast<float>(EFB_HEIGHT)) : 0.0f);
+ glUniform3f(shader.filter_coefficients_uniform, filter_coefficients[0] / 64.0f,
+ filter_coefficients[1] / 64.0f, filter_coefficients[2] / 64.0f);
ProgramShaderCache::BindVertexFormat(nullptr);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);