From 23762ef89fe9d063638fbe55a114cbfd8d2ff923 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Wed, 15 Feb 2017 23:11:46 +0100 Subject: [PATCH] Unify DrawFramebufferToOutput --- GPU/Common/FramebufferCommon.cpp | 51 +++++++++++++++++++++++ GPU/Common/FramebufferCommon.h | 2 +- GPU/D3D11/FramebufferManagerD3D11.cpp | 16 -------- GPU/D3D11/FramebufferManagerD3D11.h | 2 - GPU/Directx9/FramebufferDX9.cpp | 16 -------- GPU/Directx9/FramebufferDX9.h | 4 +- GPU/GLES/FramebufferManagerGLES.cpp | 57 +++----------------------- GPU/GLES/FramebufferManagerGLES.h | 2 - GPU/Vulkan/FramebufferVulkan.cpp | 59 --------------------------- GPU/Vulkan/FramebufferVulkan.h | 2 - 10 files changed, 58 insertions(+), 153 deletions(-) diff --git a/GPU/Common/FramebufferCommon.cpp b/GPU/Common/FramebufferCommon.cpp index 83a9d994a2..14d8d76486 100644 --- a/GPU/Common/FramebufferCommon.cpp +++ b/GPU/Common/FramebufferCommon.cpp @@ -716,6 +716,57 @@ void FramebufferManagerCommon::DrawPixels(VirtualFramebuffer *vfb, int dstX, int DrawActiveTexture(dstX, dstY, width, height, vfb->bufferWidth, vfb->bufferHeight, 0.0f, v0, 1.0f, v1, ROTATION_LOCKED_HORIZONTAL, linearFilter); } +void FramebufferManagerCommon::DrawFramebufferToOutput(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, bool applyPostShader) { + textureCache_->ForgetLastTexture(); + shaderManager_->DirtyLastShader(); + + MakePixelTexture(srcPixels, srcPixelFormat, srcStride, 512, 272); + + DisableState(); + + struct CardboardSettings cardboardSettings; + GetCardboardSettings(&cardboardSettings); + + // This might draw directly at the backbuffer (if so, applyPostShader is set) so if there's a post shader, we need to apply it here. + // Should try to unify this path with the regular path somehow, but this simple solution works for most of the post shaders + // (it always runs at output resolution so FXAA may look odd). + float x, y, w, h; + int uvRotation = (g_Config.iRenderingMode != FB_NON_BUFFERED_MODE) ? g_Config.iInternalScreenRotation : ROTATION_LOCKED_HORIZONTAL; + CenterDisplayOutputRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, uvRotation); + if (applyPostShader && useBufferedRendering_) { + // Might've changed if the shader was just changed to Off. + if (usePostShader_) { + PostShaderUniforms uniforms{}; + CalculatePostShaderUniforms(480, 272, renderWidth_, renderHeight_, &uniforms); + BindPostShader(uniforms); + } else { + Bind2DShader(); + } + } else { + Bind2DShader(); + } + float u0 = 0.0f, u1 = 480.0f / 512.0f; + float v0 = 0.0f, v1 = 1.0f; + + // We are drawing directly to the back buffer. + if (needBackBufferYSwap_) + std::swap(v0, v1); + + bool linearFilter = g_Config.iBufFilter == SCALE_LINEAR; + if (cardboardSettings.enabled) { + // Left Eye Image + SetViewport2D(cardboardSettings.leftEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight); + DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, ROTATION_LOCKED_HORIZONTAL, linearFilter); + // Right Eye Image + SetViewport2D(cardboardSettings.rightEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight); + DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, ROTATION_LOCKED_HORIZONTAL, linearFilter); + } else { + // Fullscreen Image + SetViewport2D(0, 0, pixelWidth_, pixelHeight_); + DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, uvRotation, linearFilter); + } +} + void FramebufferManagerCommon::DownloadFramebufferOnSwitch(VirtualFramebuffer *vfb) { if (vfb && vfb->safeWidth > 0 && vfb->safeHeight > 0 && !vfb->firstFrameSaved) { // Some games will draw to some memory once, and use it as a render-to-texture later. diff --git a/GPU/Common/FramebufferCommon.h b/GPU/Common/FramebufferCommon.h index 4be4c7b77b..a2ecb06d6e 100644 --- a/GPU/Common/FramebufferCommon.h +++ b/GPU/Common/FramebufferCommon.h @@ -197,7 +197,7 @@ public: virtual void ReadFramebufferToMemory(VirtualFramebuffer *vfb, bool sync, int x, int y, int w, int h) = 0; virtual void DownloadFramebufferForClut(u32 fb_address, u32 loadBytes) = 0; - virtual void DrawFramebufferToOutput(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, bool applyPostShader) = 0; + void DrawFramebufferToOutput(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, bool applyPostShader); void DrawPixels(VirtualFramebuffer *vfb, int dstX, int dstY, const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height); diff --git a/GPU/D3D11/FramebufferManagerD3D11.cpp b/GPU/D3D11/FramebufferManagerD3D11.cpp index ab21ee5c42..5d26a9e9d6 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.cpp +++ b/GPU/D3D11/FramebufferManagerD3D11.cpp @@ -252,22 +252,6 @@ void FramebufferManagerD3D11::SetViewport2D(int x, int y, int w, int h) { context_->RSSetViewports(1, &vp); } -void FramebufferManagerD3D11::DrawFramebufferToOutput(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, bool applyPostShader) { - MakePixelTexture(srcPixels, srcPixelFormat, srcStride, 512, 272); - DisableState(); - // This might draw directly at the backbuffer (if so, applyPostShader is set) so if there's a post shader, we need to apply it here. - // Should try to unify this path with the regular path somehow, but this simple solution works for most of the post shaders - // (it always runs at output resolution so FXAA may look odd). - float x, y, w, h; - int uvRotation = (g_Config.iRenderingMode != FB_NON_BUFFERED_MODE) ? g_Config.iInternalScreenRotation : ROTATION_LOCKED_HORIZONTAL; - CenterDisplayOutputRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, uvRotation); - context_->PSSetShaderResources(0, 1, &drawPixelsTexView_); - Bind2DShader(); - DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, 0.0f, 0.0f, 480.0f / 512.0f, 1.0f, uvRotation, g_Config.iBufFilter == SCALE_LINEAR); - textureCacheD3D11_->ForgetLastTexture(); - shaderManagerD3D11_->DirtyLastShader(); -} - void FramebufferManagerD3D11::DrawActiveTexture(float x, float y, float w, float h, float destW, float destH, float u0, float v0, float u1, float v1, int uvRotation, bool linearFilter) { float coord[20] = { x,y,0, u0,v0, diff --git a/GPU/D3D11/FramebufferManagerD3D11.h b/GPU/D3D11/FramebufferManagerD3D11.h index af5fcbaf95..b2ea6de043 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.h +++ b/GPU/D3D11/FramebufferManagerD3D11.h @@ -49,8 +49,6 @@ public: drawEngine_ = td; } - virtual void DrawFramebufferToOutput(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, bool applyPostShader) override; - void DrawActiveTexture(float x, float y, float w, float h, float destW, float destH, float u0, float v0, float u1, float v1, int uvRotation, bool linearFilter) override; void DestroyAllFBOs(bool forceDelete); diff --git a/GPU/Directx9/FramebufferDX9.cpp b/GPU/Directx9/FramebufferDX9.cpp index c688cd9f0a..8ec4859027 100644 --- a/GPU/Directx9/FramebufferDX9.cpp +++ b/GPU/Directx9/FramebufferDX9.cpp @@ -271,22 +271,6 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float // D3DXSaveTextureToFile("game:\\cc.png", D3DXIFF_PNG, drawPixelsTex_, NULL); } - void FramebufferManagerDX9::DrawFramebufferToOutput(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, bool applyPostShader) { - textureCache_->ForgetLastTexture(); - shaderManagerDX9_->DirtyLastShader(); - DisableState(); - MakePixelTexture(srcPixels, srcPixelFormat, srcStride, 512, 272); - - // This might draw directly at the backbuffer (if so, applyPostShader is set) so if there's a post shader, we need to apply it here. - // Should try to unify this path with the regular path somehow, but this simple solution works for most of the post shaders - // (it always runs at output resolution so FXAA may look odd). - float x, y, w, h; - int uvRotation = (g_Config.iRenderingMode != FB_NON_BUFFERED_MODE) ? g_Config.iInternalScreenRotation : ROTATION_LOCKED_HORIZONTAL; - CenterDisplayOutputRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, uvRotation); - Bind2DShader(); - DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, 0.0f, 0.0f, 480.0f / 512.0f, 1.0f, uvRotation, true); - } - void FramebufferManagerDX9::SetViewport2D(int x, int y, int w, int h) { D3DVIEWPORT9 vp{ (DWORD)x, (DWORD)y, (DWORD)w, (DWORD)h, 0.0f, 1.0f }; pD3Ddevice->SetViewport(&vp); diff --git a/GPU/Directx9/FramebufferDX9.h b/GPU/Directx9/FramebufferDX9.h index 9a54cc6c2a..ba9e822d96 100644 --- a/GPU/Directx9/FramebufferDX9.h +++ b/GPU/Directx9/FramebufferDX9.h @@ -21,7 +21,7 @@ #include #include -#include "d3d9.h" +#include // Keeps track of allocated FBOs. // Also provides facilities for drawing and later converting raw @@ -51,8 +51,6 @@ public: drawEngine_ = td; } - virtual void DrawFramebufferToOutput(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, bool applyPostShader) override; - void DrawActiveTexture(float x, float y, float w, float h, float destW, float destH, float u0, float v0, float u1, float v1, int uvRotation, bool linearFilter) override; void DestroyAllFBOs(bool forceDelete); diff --git a/GPU/GLES/FramebufferManagerGLES.cpp b/GPU/GLES/FramebufferManagerGLES.cpp index 10fc0c3451..9633be6c52 100644 --- a/GPU/GLES/FramebufferManagerGLES.cpp +++ b/GPU/GLES/FramebufferManagerGLES.cpp @@ -186,6 +186,11 @@ void FramebufferManagerGLES::Bind2DShader() { } void FramebufferManagerGLES::BindPostShader(const PostShaderUniforms &uniforms) { + // Make sure we've compiled the shader. + if (!postShaderProgram_) { + CompileDraw2DProgram(); + } + glsl_bind(postShaderProgram_); if (deltaLoc_ != -1) glUniform2f(deltaLoc_, uniforms.texelDelta[0], uniforms.texelDelta[1]); @@ -345,58 +350,6 @@ void FramebufferManagerGLES::SetViewport2D(int x, int y, int w, int h) { glstate.viewport.set(x, y, w, h); } -void FramebufferManagerGLES::DrawFramebufferToOutput(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, bool applyPostShader) { - MakePixelTexture(srcPixels, srcPixelFormat, srcStride, 512, 272); - - DisableState(); - - struct CardboardSettings cardboardSettings; - GetCardboardSettings(&cardboardSettings); - - // This might draw directly at the backbuffer (if so, applyPostShader is set) so if there's a post shader, we need to apply it here. - // Should try to unify this path with the regular path somehow, but this simple solution works for most of the post shaders - // (it always runs at output resolution so FXAA may look odd). - float x, y, w, h; - int uvRotation = (g_Config.iRenderingMode != FB_NON_BUFFERED_MODE) ? g_Config.iInternalScreenRotation : ROTATION_LOCKED_HORIZONTAL; - CenterDisplayOutputRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, uvRotation); - if (applyPostShader && useBufferedRendering_) { - // Make sure we've compiled the shader. - if (!postShaderProgram_) { - CompileDraw2DProgram(); - } - // Might've changed if the shader was just changed to Off. - if (usePostShader_) { - PostShaderUniforms uniforms{}; - CalculatePostShaderUniforms(480, 272, renderWidth_, renderHeight_, &uniforms); - BindPostShader(uniforms); - } else { - Bind2DShader(); - } - } else { - Bind2DShader(); - } - float u0 = 0.0f, u1 = 480.0f / 512.0f; - float v0 = 0.0f, v1 = 1.0f; - - // We are drawing directly to the back buffer. - if (needBackBufferYSwap_) - std::swap(v0, v1); - - bool linearFilter = g_Config.iBufFilter == SCALE_LINEAR; - if (cardboardSettings.enabled) { - // Left Eye Image - SetViewport2D(cardboardSettings.leftEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight); - DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, ROTATION_LOCKED_HORIZONTAL, linearFilter); - // Right Eye Image - SetViewport2D(cardboardSettings.rightEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight); - DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, ROTATION_LOCKED_HORIZONTAL, linearFilter); - } else { - // Fullscreen Image - SetViewport2D(0, 0, pixelWidth_, pixelHeight_); - DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, uvRotation, linearFilter); - } -} - // x, y, w, h are relative coordinates against destW/destH, which is not very intuitive. // TODO: This could totally use fbo_blit in many cases. void FramebufferManagerGLES::DrawActiveTexture(float x, float y, float w, float h, float destW, float destH, float u0, float v0, float u1, float v1, int uvRotation, bool linearFilter) { diff --git a/GPU/GLES/FramebufferManagerGLES.h b/GPU/GLES/FramebufferManagerGLES.h index 16bdc4ddff..825280e9e7 100644 --- a/GPU/GLES/FramebufferManagerGLES.h +++ b/GPU/GLES/FramebufferManagerGLES.h @@ -62,8 +62,6 @@ public: drawEngine_ = td; } - void DrawFramebufferToOutput(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, bool applyPostShader) override; - // x,y,w,h are relative to destW, destH which fill out the target completely. void DrawActiveTexture(float x, float y, float w, float h, float destW, float destH, float u0, float v0, float u1, float v1, int uvRotation, bool linearFilter) override; diff --git a/GPU/Vulkan/FramebufferVulkan.cpp b/GPU/Vulkan/FramebufferVulkan.cpp index ec3650681a..5ea149b54b 100644 --- a/GPU/Vulkan/FramebufferVulkan.cpp +++ b/GPU/Vulkan/FramebufferVulkan.cpp @@ -417,65 +417,6 @@ void FramebufferManagerVulkan::SetViewport2D(int x, int y, int w, int h) { vkCmdSetViewport(curCmd_, 0, 1, &vp); } -void FramebufferManagerVulkan::DrawFramebufferToOutput(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, bool applyPostShader) { - MakePixelTexture(srcPixels, srcPixelFormat, srcStride, 512, 272); - VulkanTexture *pixelTex = drawPixelsTex_; - // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, g_Config.iTexFiltering == TEX_FILTER_NEAREST ? GL_NEAREST : GL_LINEAR); - - // This might draw directly at the backbuffer (if so, applyPostShader is set) so if there's a post shader, we need to apply it here. - // Should try to unify this path with the regular path somehow, but this simple solution works for most of the post shaders - // (it always runs at output resolution so FXAA may look odd). - float x, y, w, h; - int uvRotation = (g_Config.iRenderingMode != FB_NON_BUFFERED_MODE) ? g_Config.iInternalScreenRotation : ROTATION_LOCKED_HORIZONTAL; - CenterDisplayOutputRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, uvRotation); - if (applyPostShader) { - // Might've changed if the shader was just changed to Off. - if (usePostShader_) { - UpdatePostShaderUniforms(480, 272, renderWidth_, renderHeight_); - } - } - float u0 = 0.0f, u1 = 480.0f / 512.0f; - float v0 = 0.0f, v1 = 1.0f; - - VkPipeline postShaderProgram_ = VK_NULL_HANDLE; - - VkPipeline program = pipelineBasicTex_; - if (applyPostShader && usePostShader_ && useBufferedRendering_) { - program = postShaderProgram_; - } - - CardboardSettings cardboardSettings; - GetCardboardSettings(&cardboardSettings); - - // TODO: Don't use the viewport mechanism for this. - VkViewport vp; - vp.minDepth = 0.0f; - vp.maxDepth = 1.0f; - if (cardboardSettings.enabled) { - // Left Eye Image - vp.x = cardboardSettings.leftEyeXPosition; - vp.y = cardboardSettings.screenYPosition; - vp.width = cardboardSettings.screenWidth; - vp.height = cardboardSettings.screenHeight; - vkCmdSetViewport(curCmd_, 0, 1, &vp); - - DrawTexture(pixelTex, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, program, ROTATION_LOCKED_HORIZONTAL); - - // Right Eye Image - vp.x = cardboardSettings.rightEyeXPosition; - vkCmdSetViewport(curCmd_, 0, 1, &vp); - DrawTexture(pixelTex, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, program, ROTATION_LOCKED_HORIZONTAL); - } else { - // Fullscreen Image - vp.x = 0.0f; - vp.y = 0.0f; - vp.width = pixelWidth_; - vp.height = pixelHeight_; - vkCmdSetViewport(curCmd_, 0, 1, &vp); - DrawTexture(pixelTex, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, program, uvRotation); - } -} - void FramebufferManagerVulkan::DrawActiveTexture(float x, float y, float w, float h, float destW, float destH, float u0, float v0, float u1, float v1, int uvRotation, bool linearFilter) { // TODO } diff --git a/GPU/Vulkan/FramebufferVulkan.h b/GPU/Vulkan/FramebufferVulkan.h index 7012ee0b56..6ba963268a 100644 --- a/GPU/Vulkan/FramebufferVulkan.h +++ b/GPU/Vulkan/FramebufferVulkan.h @@ -69,8 +69,6 @@ public: drawEngine_ = td; } - void DrawFramebufferToOutput(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, bool applyPostShader) override; - // If texture != 0, will bind it. // x,y,w,h are relative to destW, destH which fill out the target completely. void DrawTexture(VulkanTexture *texture, float x, float y, float w, float h, float destW, float destH, float u0, float v0, float u1, float v1, VkPipeline pipeline, int uvRotation);