diff --git a/GPU/Common/FramebufferCommon.cpp b/GPU/Common/FramebufferCommon.cpp index 52be6bce2d..8d3b0d42c4 100644 --- a/GPU/Common/FramebufferCommon.cpp +++ b/GPU/Common/FramebufferCommon.cpp @@ -791,10 +791,9 @@ void FramebufferManagerCommon::DrawFramebufferToOutput(const u8 *srcPixels, GEBu flags |= OutputFlags::POSITION_FLIPPED; } - PostShaderUniforms uniforms{}; - presentation_->CalculatePostShaderUniforms(512, 272, textureCache_->VideoIsPlaying(), &uniforms); - presentation_->SourceTexture(pixelsTex); - presentation_->CopyToOutput(flags, uvRotation, u0, v0, u1, v1, uniforms); + presentation_->UpdateUniforms(textureCache_->VideoIsPlaying()); + presentation_->SourceTexture(pixelsTex, 512, 272); + presentation_->CopyToOutput(flags, uvRotation, u0, v0, u1, v1); pixelsTex->Release(); // PresentationCommon sets all kinds of state, we can't rely on anything. @@ -954,12 +953,11 @@ void FramebufferManagerCommon::CopyDisplayToOutput(bool reallyDirty) { flags |= OutputFlags::POSITION_FLIPPED; } - PostShaderUniforms uniforms{}; int actualWidth = (vfb->bufferWidth * vfb->renderWidth) / vfb->width; int actualHeight = (vfb->bufferHeight * vfb->renderHeight) / vfb->height; - presentation_->CalculatePostShaderUniforms(actualWidth, actualHeight, textureCache_->VideoIsPlaying(), &uniforms); - presentation_->SourceFramebuffer(vfb->fbo); - presentation_->CopyToOutput(flags, uvRotation, u0, v0, u1, v1, uniforms); + presentation_->UpdateUniforms(textureCache_->VideoIsPlaying()); + presentation_->SourceFramebuffer(vfb->fbo, actualWidth, actualHeight); + presentation_->CopyToOutput(flags, uvRotation, u0, v0, u1, v1); } else if (useBufferedRendering_) { WARN_LOG(FRAMEBUF, "Current VFB lacks an FBO: %08x", vfb->fb_address); } diff --git a/GPU/Common/PresentationCommon.cpp b/GPU/Common/PresentationCommon.cpp index f545240ee7..2787ca9604 100644 --- a/GPU/Common/PresentationCommon.cpp +++ b/GPU/Common/PresentationCommon.cpp @@ -139,17 +139,11 @@ void PresentationCommon::GetCardboardSettings(CardboardSettings *cardboardSettin cardboardSettings->screenHeight = cardboardScreenHeight; } -void PresentationCommon::CalculatePostShaderUniforms(int bufferWidth, int bufferHeight, bool hasVideo, PostShaderUniforms *uniforms) { +void PresentationCommon::CalculatePostShaderUniforms(int bufferWidth, int bufferHeight, int targetWidth, int targetHeight, const ShaderInfo *shaderInfo, PostShaderUniforms *uniforms) { float u_delta = 1.0f / bufferWidth; float v_delta = 1.0f / bufferHeight; - float u_pixel_delta = 1.0f / renderWidth_; - float v_pixel_delta = 1.0f / renderHeight_; - if (postShaderAtOutputResolution_) { - float x, y, w, h; - CenterDisplayOutputRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, g_Config.iInternalScreenRotation); - u_pixel_delta = 1.0f / w; - v_pixel_delta = 1.0f / h; - } + float u_pixel_delta = 1.0f / targetWidth; + float v_pixel_delta = 1.0f / targetHeight; int flipCount = __DisplayGetFlipCount(); int vCount = __DisplayGetVCount(); float time[4] = { time_now(), (vCount % 60) * 1.0f / 60.0f, (float)vCount, (float)(flipCount % 60) }; @@ -159,7 +153,7 @@ void PresentationCommon::CalculatePostShaderUniforms(int bufferWidth, int buffer uniforms->pixelDelta[0] = u_pixel_delta; uniforms->pixelDelta[1] = v_pixel_delta; memcpy(uniforms->time, time, 4 * sizeof(float)); - uniforms->video = hasVideo; + uniforms->video = hasVideo_ ? 1.0f : 0.0f; // The shader translator tacks this onto our shaders, if we don't set it they render garbage. uniforms->gl_HalfPixel[0] = u_pixel_delta * 0.5f; @@ -196,7 +190,6 @@ bool PresentationCommon::UpdatePostShader() { } usePostShader_ = true; - postShaderAtOutputResolution_ = shaderInfo->outputResolution; return true; } @@ -443,20 +436,24 @@ Draw::ShaderModule *PresentationCommon::CompileShaderModule(Draw::ShaderStage st return shader; } -void PresentationCommon::SourceTexture(Draw::Texture *texture) { +void PresentationCommon::SourceTexture(Draw::Texture *texture, int bufferWidth, int bufferHeight) { DoRelease(srcTexture_); DoRelease(srcFramebuffer_); texture->AddRef(); srcTexture_ = texture; + srcWidth_ = bufferWidth; + srcHeight_ = bufferHeight; } -void PresentationCommon::SourceFramebuffer(Draw::Framebuffer *fb) { +void PresentationCommon::SourceFramebuffer(Draw::Framebuffer *fb, int bufferWidth, int bufferHeight) { DoRelease(srcTexture_); DoRelease(srcFramebuffer_); fb->AddRef(); srcFramebuffer_ = fb; + srcWidth_ = bufferWidth; + srcHeight_ = bufferHeight; } void PresentationCommon::BindSource() { @@ -469,7 +466,11 @@ void PresentationCommon::BindSource() { } } -void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u0, float v0, float u1, float v1, const PostShaderUniforms &uniforms) { +void PresentationCommon::UpdateUniforms(bool hasVideo) { + hasVideo_ = hasVideo; +} + +void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u0, float v0, float u1, float v1) { // Make sure Direct3D 11 clears state, since we set shaders outside Draw. draw_->BindPipeline(nullptr); @@ -481,6 +482,8 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u const bool usePostShader = usePostShader_ && !(flags & OutputFlags::RB_SWIZZLE); const bool isFinalAtOutputResolution = usePostShader && postShaderFramebuffers_.size() < postShaderPipelines_.size(); bool usePostShaderOutput = false; + int lastWidth = srcWidth_; + int lastHeight = srcHeight_; // These are the output coordinates. float x, y, w, h; @@ -576,11 +579,14 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u BindSource(); } - int fbo_w, fbo_h; - draw_->GetFramebufferDimensions(postShaderFramebuffer, &fbo_w, &fbo_h); - Draw::Viewport viewport{ 0, 0, (float)fbo_w, (float)fbo_h, 0.0f, 1.0f }; + int nextWidth, nextHeight; + draw_->GetFramebufferDimensions(postShaderFramebuffer, &nextWidth, &nextHeight); + Draw::Viewport viewport{ 0, 0, (float)nextWidth, (float)nextHeight, 0.0f, 1.0f }; draw_->SetViewports(1, &viewport); - draw_->SetScissorRect(0, 0, fbo_w, fbo_h); + draw_->SetScissorRect(0, 0, nextWidth, nextHeight); + + PostShaderUniforms uniforms; + CalculatePostShaderUniforms(lastWidth, lastHeight, nextWidth, nextHeight, shaderInfo, &uniforms); draw_->BindPipeline(postShaderPipeline); draw_->UpdateDynamicUniformBuffer(&uniforms, sizeof(uniforms)); @@ -594,6 +600,8 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u draw_->BindIndexBuffer(nullptr, 0); usePostShaderOutput = true; + lastWidth = nextWidth; + lastHeight = nextHeight; if (shaderInfo->isUpscalingFilter) useNearest = true; } @@ -618,6 +626,8 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u } if (isFinalAtOutputResolution) { + PostShaderUniforms uniforms; + CalculatePostShaderUniforms(lastWidth, lastHeight, (int)w, (int)h, &postShaderInfo_.back(), &uniforms); draw_->UpdateDynamicUniformBuffer(&uniforms, sizeof(uniforms)); } else { Draw::VsTexColUB ub{}; diff --git a/GPU/Common/PresentationCommon.h b/GPU/Common/PresentationCommon.h index ec61ad395c..daf9b4e7e2 100644 --- a/GPU/Common/PresentationCommon.h +++ b/GPU/Common/PresentationCommon.h @@ -94,12 +94,10 @@ public: void DeviceLost(); void DeviceRestore(Draw::DrawContext *draw); - void GetCardboardSettings(CardboardSettings *cardboardSettings); - void CalculatePostShaderUniforms(int bufferWidth, int bufferHeight, bool hasVideo, PostShaderUniforms *uniforms); - - void SourceTexture(Draw::Texture *texture); - void SourceFramebuffer(Draw::Framebuffer *fb); - void CopyToOutput(OutputFlags flags, int uvRotation, float u0, float v0, float u1, float v1, const PostShaderUniforms &uniforms); + void UpdateUniforms(bool hasVideo); + void SourceTexture(Draw::Texture *texture, int bufferWidth, int bufferHeight); + void SourceFramebuffer(Draw::Framebuffer *fb, int bufferWidth, int bufferHeight); + void CopyToOutput(OutputFlags flags, int uvRotation, float u0, float v0, float u1, float v1); protected: void CreateDeviceObjects(); @@ -114,6 +112,9 @@ protected: void BindSource(); + void GetCardboardSettings(CardboardSettings *cardboardSettings); + void CalculatePostShaderUniforms(int bufferWidth, int bufferHeight, int targetWidth, int targetHeight, const ShaderInfo *shaderInfo, PostShaderUniforms *uniforms); + Draw::DrawContext *draw_; Draw::Pipeline *texColor_ = nullptr; Draw::Pipeline *texColorRBSwizzle_ = nullptr; @@ -129,6 +130,9 @@ protected: Draw::Texture *srcTexture_ = nullptr; Draw::Framebuffer *srcFramebuffer_ = nullptr; + int srcWidth_ = 0; + int srcHeight_ = 0; + bool hasVideo_ = false; int pixelWidth_ = 0; int pixelHeight_ = 0; @@ -137,6 +141,5 @@ protected: bool usePostShader_ = false; bool restorePostShader_ = false; - bool postShaderAtOutputResolution_ = false; ShaderLanguage lang_; }; diff --git a/GPU/Software/SoftGpu.cpp b/GPU/Software/SoftGpu.cpp index a8a0163122..a45b4791dc 100644 --- a/GPU/Software/SoftGpu.cpp +++ b/GPU/Software/SoftGpu.cpp @@ -275,10 +275,8 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) { break; } - PostShaderUniforms uniforms{}; - presentation_->CalculatePostShaderUniforms(desc.width, desc.height, false, &uniforms); - presentation_->SourceTexture(fbTex); - presentation_->CopyToOutput(outputFlags, g_Config.iInternalScreenRotation, u0, v0, u1, v1, uniforms); + presentation_->SourceTexture(fbTex, desc.width, desc.height); + presentation_->CopyToOutput(outputFlags, g_Config.iInternalScreenRotation, u0, v0, u1, v1); } void SoftGPU::CopyDisplayToOutput(bool reallyDirty) {