diff options
| author | Stenzek <stenzek@gmail.com> | 2018-04-29 18:52:30 +1000 |
|---|---|---|
| committer | Stenzek <stenzek@gmail.com> | 2018-04-29 19:05:20 +1000 |
| commit | 9e798eec94a8ebe94c1ef8270b504b5698b2a0f5 (patch) | |
| tree | 4265b19082fd65555dd795703e09abb94811c65a /Source/Core/VideoBackends/Vulkan/TextureCache.cpp | |
| parent | a192a3bb3043c921ec897186c2a927b33050dffc (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/Vulkan/TextureCache.cpp')
| -rw-r--r-- | Source/Core/VideoBackends/Vulkan/TextureCache.cpp | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/Source/Core/VideoBackends/Vulkan/TextureCache.cpp b/Source/Core/VideoBackends/Vulkan/TextureCache.cpp index cb61cd4de4..bc7a0d0f18 100644 --- a/Source/Core/VideoBackends/Vulkan/TextureCache.cpp +++ b/Source/Core/VideoBackends/Vulkan/TextureCache.cpp @@ -100,7 +100,9 @@ void TextureCache::ConvertTexture(TCacheEntry* destination, TCacheEntry* source, 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) { // Flush EFB pokes first, as they're expected to be included. FramebufferManager::GetInstance()->FlushEFBPokes(); @@ -131,9 +133,9 @@ void TextureCache::CopyEFB(u8* dst, const EFBCopyParams& params, u32 native_widt src_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); - m_texture_converter->EncodeTextureToMemory(src_texture->GetView(), dst, params, native_width, - bytes_per_row, num_blocks_y, memory_stride, src_rect, - scale_by_half); + m_texture_converter->EncodeTextureToMemory( + src_texture->GetView(), dst, params, native_width, bytes_per_row, num_blocks_y, memory_stride, + src_rect, scale_by_half, y_scale, gamma, clamp_top, clamp_bottom, filter_coefficients); // Transition back to original state src_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(), original_layout); @@ -209,7 +211,9 @@ void TextureCache::DeleteShaders() 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) { VKTexture* texture = static_cast<VKTexture*>(entry->texture.get()); @@ -228,6 +232,26 @@ void TextureCache::CopyEFBToCacheEntry(TCacheEntry* entry, bool is_depth_copy, VkCommandBuffer command_buffer = g_command_buffer_mgr->GetCurrentCommandBuffer(); StateTracker::GetInstance()->EndRenderPass(); + // Fill uniform buffer. + struct PixelUniforms + { + float filter_coefficients[3]; + float gamma_rcp; + float clamp_top; + float clamp_bottom; + float pixel_height; + u32 padding; + }; + PixelUniforms uniforms; + for (size_t i = 0; i < filter_coefficients.size(); i++) + uniforms.filter_coefficients[i] = filter_coefficients[i] / 64.0f; + uniforms.gamma_rcp = 1.0f / gamma; + uniforms.clamp_top = clamp_top ? src_rect.top / float(EFB_HEIGHT) : 0.0f; + uniforms.clamp_bottom = clamp_bottom ? src_rect.bottom / float(EFB_HEIGHT) : 1.0f; + uniforms.pixel_height = + g_ActiveConfig.bCopyEFBScaled ? 1.0f / g_renderer->GetTargetHeight() : 1.0f / EFB_HEIGHT; + uniforms.padding = 0; + // Transition EFB to shader resource before binding. // An out-of-bounds source region is valid here, and fine for the draw (since it is converted // to texture coordinates), but it's not valid to resolve an out-of-range rectangle. @@ -274,6 +298,10 @@ void TextureCache::CopyEFBToCacheEntry(TCacheEntry* entry, bool is_depth_copy, g_shader_cache->GetPassthroughVertexShader(), g_shader_cache->GetPassthroughGeometryShader(), shader); + u8* ubo_ptr = draw.AllocatePSUniforms(sizeof(PixelUniforms)); + std::memcpy(ubo_ptr, &uniforms, sizeof(PixelUniforms)); + draw.CommitPSUniforms(sizeof(PixelUniforms)); + draw.SetPSSampler(0, src_texture->GetView(), src_sampler); VkRect2D dest_region = {{0, 0}, {texture->GetConfig().width, texture->GetConfig().height}}; |
