diff --git a/GPU/Common/FramebufferCommon.h b/GPU/Common/FramebufferCommon.h index 1b85572a2..2fd45a06c 100644 --- a/GPU/Common/FramebufferCommon.h +++ b/GPU/Common/FramebufferCommon.h @@ -258,6 +258,7 @@ public: Draw::Framebuffer *GetTempFBO(u16 w, u16 h, Draw::FBColorDepth depth = Draw::FBO_8888); protected: + virtual void SetViewport2D(int x, int y, int w, int h) = 0; void CalculatePostShaderUniforms(int bufferWidth, int bufferHeight, int renderWidth, int renderHeight, PostShaderUniforms *uniforms); virtual 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) = 0; virtual void BindPostShader(const PostShaderUniforms &uniforms) {} diff --git a/GPU/D3D11/FramebufferManagerD3D11.cpp b/GPU/D3D11/FramebufferManagerD3D11.cpp index 1f8c0b209..144b2c598 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.cpp +++ b/GPU/D3D11/FramebufferManagerD3D11.cpp @@ -241,6 +241,11 @@ void FramebufferManagerD3D11::MakePixelTexture(const u8 *srcPixels, GEBufferForm // D3DXSaveTextureToFile("game:\\cc.png", D3DXIFF_PNG, drawPixelsTex_, NULL); } +void FramebufferManagerD3D11::SetViewport2D(int x, int y, int w, int h) { + D3D11_VIEWPORT vp{ (float)x, (float)y, (float)w, (float)h, 0.0f, 1.0f }; + context_->RSSetViewports(1, &vp); +} + void FramebufferManagerD3D11::DrawPixels(VirtualFramebuffer *vfb, int dstX, int dstY, const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height) { if (useBufferedRendering_ && vfb && vfb->fbo) { draw_->BindFramebufferAsRenderTarget(vfb->fbo); diff --git a/GPU/D3D11/FramebufferManagerD3D11.h b/GPU/D3D11/FramebufferManagerD3D11.h index fe1c2eb54..afc3c6296 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.h +++ b/GPU/D3D11/FramebufferManagerD3D11.h @@ -88,6 +88,7 @@ public: } protected: + void SetViewport2D(int x, int y, int w, int h); void DisableState() override; void ClearBuffer(bool keepState = false) override; void FlushBeforeCopy() override; diff --git a/GPU/Directx9/FramebufferDX9.cpp b/GPU/Directx9/FramebufferDX9.cpp index 49ba31c6d..fdd7b78ff 100644 --- a/GPU/Directx9/FramebufferDX9.cpp +++ b/GPU/Directx9/FramebufferDX9.cpp @@ -268,26 +268,23 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float void FramebufferManagerDX9::DrawPixels(VirtualFramebuffer *vfb, int dstX, int dstY, const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height) { if (useBufferedRendering_ && vfb && vfb->fbo) { draw_->BindFramebufferAsRenderTarget(vfb->fbo); - D3DVIEWPORT9 vp{ 0, 0, vfb->renderWidth, vfb->renderHeight, 0.0f, 1.0f }; - pD3Ddevice->SetViewport(&vp); + SetViewport2D(0, 0, vfb->renderWidth, vfb->renderHeight); } else { float x, y, w, h; CenterDisplayOutputRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, ROTATION_LOCKED_HORIZONTAL); - D3DVIEWPORT9 vp{ (DWORD)x, (DWORD)y, (DWORD)w, (DWORD)h, 0.0f, 1.0f }; - pD3Ddevice->SetViewport(&vp); + SetViewport2D(x, y, w, h); } MakePixelTexture(srcPixels, srcPixelFormat, srcStride, width, height); DisableState(); device_->SetTexture(0, drawPixelsTex_); DrawActiveTexture(dstX, dstY, width, height, vfb->bufferWidth, vfb->bufferHeight, 0.0f, 0.0f, 1.0f, 1.0f, ROTATION_LOCKED_HORIZONTAL, true); - textureCacheDX9_->ForgetLastTexture(); + textureCache_->ForgetLastTexture(); dxstate.viewport.restore(); } void FramebufferManagerDX9::DrawFramebufferToOutput(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, bool applyPostShader) { - MakePixelTexture(srcPixels, srcPixelFormat, srcStride, 512, 272); - 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 @@ -299,6 +296,11 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float 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); + } + void FramebufferManagerDX9::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: StretchRect instead? float coord[20] = { diff --git a/GPU/Directx9/FramebufferDX9.h b/GPU/Directx9/FramebufferDX9.h index 46ada0564..3c71a309d 100644 --- a/GPU/Directx9/FramebufferDX9.h +++ b/GPU/Directx9/FramebufferDX9.h @@ -88,6 +88,7 @@ public: LPDIRECT3DSURFACE9 GetOffscreenSurface(D3DFORMAT fmt, u32 w, u32 h); protected: + void SetViewport2D(int x, int y, int w, int h) override; void DisableState() override; void ClearBuffer(bool keepState = false) override; void FlushBeforeCopy() override; @@ -101,9 +102,6 @@ protected: private: void MakePixelTexture(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height); - void CompileDraw2DProgram(); - void DestroyDraw2DProgram(); - void PackFramebufferDirectx9_(VirtualFramebuffer *vfb, int x, int y, int w, int h); void PackDepthbuffer(VirtualFramebuffer *vfb, int x, int y, int w, int h); static bool GetRenderTargetFramebuffer(LPDIRECT3DSURFACE9 renderTarget, LPDIRECT3DSURFACE9 offscreen, int w, int h, GPUDebugBuffer &buffer); diff --git a/GPU/GLES/FramebufferManagerGLES.cpp b/GPU/GLES/FramebufferManagerGLES.cpp index f423d6b6e..05ac7f148 100644 --- a/GPU/GLES/FramebufferManagerGLES.cpp +++ b/GPU/GLES/FramebufferManagerGLES.cpp @@ -331,6 +331,10 @@ void FramebufferManagerGLES::MakePixelTexture(const u8 *srcPixels, GEBufferForma glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, useConvBuf ? convBuf_ : srcPixels); } +void FramebufferManagerGLES::SetViewport2D(int x, int y, int w, int h) { + glstate.viewport.set(x, y, w, h); +} + void FramebufferManagerGLES::DrawPixels(VirtualFramebuffer *vfb, int dstX, int dstY, const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height) { shaderManager_->DirtyLastShader(); textureCacheGL_->ForgetLastTexture(); @@ -338,14 +342,14 @@ void FramebufferManagerGLES::DrawPixels(VirtualFramebuffer *vfb, int dstX, int d float v0 = 0.0f, v1 = 1.0f; if (useBufferedRendering_ && vfb && vfb->fbo) { draw_->BindFramebufferAsRenderTarget(vfb->fbo); - glViewport(0, 0, vfb->renderWidth, vfb->renderHeight); + SetViewport2D(0, 0, vfb->renderWidth, vfb->renderHeight); } else { // We are drawing to the back buffer so need to flip. v0 = 1.0f; v1 = 0.0f; float x, y, w, h; CenterDisplayOutputRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, ROTATION_LOCKED_HORIZONTAL); - glViewport(x, y, w, h); + SetViewport2D(x, y, w, h); } MakePixelTexture(srcPixels, srcPixelFormat, srcStride, width, height); @@ -395,14 +399,14 @@ void FramebufferManagerGLES::DrawFramebufferToOutput(const u8 *srcPixels, GEBuff bool linearFilter = g_Config.iBufFilter == SCALE_LINEAR; if (cardboardSettings.enabled) { // Left Eye Image - glstate.viewport.set(cardboardSettings.leftEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight); + 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 - glstate.viewport.set(cardboardSettings.rightEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight); + 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 - glstate.viewport.set(0, 0, pixelWidth_, pixelHeight_); + SetViewport2D(0, 0, pixelWidth_, pixelHeight_); DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, uvRotation, linearFilter); } } @@ -617,7 +621,7 @@ void FramebufferManagerGLES::BindFramebufferColor(int stage, u32 fbRawAddress, V void FramebufferManagerGLES::CopyDisplayToOutput() { DownloadFramebufferOnSwitch(currentRenderVfb_); - glstate.viewport.set(0, 0, pixelWidth_, pixelHeight_); + SetViewport2D(0, 0, pixelWidth_, pixelHeight_); draw_->BindBackbufferAsRenderTarget(); currentRenderVfb_ = 0; @@ -751,15 +755,15 @@ void FramebufferManagerGLES::CopyDisplayToOutput() { std::swap(v0, v1); if (cardboardSettings.enabled) { // Left Eye Image - glstate.viewport.set(cardboardSettings.leftEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight); + 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 - glstate.viewport.set(cardboardSettings.rightEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight); + 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 - glstate.viewport.set(0, 0, pixelWidth_, pixelHeight_); + SetViewport2D(0, 0, pixelWidth_, pixelHeight_); DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, uvRotation, linearFilter); } } else if (usePostShader_ && extraFBOs_.size() == 1 && !postShaderAtOutputResolution_) { @@ -767,7 +771,7 @@ void FramebufferManagerGLES::CopyDisplayToOutput() { draw_->BindFramebufferAsRenderTarget(extraFBOs_[0]); int fbo_w, fbo_h; draw_->GetFramebufferDimensions(extraFBOs_[0], &fbo_w, &fbo_h); - glstate.viewport.set(0, 0, fbo_w, fbo_h); + SetViewport2D(0, 0, fbo_w, fbo_h); shaderManager_->DirtyLastShader(); // dirty lastShader_ PostShaderUniforms uniforms{}; CalculatePostShaderUniforms(vfb->bufferWidth, vfb->bufferHeight, renderWidth_, renderHeight_, &uniforms); @@ -792,15 +796,15 @@ void FramebufferManagerGLES::CopyDisplayToOutput() { linearFilter = !postShaderIsUpscalingFilter_ && g_Config.iBufFilter == SCALE_LINEAR; if (g_Config.bEnableCardboard) { // Left Eye Image - glstate.viewport.set(cardboardSettings.leftEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight); + 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 - glstate.viewport.set(cardboardSettings.rightEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight); + 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 - glstate.viewport.set(0, 0, pixelWidth_, pixelHeight_); + SetViewport2D(0, 0, pixelWidth_, pixelHeight_); DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, uvRotation, linearFilter); } @@ -821,15 +825,15 @@ void FramebufferManagerGLES::CopyDisplayToOutput() { BindPostShader(uniforms); if (g_Config.bEnableCardboard) { // Left Eye Image - glstate.viewport.set(cardboardSettings.leftEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight); + 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 - glstate.viewport.set(cardboardSettings.rightEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight); + 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 - glstate.viewport.set(0, 0, pixelWidth_, pixelHeight_); + SetViewport2D(0, 0, pixelWidth_, pixelHeight_); DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, uvRotation, linearFilter); } } diff --git a/GPU/GLES/FramebufferManagerGLES.h b/GPU/GLES/FramebufferManagerGLES.h index c505835d6..f491ad8bb 100644 --- a/GPU/GLES/FramebufferManagerGLES.h +++ b/GPU/GLES/FramebufferManagerGLES.h @@ -101,6 +101,7 @@ public: virtual void RebindFramebuffer() override; protected: + void SetViewport2D(int x, int y, int w, int h) override; void DisableState() override; void ClearBuffer(bool keepState = false) override; void FlushBeforeCopy() override; diff --git a/GPU/Vulkan/FramebufferVulkan.cpp b/GPU/Vulkan/FramebufferVulkan.cpp index 411201af1..a87a101af 100644 --- a/GPU/Vulkan/FramebufferVulkan.cpp +++ b/GPU/Vulkan/FramebufferVulkan.cpp @@ -402,6 +402,17 @@ VulkanTexture *FramebufferManagerVulkan::MakePixelTexture(const u8 *srcPixels, G return drawPixelsTex_; } +void FramebufferManagerVulkan::SetViewport2D(int x, int y, int w, int h) { + VkViewport vp; + vp.minDepth = 0.0; + vp.maxDepth = 1.0; + vp.x = (float)x; + vp.y = (float)y; + vp.width = (float)w; + vp.height = (float)h; + vkCmdSetViewport(curCmd_, 0, 1, &vp); +} + void FramebufferManagerVulkan::DrawPixels(VirtualFramebuffer *vfb, int dstX, int dstY, const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height) { VkViewport vp; vp.minDepth = 0.0; diff --git a/GPU/Vulkan/FramebufferVulkan.h b/GPU/Vulkan/FramebufferVulkan.h index cb8cd69bf..2c7b0c170 100644 --- a/GPU/Vulkan/FramebufferVulkan.h +++ b/GPU/Vulkan/FramebufferVulkan.h @@ -126,6 +126,7 @@ public: } protected: + void SetViewport2D(int x, int y, int w, int h); void DisableState() override {} void ClearBuffer(bool keepState = false) override; void FlushBeforeCopy() override;