diff --git a/src/frontend-common/d3d11_host_display.cpp b/src/frontend-common/d3d11_host_display.cpp index d33dc8ff9..7ef7b8651 100644 --- a/src/frontend-common/d3d11_host_display.cpp +++ b/src/frontend-common/d3d11_host_display.cpp @@ -96,7 +96,8 @@ void D3D11HostDisplay::EndTextureUpdate(GPUTexture* texture, u32 x, u32 y, u32 w m_context->Unmap(tex->GetD3DTexture(), 0); } -bool D3D11HostDisplay::UpdateTexture(GPUTexture* texture, u32 x, u32 y, u32 width, u32 height, const void* data, u32 pitch) +bool D3D11HostDisplay::UpdateTexture(GPUTexture* texture, u32 x, u32 y, u32 width, u32 height, const void* data, + u32 pitch) { D3D11::Texture* tex = static_cast(texture); if (tex->IsDynamic()) @@ -1007,6 +1008,7 @@ bool D3D11HostDisplay::SetPostProcessingChain(const std::string_view& config) return false; } + m_post_processing_timer.Reset(); return true; } @@ -1061,6 +1063,8 @@ void D3D11HostDisplay::ApplyPostProcessingChain(ID3D11RenderTargetView* final_ta RenderDisplay(final_left, final_top, final_width, final_height, texture, texture_view_x, texture_view_y, texture_view_width, texture_view_height, IsUsingLinearFiltering()); + const s32 orig_texture_width = texture_view_width; + const s32 orig_texture_height = texture_view_height; texture = &m_post_processing_input_texture; texture_view_x = final_left; texture_view_y = final_top; @@ -1091,7 +1095,8 @@ void D3D11HostDisplay::ApplyPostProcessingChain(ID3D11RenderTargetView* final_ta m_display_uniform_buffer.Map(m_context.Get(), m_display_uniform_buffer.GetSize(), pps.uniforms_size); m_post_processing_chain.GetShaderStage(i).FillUniformBuffer( map.pointer, texture->GetWidth(), texture->GetHeight(), texture_view_x, texture_view_y, texture_view_width, - texture_view_height, GetWindowWidth(), GetWindowHeight(), 0.0f); + texture_view_height, GetWindowWidth(), GetWindowHeight(), orig_texture_width, orig_texture_height, + static_cast(m_post_processing_timer.GetTimeSeconds())); m_display_uniform_buffer.Unmap(m_context.Get(), pps.uniforms_size); m_context->VSSetConstantBuffers(0, 1, m_display_uniform_buffer.GetD3DBufferArray()); m_context->PSSetConstantBuffers(0, 1, m_display_uniform_buffer.GetD3DBufferArray()); diff --git a/src/frontend-common/d3d11_host_display.h b/src/frontend-common/d3d11_host_display.h index 79a885baf..350636c8f 100644 --- a/src/frontend-common/d3d11_host_display.h +++ b/src/frontend-common/d3d11_host_display.h @@ -1,6 +1,7 @@ #pragma once #include "common/d3d11/stream_buffer.h" #include "common/d3d11/texture.h" +#include "common/timer.h" #include "common/window_info.h" #include "common/windows_headers.h" #include "core/host_display.h" @@ -146,6 +147,7 @@ protected: FrontendCommon::PostProcessingChain m_post_processing_chain; D3D11::Texture m_post_processing_input_texture; std::vector m_post_processing_stages; + Common::Timer m_post_processing_timer; std::array, 3>, NUM_TIMESTAMP_QUERIES> m_timestamp_queries = {}; u8 m_read_timestamp_query = 0; diff --git a/src/frontend-common/opengl_host_display.cpp b/src/frontend-common/opengl_host_display.cpp index 4daad42d7..6e7629cee 100644 --- a/src/frontend-common/opengl_host_display.cpp +++ b/src/frontend-common/opengl_host_display.cpp @@ -929,6 +929,8 @@ void OpenGLHostDisplay::ApplyPostProcessingChain(GLuint final_target, s32 final_ RenderDisplay(final_left, target_height - final_top - final_height, final_width, final_height, texture, texture_view_x, texture_view_y, texture_view_width, texture_view_height, IsUsingLinearFiltering()); + const s32 orig_texture_width = texture_view_width; + const s32 orig_texture_height = texture_view_height; texture = &m_post_processing_input_texture; texture_view_x = final_left; texture_view_y = final_top; @@ -959,7 +961,8 @@ void OpenGLHostDisplay::ApplyPostProcessingChain(GLuint final_target, s32 final_ const auto map_result = m_post_processing_ubo->Map(m_uniform_buffer_alignment, pps.uniforms_size); m_post_processing_chain.GetShaderStage(i).FillUniformBuffer( map_result.pointer, texture->GetWidth(), texture->GetHeight(), texture_view_x, texture_view_y, texture_view_width, - texture_view_height, GetWindowWidth(), GetWindowHeight(), 0.0f); + texture_view_height, GetWindowWidth(), GetWindowHeight(), orig_texture_width, orig_texture_height, + static_cast(m_post_processing_timer.GetTimeSeconds())); m_post_processing_ubo->Unmap(pps.uniforms_size); glBindBufferRange(GL_UNIFORM_BUFFER, 1, m_post_processing_ubo->GetGLBufferId(), map_result.buffer_offset, pps.uniforms_size); diff --git a/src/frontend-common/opengl_host_display.h b/src/frontend-common/opengl_host_display.h index 303d30565..0f42c513e 100644 --- a/src/frontend-common/opengl_host_display.h +++ b/src/frontend-common/opengl_host_display.h @@ -4,6 +4,7 @@ #include "common/gl/program.h" #include "common/gl/stream_buffer.h" #include "common/gl/texture.h" +#include "common/timer.h" #include "common/window_info.h" #include "core/host_display.h" #include "postprocessing_chain.h" @@ -121,6 +122,7 @@ protected: GL::Texture m_post_processing_input_texture; std::unique_ptr m_post_processing_ubo; std::vector m_post_processing_stages; + Common::Timer m_post_processing_timer; std::array m_timestamp_queries = {}; float m_accumulated_gpu_time = 0.0f; diff --git a/src/frontend-common/postprocessing_shader.cpp b/src/frontend-common/postprocessing_shader.cpp index 1c6479cf7..abdc5f9a4 100644 --- a/src/frontend-common/postprocessing_shader.cpp +++ b/src/frontend-common/postprocessing_shader.cpp @@ -248,11 +248,11 @@ u32 PostProcessingShader::GetUniformsSize() const void PostProcessingShader::FillUniformBuffer(void* buffer, u32 texture_width, s32 texture_height, s32 texture_view_x, s32 texture_view_y, s32 texture_view_width, s32 texture_view_height, - u32 window_width, u32 window_height, float time) const + u32 window_width, u32 window_height, s32 original_width, + s32 original_height, float time) const { CommonUniforms* common = static_cast(buffer); - // TODO: OpenGL? const float rcp_texture_width = 1.0f / static_cast(texture_width); const float rcp_texture_height = 1.0f / static_cast(texture_height); common->src_rect[0] = static_cast(texture_view_x) * rcp_texture_width; @@ -269,6 +269,17 @@ void PostProcessingShader::FillUniformBuffer(void* buffer, u32 texture_width, s3 common->window_resolution[1] = static_cast(window_height); common->rcp_window_resolution[0] = 1.0f / static_cast(window_width); common->rcp_window_resolution[1] = 1.0f / static_cast(window_height); + + // pad the "original size" relative to the positioning on the screen + const float view_scale_x = static_cast(original_width) / static_cast(texture_view_width); + const float view_scale_y = static_cast(original_height) / static_cast(texture_view_height); + const s32 view_pad_x = texture_view_x + (texture_width - texture_view_width - texture_view_x); + const s32 view_pad_y = texture_view_y + (texture_height - texture_view_height - texture_view_y); + common->original_size[0] = static_cast(original_width); + common->original_size[1] = static_cast(original_height); + common->padded_original_size[0] = common->original_size[0] + static_cast(view_pad_x) * view_scale_x; + common->padded_original_size[1] = common->original_size[1] + static_cast(view_pad_y) * view_scale_y; + common->time = time; u8* option_values = reinterpret_cast(common + 1); diff --git a/src/frontend-common/postprocessing_shader.h b/src/frontend-common/postprocessing_shader.h index 8dffb6cee..599cfb41c 100644 --- a/src/frontend-common/postprocessing_shader.h +++ b/src/frontend-common/postprocessing_shader.h @@ -83,7 +83,7 @@ public: u32 GetUniformsSize() const; void FillUniformBuffer(void* buffer, u32 texture_width, s32 texture_height, s32 texture_view_x, s32 texture_view_y, s32 texture_view_width, s32 texture_view_height, u32 window_width, u32 window_height, - float time) const; + s32 original_width, s32 original_height, float time) const; private: struct CommonUniforms @@ -94,8 +94,10 @@ private: float rcp_resolution[2]; float window_resolution[2]; float rcp_window_resolution[2]; + float original_size[2]; + float padded_original_size[2]; float time; - float padding[1]; + float padding; }; void LoadOptions(); diff --git a/src/frontend-common/postprocessing_shadergen.cpp b/src/frontend-common/postprocessing_shadergen.cpp index 0eb418f58..0671b73e6 100644 --- a/src/frontend-common/postprocessing_shadergen.cpp +++ b/src/frontend-common/postprocessing_shadergen.cpp @@ -106,6 +106,14 @@ float2 GetCoordinates() { return v_tex0; } +float2 GetOriginalSize() +{ + return original_size; +} +float2 GetPaddedOriginalSize() +{ + return padded_original_size; +} float GetTime() { return time; @@ -150,6 +158,8 @@ void PostProcessingShaderGen::WriteUniformBuffer(std::stringstream& ss, const Po ss << " float2 rcp_resolution;\n"; ss << " float2 window_resolution;\n"; ss << " float2 rcp_window_resolution;\n"; + ss << " float2 original_size;\n"; + ss << " float2 padded_original_size;\n"; ss << " float time;\n"; ss << " float ubo_pad" << (pad_counter++) << ";\n"; ss << "\n"; diff --git a/src/frontend-common/vulkan_host_display.cpp b/src/frontend-common/vulkan_host_display.cpp index 93dada004..21bbeea45 100644 --- a/src/frontend-common/vulkan_host_display.cpp +++ b/src/frontend-common/vulkan_host_display.cpp @@ -1113,6 +1113,8 @@ void VulkanHostDisplay::ApplyPostProcessingChain(VkFramebuffer target_fb, s32 fi Vulkan::Util::EndDebugScope(g_vulkan_context->GetCurrentCommandBuffer()); m_post_processing_input_texture.TransitionToLayout(cmdbuffer, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + const s32 orig_texture_width = texture_view_width; + const s32 orig_texture_height = texture_view_height; texture = &m_post_processing_input_texture; texture_view_x = final_left; texture_view_y = final_top; @@ -1154,7 +1156,8 @@ void VulkanHostDisplay::ApplyPostProcessingChain(VkFramebuffer target_fb, s32 fi Assert(pps.uniforms_size <= sizeof(buffer)); m_post_processing_chain.GetShaderStage(i).FillUniformBuffer( buffer, texture->GetWidth(), texture->GetHeight(), texture_view_x, texture_view_y, texture_view_width, - texture_view_height, GetWindowWidth(), GetWindowHeight(), 0.0f); + texture_view_height, GetWindowWidth(), GetWindowHeight(), orig_texture_width, orig_texture_height, + static_cast(m_post_processing_timer.GetTimeSeconds())); vkCmdPushConstants(cmdbuffer, m_post_process_pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, pps.uniforms_size, buffer); @@ -1174,7 +1177,8 @@ void VulkanHostDisplay::ApplyPostProcessingChain(VkFramebuffer target_fb, s32 fi const u32 offset = m_post_processing_ubo.GetCurrentOffset(); m_post_processing_chain.GetShaderStage(i).FillUniformBuffer( m_post_processing_ubo.GetCurrentHostPointer(), texture->GetWidth(), texture->GetHeight(), texture_view_x, - texture_view_y, texture_view_width, texture_view_height, GetWindowWidth(), GetWindowHeight(), 0.0f); + texture_view_y, texture_view_width, texture_view_height, GetWindowWidth(), GetWindowHeight(), + orig_texture_width, orig_texture_height, static_cast(m_post_processing_timer.GetTimeSeconds())); m_post_processing_ubo.CommitMemory(pps.uniforms_size); dsupdate.AddBufferDescriptorWrite(ds, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, diff --git a/src/frontend-common/vulkan_host_display.h b/src/frontend-common/vulkan_host_display.h index 1ed68646c..ada24886c 100644 --- a/src/frontend-common/vulkan_host_display.h +++ b/src/frontend-common/vulkan_host_display.h @@ -1,4 +1,5 @@ #pragma once +#include "common/timer.h" #include "common/vulkan/loader.h" #include "common/vulkan/stream_buffer.h" #include "common/vulkan/swap_chain.h" @@ -137,4 +138,5 @@ protected: VkFramebuffer m_post_processing_input_framebuffer = VK_NULL_HANDLE; Vulkan::StreamBuffer m_post_processing_ubo; std::vector m_post_processing_stages; + Common::Timer m_post_processing_timer; };