diff --git a/Source/Core/VideoBackends/D3D/FramebufferManager.cpp b/Source/Core/VideoBackends/D3D/FramebufferManager.cpp index d4d620320a..9027bc21d5 100644 --- a/Source/Core/VideoBackends/D3D/FramebufferManager.cpp +++ b/Source/Core/VideoBackends/D3D/FramebufferManager.cpp @@ -6,6 +6,7 @@ #include "VideoBackends/D3D/D3DBase.h" #include "VideoBackends/D3D/D3DUtil.h" #include "VideoBackends/D3D/FramebufferManager.h" +#include "VideoBackends/D3D/GeometryShaderCache.h" #include "VideoBackends/D3D/PixelShaderCache.h" #include "VideoBackends/D3D/Render.h" #include "VideoBackends/D3D/VertexShaderCache.h" @@ -17,6 +18,8 @@ namespace DX11 { static XFBEncoder s_xfbEncoder; FramebufferManager::Efb FramebufferManager::m_efb; +unsigned int FramebufferManager::m_target_width; +unsigned int FramebufferManager::m_target_height; D3DTexture2D* &FramebufferManager::GetEFBColorTexture() { return m_efb.color_tex; } ID3D11Texture2D* &FramebufferManager::GetEFBColorStagingBuffer() { return m_efb.color_staging_buf; } @@ -51,8 +54,8 @@ D3DTexture2D* &FramebufferManager::GetResolvedEFBDepthTexture() FramebufferManager::FramebufferManager() { - unsigned int target_width = Renderer::GetTargetWidth(); - unsigned int target_height = Renderer::GetTargetHeight(); + m_target_width = Renderer::GetTargetWidth(); + m_target_height = Renderer::GetTargetHeight(); DXGI_SAMPLE_DESC sample_desc = D3D::GetAAMode(g_ActiveConfig.iMultisampleMode); ID3D11Texture2D* buf; @@ -62,22 +65,22 @@ FramebufferManager::FramebufferManager() m_EFBLayers = m_efb.slices = (g_ActiveConfig.iStereoMode > 0) ? 2 : 1; // EFB color texture - primary render target - texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, target_width, target_height, m_efb.slices, 1, D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET, D3D11_USAGE_DEFAULT, 0, sample_desc.Count, sample_desc.Quality); + texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, m_target_width, m_target_height, m_efb.slices, 1, D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET, D3D11_USAGE_DEFAULT, 0, sample_desc.Count, sample_desc.Quality); hr = D3D::device->CreateTexture2D(&texdesc, nullptr, &buf); - CHECK(hr==S_OK, "create EFB color texture (size: %dx%d; hr=%#x)", target_width, target_height, hr); + CHECK(hr==S_OK, "create EFB color texture (size: %dx%d; hr=%#x)", m_target_width, m_target_height, hr); m_efb.color_tex = new D3DTexture2D(buf, (D3D11_BIND_FLAG)(D3D11_BIND_SHADER_RESOURCE|D3D11_BIND_RENDER_TARGET), DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R8G8B8A8_UNORM, (sample_desc.Count > 1)); - CHECK(m_efb.color_tex!=nullptr, "create EFB color texture (size: %dx%d)", target_width, target_height); + CHECK(m_efb.color_tex!=nullptr, "create EFB color texture (size: %dx%d)", m_target_width, m_target_height); SAFE_RELEASE(buf); D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_tex->GetTex(), "EFB color texture"); D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_tex->GetSRV(), "EFB color texture shader resource view"); D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_tex->GetRTV(), "EFB color texture render target view"); // Temporary EFB color texture - used in ReinterpretPixelData - texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, target_width, target_height, m_efb.slices, 1, D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET, D3D11_USAGE_DEFAULT, 0, sample_desc.Count, sample_desc.Quality); + texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, m_target_width, m_target_height, m_efb.slices, 1, D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET, D3D11_USAGE_DEFAULT, 0, sample_desc.Count, sample_desc.Quality); hr = D3D::device->CreateTexture2D(&texdesc, nullptr, &buf); - CHECK(hr==S_OK, "create EFB color temp texture (size: %dx%d; hr=%#x)", target_width, target_height, hr); + CHECK(hr==S_OK, "create EFB color temp texture (size: %dx%d; hr=%#x)", m_target_width, m_target_height, hr); m_efb.color_temp_tex = new D3DTexture2D(buf, (D3D11_BIND_FLAG)(D3D11_BIND_SHADER_RESOURCE|D3D11_BIND_RENDER_TARGET), DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R8G8B8A8_UNORM, (sample_desc.Count > 1)); - CHECK(m_efb.color_temp_tex!=nullptr, "create EFB color temp texture (size: %dx%d)", target_width, target_height); + CHECK(m_efb.color_temp_tex!=nullptr, "create EFB color temp texture (size: %dx%d)", m_target_width, m_target_height); SAFE_RELEASE(buf); D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_temp_tex->GetTex(), "EFB color temp texture"); D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_temp_tex->GetSRV(), "EFB color temp texture shader resource view"); @@ -90,9 +93,9 @@ FramebufferManager::FramebufferManager() D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_staging_buf, "EFB color staging texture (used for Renderer::AccessEFB)"); // EFB depth buffer - primary depth buffer - texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R24G8_TYPELESS, target_width, target_height, m_efb.slices, 1, D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_DEFAULT, 0, sample_desc.Count, sample_desc.Quality); + texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R24G8_TYPELESS, m_target_width, m_target_height, m_efb.slices, 1, D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_DEFAULT, 0, sample_desc.Count, sample_desc.Quality); hr = D3D::device->CreateTexture2D(&texdesc, nullptr, &buf); - CHECK(hr==S_OK, "create EFB depth texture (size: %dx%d; hr=%#x)", target_width, target_height, hr); + CHECK(hr==S_OK, "create EFB depth texture (size: %dx%d; hr=%#x)", m_target_width, m_target_height, hr); m_efb.depth_tex = new D3DTexture2D(buf, (D3D11_BIND_FLAG)(D3D11_BIND_DEPTH_STENCIL|D3D11_BIND_SHADER_RESOURCE), DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_D24_UNORM_S8_UINT, DXGI_FORMAT_UNKNOWN, (sample_desc.Count > 1)); SAFE_RELEASE(buf); D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.depth_tex->GetTex(), "EFB depth texture"); @@ -117,17 +120,17 @@ FramebufferManager::FramebufferManager() if (g_ActiveConfig.iMultisampleMode) { // Framebuffer resolve textures (color+depth) - texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, target_width, target_height, m_efb.slices, 1, D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_DEFAULT, 0, 1); + texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, m_target_width, m_target_height, m_efb.slices, 1, D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_DEFAULT, 0, 1); hr = D3D::device->CreateTexture2D(&texdesc, nullptr, &buf); m_efb.resolved_color_tex = new D3DTexture2D(buf, D3D11_BIND_SHADER_RESOURCE, DXGI_FORMAT_R8G8B8A8_UNORM); - CHECK(m_efb.resolved_color_tex!=nullptr, "create EFB color resolve texture (size: %dx%d)", target_width, target_height); + CHECK(m_efb.resolved_color_tex!=nullptr, "create EFB color resolve texture (size: %dx%d)", m_target_width, m_target_height); SAFE_RELEASE(buf); D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.resolved_color_tex->GetTex(), "EFB color resolve texture"); D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.resolved_color_tex->GetSRV(), "EFB color resolve texture shader resource view"); - texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R24G8_TYPELESS, target_width, target_height, m_efb.slices, 1, D3D11_BIND_SHADER_RESOURCE); + texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R24G8_TYPELESS, m_target_width, m_target_height, m_efb.slices, 1, D3D11_BIND_SHADER_RESOURCE); hr = D3D::device->CreateTexture2D(&texdesc, nullptr, &buf); - CHECK(hr==S_OK, "create EFB depth resolve texture (size: %dx%d; hr=%#x)", target_width, target_height, hr); + CHECK(hr==S_OK, "create EFB depth resolve texture (size: %dx%d; hr=%#x)", m_target_width, m_target_height, hr); m_efb.resolved_depth_tex = new D3DTexture2D(buf, D3D11_BIND_SHADER_RESOURCE, DXGI_FORMAT_R24_UNORM_X8_TYPELESS); SAFE_RELEASE(buf); D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.resolved_depth_tex->GetTex(), "EFB depth resolve texture"); @@ -162,32 +165,17 @@ void FramebufferManager::CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, c s_xfbEncoder.Encode(dst, fbWidth, fbHeight, sourceRc, Gamma); } -XFBSourceBase* FramebufferManager::CreateXFBSource(unsigned int target_width, unsigned int target_height) +XFBSourceBase* FramebufferManager::CreateXFBSource(unsigned int target_width, unsigned int target_height, unsigned int layers) { return new XFBSource(D3DTexture2D::Create(target_width, target_height, (D3D11_BIND_FLAG)(D3D11_BIND_RENDER_TARGET|D3D11_BIND_SHADER_RESOURCE), - D3D11_USAGE_DEFAULT, DXGI_FORMAT_R8G8B8A8_UNORM, 1, FramebufferManager::GetEFBLayers()), FramebufferManager::GetEFBLayers()); + D3D11_USAGE_DEFAULT, DXGI_FORMAT_R8G8B8A8_UNORM, 1, layers), layers); } -void FramebufferManager::GetTargetSize(unsigned int *width, unsigned int *height, const EFBRectangle& sourceRc) +void FramebufferManager::GetTargetSize(unsigned int *width, unsigned int *height) { - TargetRectangle targetSource; - - targetSource.top = ScaleToVirtualXfbHeight(sourceRc.top, Renderer::GetBackbufferHeight()); - targetSource.bottom = ScaleToVirtualXfbHeight(sourceRc.bottom, Renderer::GetBackbufferHeight()); - targetSource.left = ScaleToVirtualXfbWidth(sourceRc.left, Renderer::GetBackbufferWidth()); - targetSource.right = ScaleToVirtualXfbWidth(sourceRc.right, Renderer::GetBackbufferWidth()); - - *width = targetSource.right - targetSource.left; - *height = targetSource.bottom - targetSource.top; -} - -void XFBSource::Draw(const MathUtil::Rectangle &sourcerc, - const MathUtil::Rectangle &drawrc) const -{ - D3D::drawShadedTexSubQuad(tex->GetSRV(), &sourcerc, - texWidth, texHeight, &drawrc, PixelShaderCache::GetColorCopyProgram(false), - VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout()); + *width = m_target_width; + *height = m_target_height; } void XFBSource::DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight) @@ -208,9 +196,9 @@ void XFBSource::CopyEFB(float Gamma) D3D::SetLinearCopySampler(); D3D::drawShadedTexQuad(FramebufferManager::GetEFBColorTexture()->GetSRV(), sourceRc.AsRECT(), - Renderer::GetTargetWidth(), Renderer::GetTargetHeight(), - PixelShaderCache::GetColorCopyProgram(true), VertexShaderCache::GetSimpleVertexShader(), - VertexShaderCache::GetSimpleInputLayout(), nullptr, Gamma); + Renderer::GetTargetWidth(), Renderer::GetTargetHeight(), PixelShaderCache::GetColorCopyProgram(true), + VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), + GeometryShaderCache::GetCopyGeometryShader(), Gamma); D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); @@ -218,4 +206,4 @@ void XFBSource::CopyEFB(float Gamma) g_renderer->RestoreAPIState(); } -} // namespace DX11 \ No newline at end of file +} // namespace DX11 diff --git a/Source/Core/VideoBackends/D3D/FramebufferManager.h b/Source/Core/VideoBackends/D3D/FramebufferManager.h index d7961cb9b8..559215e7e8 100644 --- a/Source/Core/VideoBackends/D3D/FramebufferManager.h +++ b/Source/Core/VideoBackends/D3D/FramebufferManager.h @@ -48,8 +48,6 @@ struct XFBSource : public XFBSourceBase XFBSource(D3DTexture2D *_tex, int slices) : tex(_tex), m_slices(slices) {} ~XFBSource() { tex->Release(); } - void Draw(const MathUtil::Rectangle &sourcerc, - const MathUtil::Rectangle &drawrc) const override; void DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight) override; void CopyEFB(float Gamma) override; @@ -82,8 +80,8 @@ public: } private: - XFBSourceBase* CreateXFBSource(unsigned int target_width, unsigned int target_height) override; - void GetTargetSize(unsigned int *width, unsigned int *height, const EFBRectangle& sourceRc) override; + XFBSourceBase* CreateXFBSource(unsigned int target_width, unsigned int target_height, unsigned int layers) override; + void GetTargetSize(unsigned int *width, unsigned int *height) override; void CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma) override; @@ -103,6 +101,9 @@ private: int slices; } m_efb; + + static unsigned int m_target_width; + static unsigned int m_target_height; }; } // namespace DX11 diff --git a/Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp b/Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp index a5cfcd235f..ab4a26368e 100644 --- a/Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp +++ b/Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp @@ -70,29 +70,29 @@ public: const char clear_shader_code[] = { "struct VSOUTPUT\n" "{\n" - "float4 vPosition : POSITION;\n" - "float4 vColor0 : COLOR0;\n" + " float4 vPosition : POSITION;\n" + " float4 vColor0 : COLOR0;\n" "};\n" "struct GSOUTPUT\n" "{\n" - "float4 vPosition : POSITION;\n" - "float4 vColor0 : COLOR0;\n" - "uint slice : SV_RenderTargetArrayIndex;\n" + " float4 vPosition : POSITION;\n" + " float4 vColor0 : COLOR0;\n" + " uint slice : SV_RenderTargetArrayIndex;\n" "};\n" "[maxvertexcount(6)]\n" "void main(triangle VSOUTPUT o[3], inout TriangleStream Output)\n" "{\n" "for(int slice = 0; slice < 2; slice++)\n" "{\n" - "for(int i = 0; i < 3; i++)\n" - "{\n" - "GSOUTPUT OUT;\n" - "OUT.vPosition = o[i].vPosition;\n" - "OUT.vColor0 = o[i].vColor0;\n" - "OUT.slice = slice;\n" - "Output.Append(OUT);\n" - "}\n" - "Output.RestartStrip();\n" + " for(int i = 0; i < 3; i++)\n" + " {\n" + " GSOUTPUT OUT;\n" + " OUT.vPosition = o[i].vPosition;\n" + " OUT.vColor0 = o[i].vColor0;\n" + " OUT.slice = slice;\n" + " Output.Append(OUT);\n" + " }\n" + " Output.RestartStrip();\n" "}\n" "}\n" }; @@ -100,33 +100,33 @@ const char clear_shader_code[] = { const char copy_shader_code[] = { "struct VSOUTPUT\n" "{\n" - "float4 vPosition : POSITION;\n" - "float3 vTexCoord : TEXCOORD0;\n" - "float vTexCoord1 : TEXCOORD1;\n" + " float4 vPosition : POSITION;\n" + " float3 vTexCoord : TEXCOORD0;\n" + " float vTexCoord1 : TEXCOORD1;\n" "};\n" "struct GSOUTPUT\n" "{\n" - "float4 vPosition : POSITION;\n" - "float3 vTexCoord : TEXCOORD0;\n" - "float vTexCoord1 : TEXCOORD1;\n" - "uint slice : SV_RenderTargetArrayIndex;\n" + " float4 vPosition : POSITION;\n" + " float3 vTexCoord : TEXCOORD0;\n" + " float vTexCoord1 : TEXCOORD1;\n" + " uint slice : SV_RenderTargetArrayIndex;\n" "};\n" "[maxvertexcount(6)]\n" "void main(triangle VSOUTPUT o[3], inout TriangleStream Output)\n" "{\n" "for(int slice = 0; slice < 2; slice++)\n" "{\n" - "for(int i = 0; i < 3; i++)\n" - "{\n" - "GSOUTPUT OUT;\n" - "OUT.vPosition = o[i].vPosition;\n" - "OUT.vTexCoord = o[i].vTexCoord;\n" - "OUT.vTexCoord.z = slice;\n" - "OUT.vTexCoord1 = o[i].vTexCoord1;\n" - "OUT.slice = slice;\n" - "Output.Append(OUT);\n" - "}\n" - "Output.RestartStrip();\n" + " for(int i = 0; i < 3; i++)\n" + " {\n" + " GSOUTPUT OUT;\n" + " OUT.vPosition = o[i].vPosition;\n" + " OUT.vTexCoord = o[i].vTexCoord;\n" + " OUT.vTexCoord.z = slice;\n" + " OUT.vTexCoord1 = o[i].vTexCoord1;\n" + " OUT.slice = slice;\n" + " Output.Append(OUT);\n" + " }\n" + " Output.RestartStrip();\n" "}\n" "}\n" }; diff --git a/Source/Core/VideoBackends/D3D/Render.cpp b/Source/Core/VideoBackends/D3D/Render.cpp index c309882e75..cf2a0a77ff 100644 --- a/Source/Core/VideoBackends/D3D/Render.cpp +++ b/Source/Core/VideoBackends/D3D/Render.cpp @@ -709,23 +709,8 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co // Prepare to copy the XFBs to our backbuffer UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height); + TargetRectangle targetRc = GetTargetRectangle(); - int X = GetTargetRectangle().left; - int Y = GetTargetRectangle().top; - int Width = GetTargetRectangle().right - GetTargetRectangle().left; - int Height = GetTargetRectangle().bottom - GetTargetRectangle().top; - - // TODO: Redundant checks... - if (X < 0) X = 0; - if (Y < 0) Y = 0; - if (X > s_backbuffer_width) X = s_backbuffer_width; - if (Y > s_backbuffer_height) Y = s_backbuffer_height; - if (Width < 0) Width = 0; - if (Height < 0) Height = 0; - if (Width > (s_backbuffer_width - X)) Width = s_backbuffer_width - X; - if (Height > (s_backbuffer_height - Y)) Height = s_backbuffer_height - Y; - D3D11_VIEWPORT vp = CD3D11_VIEWPORT((float)X, (float)Y, (float)Width, (float)Height); - D3D::context->RSSetViewports(1, &vp); D3D::context->OMSetRenderTargets(1, &D3D::GetBackBuffer()->GetRTV(), nullptr); float ClearColor[4] = { 0.f, 0.f, 0.f, 1.f }; @@ -737,110 +722,58 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co if (g_ActiveConfig.bUseXFB && g_ActiveConfig.bUseRealXFB) { // TODO: Television should be used to render Virtual XFB mode as well. + D3D11_VIEWPORT vp = CD3D11_VIEWPORT((float)targetRc.left, (float)targetRc.top, (float)targetRc.GetWidth(), (float)targetRc.GetHeight()); + D3D::context->RSSetViewports(1, &vp); + s_television.Submit(xfbAddr, fbStride, fbWidth, fbHeight); s_television.Render(); } else if (g_ActiveConfig.bUseXFB) { - const XFBSourceBase* xfbSource; + const XFBSource* xfbSource; // draw each xfb source for (u32 i = 0; i < xfbCount; ++i) { - xfbSource = xfbSourceList[i]; - MathUtil::Rectangle sourceRc; + xfbSource = (const XFBSource*)xfbSourceList[i]; + TargetRectangle drawRc; + + // use virtual xfb with offset + int xfbHeight = xfbSource->srcHeight; + int xfbWidth = xfbSource->srcWidth; + int hOffset = ((s32)xfbSource->srcAddr - (s32)xfbAddr) / ((s32)fbStride * 2); + + drawRc.top = targetRc.bottom - (hOffset + xfbHeight) * targetRc.GetHeight() / fbHeight; + drawRc.bottom = targetRc.bottom - hOffset * targetRc.GetHeight() / fbHeight; + drawRc.left = targetRc.left + (targetRc.GetWidth() - xfbWidth * targetRc.GetWidth() / fbStride) / 2; + drawRc.right = targetRc.left + (targetRc.GetWidth() + xfbWidth * targetRc.GetWidth() / fbStride) / 2; + + // The following code disables auto stretch. Kept for reference. + // scale draw area for a 1 to 1 pixel mapping with the draw target + //float vScale = (float)fbHeight / (float)s_backbuffer_height; + //float hScale = (float)fbWidth / (float)s_backbuffer_width; + //drawRc.top *= vScale; + //drawRc.bottom *= vScale; + //drawRc.left *= hScale; + //drawRc.right *= hScale; + + TargetRectangle sourceRc; sourceRc.left = 0; sourceRc.top = 0; sourceRc.right = (int)xfbSource->texWidth; sourceRc.bottom = (int)xfbSource->texHeight; - MathUtil::Rectangle drawRc; - - if (g_ActiveConfig.bUseRealXFB) - { - drawRc.top = 1; - drawRc.bottom = -1; - drawRc.left = -1; - drawRc.right = 1; - } - else - { - // use virtual xfb with offset - int xfbHeight = xfbSource->srcHeight; - int xfbWidth = xfbSource->srcWidth; - int hOffset = ((s32)xfbSource->srcAddr - (s32)xfbAddr) / ((s32)fbStride * 2); - - drawRc.top = 1.0f - (2.0f * (hOffset) / (float)fbHeight); - drawRc.bottom = 1.0f - (2.0f * (hOffset + xfbHeight) / (float)fbHeight); - drawRc.left = -(xfbWidth / (float)fbStride); - drawRc.right = (xfbWidth / (float)fbStride); - - // The following code disables auto stretch. Kept for reference. - // scale draw area for a 1 to 1 pixel mapping with the draw target - //float vScale = (float)fbHeight / (float)s_backbuffer_height; - //float hScale = (float)fbWidth / (float)s_backbuffer_width; - //drawRc.top *= vScale; - //drawRc.bottom *= vScale; - //drawRc.left *= hScale; - //drawRc.right *= hScale; - } - - xfbSource->Draw(sourceRc, drawRc); + BlitScreen(sourceRc, drawRc, xfbSource->tex, xfbSource->texWidth, xfbSource->texHeight, Gamma); } } else { - TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc); + TargetRectangle sourceRc = Renderer::ConvertEFBRectangle(rc); // TODO: Improve sampling algorithm for the pixel shader so that we can use the multisampled EFB texture as source D3DTexture2D* read_texture = FramebufferManager::GetResolvedEFBColorTexture(); - - if (g_ActiveConfig.iStereoMode == STEREO_SBS || g_ActiveConfig.iStereoMode == STEREO_TAB) - { - TargetRectangle leftRc, rightRc; - ConvertStereoRectangle(GetTargetRectangle(), leftRc, rightRc); - - D3D11_VIEWPORT leftVp = CD3D11_VIEWPORT((float)leftRc.left, (float)leftRc.top, (float)leftRc.GetWidth(), (float)leftRc.GetHeight()); - D3D11_VIEWPORT rightVp = CD3D11_VIEWPORT((float)rightRc.left, (float)rightRc.top, (float)rightRc.GetWidth(), (float)rightRc.GetHeight()); - - D3D::context->RSSetViewports(1, &leftVp); - D3D::drawShadedTexQuad(read_texture->GetSRV(), targetRc.AsRECT(), Renderer::GetTargetWidth(), Renderer::GetTargetHeight(), PixelShaderCache::GetColorCopyProgram(false), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), nullptr, Gamma, 0); - - D3D::context->RSSetViewports(1, &rightVp); - D3D::drawShadedTexQuad(read_texture->GetSRV(), targetRc.AsRECT(), Renderer::GetTargetWidth(), Renderer::GetTargetHeight(), PixelShaderCache::GetColorCopyProgram(false), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), nullptr, Gamma, 1); - - D3D::context->RSSetViewports(1, &vp); - } - else if (g_ActiveConfig.iStereoMode == STEREO_3DVISION) - { - if (!s_3d_vision_texture) - Create3DVisionTexture(s_backbuffer_width, s_backbuffer_height); - - D3D11_VIEWPORT leftVp = CD3D11_VIEWPORT((float)X, (float)Y, (float)Width, (float)Height); - D3D11_VIEWPORT rightVp = CD3D11_VIEWPORT((float)(X + s_backbuffer_width), (float)Y, (float)Width, (float)Height); - - // Render to staging texture which is double the width of the backbuffer - D3D::context->OMSetRenderTargets(1, &s_3d_vision_texture->GetRTV(), nullptr); - - D3D::context->RSSetViewports(1, &leftVp); - D3D::drawShadedTexQuad(read_texture->GetSRV(), targetRc.AsRECT(), Renderer::GetTargetWidth(), Renderer::GetTargetHeight(), PixelShaderCache::GetColorCopyProgram(false), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), nullptr, Gamma, 0); - - D3D::context->RSSetViewports(1, &rightVp); - D3D::drawShadedTexQuad(read_texture->GetSRV(), targetRc.AsRECT(), Renderer::GetTargetWidth(), Renderer::GetTargetHeight(), PixelShaderCache::GetColorCopyProgram(false), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), nullptr, Gamma, 1); - - // Copy the left eye to the backbuffer, if Nvidia 3D Vision is enabled it should - // recognize the signature and automatically include the right eye frame. - D3D11_BOX box = CD3D11_BOX(0, 0, 0, s_backbuffer_width, s_backbuffer_height, 1); - D3D::context->CopySubresourceRegion(D3D::GetBackBuffer()->GetTex(), 0, 0, 0, 0, s_3d_vision_texture->GetTex(), 0, &box); - - D3D::context->RSSetViewports(1, &vp); - D3D::context->OMSetRenderTargets(1, &D3D::GetBackBuffer()->GetRTV(), nullptr); - } - else - { - D3D::drawShadedTexQuad(read_texture->GetSRV(), targetRc.AsRECT(), Renderer::GetTargetWidth(), Renderer::GetTargetHeight(), (g_Config.iStereoMode == STEREO_ANAGLYPH) ? PixelShaderCache::GetAnaglyphProgram() : PixelShaderCache::GetColorCopyProgram(false), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), nullptr, Gamma); - } + BlitScreen(sourceRc, targetRc, read_texture, GetTargetWidth(), GetTargetHeight(), Gamma); } // done with drawing the game stuff, good moment to save a screenshot @@ -911,7 +844,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co } // Reset viewport for drawing text - vp = CD3D11_VIEWPORT(0.0f, 0.0f, (float)GetBackbufferWidth(), (float)GetBackbufferHeight()); + D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.0f, 0.0f, (float)GetBackbufferWidth(), (float)GetBackbufferHeight()); D3D::context->RSSetViewports(1, &vp); Renderer::DrawDebugText(); @@ -1279,4 +1212,53 @@ void Renderer::BBoxWrite(int index, u16 _value) BBox::Set(index, value); } +void Renderer::BlitScreen(TargetRectangle src, TargetRectangle dst, D3DTexture2D* src_texture, u32 src_width, u32 src_height, float Gamma) +{ + if (g_ActiveConfig.iStereoMode == STEREO_SBS || g_ActiveConfig.iStereoMode == STEREO_TAB) + { + TargetRectangle leftRc, rightRc; + ConvertStereoRectangle(dst, leftRc, rightRc); + + D3D11_VIEWPORT leftVp = CD3D11_VIEWPORT((float)leftRc.left, (float)leftRc.top, (float)leftRc.GetWidth(), (float)leftRc.GetHeight()); + D3D11_VIEWPORT rightVp = CD3D11_VIEWPORT((float)rightRc.left, (float)rightRc.top, (float)rightRc.GetWidth(), (float)rightRc.GetHeight()); + + D3D::context->RSSetViewports(1, &leftVp); + D3D::drawShadedTexQuad(src_texture->GetSRV(), src.AsRECT(), src_width, src_height, PixelShaderCache::GetColorCopyProgram(false), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), nullptr, Gamma, 0); + + D3D::context->RSSetViewports(1, &rightVp); + D3D::drawShadedTexQuad(src_texture->GetSRV(), src.AsRECT(), src_width, src_height, PixelShaderCache::GetColorCopyProgram(false), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), nullptr, Gamma, 1); + } + else if (g_ActiveConfig.iStereoMode == STEREO_3DVISION) + { + if (!s_3d_vision_texture) + Create3DVisionTexture(s_backbuffer_width, s_backbuffer_height); + + D3D11_VIEWPORT leftVp = CD3D11_VIEWPORT((float)dst.left, (float)dst.top, (float)dst.GetWidth(), (float)dst.GetHeight()); + D3D11_VIEWPORT rightVp = CD3D11_VIEWPORT((float)(dst.left + s_backbuffer_width), (float)dst.top, (float)dst.GetWidth(), (float)dst.GetHeight()); + + // Render to staging texture which is double the width of the backbuffer + D3D::context->OMSetRenderTargets(1, &s_3d_vision_texture->GetRTV(), nullptr); + + D3D::context->RSSetViewports(1, &leftVp); + D3D::drawShadedTexQuad(src_texture->GetSRV(), src.AsRECT(), src_width, src_height, PixelShaderCache::GetColorCopyProgram(false), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), nullptr, Gamma, 0); + + D3D::context->RSSetViewports(1, &rightVp); + D3D::drawShadedTexQuad(src_texture->GetSRV(), src.AsRECT(), src_width, src_height, PixelShaderCache::GetColorCopyProgram(false), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), nullptr, Gamma, 1); + + // Copy the left eye to the backbuffer, if Nvidia 3D Vision is enabled it should + // recognize the signature and automatically include the right eye frame. + D3D11_BOX box = CD3D11_BOX(0, 0, 0, s_backbuffer_width, s_backbuffer_height, 1); + D3D::context->CopySubresourceRegion(D3D::GetBackBuffer()->GetTex(), 0, 0, 0, 0, s_3d_vision_texture->GetTex(), 0, &box); + + // Restore render target to backbuffer + D3D::context->OMSetRenderTargets(1, &D3D::GetBackBuffer()->GetRTV(), nullptr); + } + else + { + D3D11_VIEWPORT vp = CD3D11_VIEWPORT((float)dst.left, (float)dst.top, (float)dst.GetWidth(), (float)dst.GetHeight()); + D3D::context->RSSetViewports(1, &vp); + D3D::drawShadedTexQuad(src_texture->GetSRV(), src.AsRECT(), src_width, src_height, (g_Config.iStereoMode == STEREO_ANAGLYPH) ? PixelShaderCache::GetAnaglyphProgram() : PixelShaderCache::GetColorCopyProgram(false), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), nullptr, Gamma); + } +} + } // namespace DX11 diff --git a/Source/Core/VideoBackends/D3D/Render.h b/Source/Core/VideoBackends/D3D/Render.h index 33e3cf0681..020dc9d85a 100644 --- a/Source/Core/VideoBackends/D3D/Render.h +++ b/Source/Core/VideoBackends/D3D/Render.h @@ -52,6 +52,9 @@ public: static bool CheckForResize(); int GetMaxTextureSize() override; + +private: + void BlitScreen(TargetRectangle src, TargetRectangle dst, D3DTexture2D* src_texture, u32 src_width, u32 src_height, float Gamma); }; } diff --git a/Source/Core/VideoBackends/D3D/XFBEncoder.cpp b/Source/Core/VideoBackends/D3D/XFBEncoder.cpp index 955fb38bc8..9e95e1ea74 100644 --- a/Source/Core/VideoBackends/D3D/XFBEncoder.cpp +++ b/Source/Core/VideoBackends/D3D/XFBEncoder.cpp @@ -78,7 +78,7 @@ static const char XFB_ENCODE_PS[] = "} Params;\n" "}\n" -"Texture2D EFBTexture : register(t0);\n" +"Texture2DArray EFBTexture : register(t0);\n" "sampler EFBSampler : register(s0);\n" // GameCube/Wii uses the BT.601 standard algorithm for converting to YCbCr; see @@ -92,7 +92,7 @@ static const char XFB_ENCODE_PS[] = "float3 SampleEFB(float2 coord)\n" "{\n" "float2 texCoord = lerp(float2(Params.TexLeft,Params.TexTop), float2(Params.TexRight,Params.TexBottom), coord / float2(Params.Width,Params.Height));\n" - "return EFBTexture.Sample(EFBSampler, texCoord).rgb;\n" + "return EFBTexture.Sample(EFBSampler, float3(texCoord, 0)).rgb;\n" "}\n" "void main(out float4 ocol0 : SV_Target, in float4 Pos : SV_Position, in float2 Coord : ENCODECOORD)\n" @@ -311,7 +311,7 @@ void XFBEncoder::Encode(u8* dst, u32 width, u32 height, const EFBRectangle& srcR D3D::context->OMSetRenderTargets(1, &m_outRTV, nullptr); - ID3D11ShaderResourceView* pEFB = FramebufferManager::GetEFBColorTexture()->GetSRV(); + ID3D11ShaderResourceView* pEFB = FramebufferManager::GetResolvedEFBColorTexture()->GetSRV(); D3D::stateman->SetVertexConstants(m_encodeParams); D3D::stateman->SetPixelConstants(m_encodeParams); diff --git a/Source/Core/VideoBackends/OGL/FramebufferManager.cpp b/Source/Core/VideoBackends/OGL/FramebufferManager.cpp index 731cf389d2..9a238fc23f 100644 --- a/Source/Core/VideoBackends/OGL/FramebufferManager.cpp +++ b/Source/Core/VideoBackends/OGL/FramebufferManager.cpp @@ -509,17 +509,20 @@ void XFBSource::CopyEFB(float Gamma) g_renderer->ResetAPIState(); // Copy EFB data to XFB and restore render target again - glBindFramebuffer(GL_READ_FRAMEBUFFER, FramebufferManager::GetEFBFramebuffer()); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FramebufferManager::GetXFBFramebuffer()); - // Bind texture. - FramebufferManager::FramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_ARRAY, texture, 0); + for (int i = 0; i < m_layers; i++) + { + // Bind EFB and texture layer + glBindFramebuffer(GL_READ_FRAMEBUFFER, FramebufferManager::GetEFBFramebuffer(i)); + glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0, i); - glBlitFramebuffer( - 0, 0, texWidth, texHeight, - 0, 0, texWidth, texHeight, - GL_COLOR_BUFFER_BIT, GL_NEAREST - ); + glBlitFramebuffer( + 0, 0, texWidth, texHeight, + 0, 0, texWidth, texHeight, + GL_COLOR_BUFFER_BIT, GL_NEAREST + ); + } // Return to EFB. FramebufferManager::SetFramebuffer(0); @@ -528,7 +531,7 @@ void XFBSource::CopyEFB(float Gamma) } -XFBSourceBase* FramebufferManager::CreateXFBSource(unsigned int target_width, unsigned int target_height) +XFBSourceBase* FramebufferManager::CreateXFBSource(unsigned int target_width, unsigned int target_height, unsigned int layers) { GLuint texture; @@ -537,12 +540,12 @@ XFBSourceBase* FramebufferManager::CreateXFBSource(unsigned int target_width, un glActiveTexture(GL_TEXTURE0 + 9); glBindTexture(GL_TEXTURE_2D_ARRAY, texture); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 0); - glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, target_width, target_height, m_EFBLayers, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, target_width, target_height, layers, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); - return new XFBSource(texture, m_EFBLayers); + return new XFBSource(texture, layers); } -void FramebufferManager::GetTargetSize(unsigned int *width, unsigned int *height, const EFBRectangle& sourceRc) +void FramebufferManager::GetTargetSize(unsigned int *width, unsigned int *height) { *width = m_targetWidth; *height = m_targetHeight; diff --git a/Source/Core/VideoBackends/OGL/FramebufferManager.h b/Source/Core/VideoBackends/OGL/FramebufferManager.h index ffc2970ee6..9b26e32335 100644 --- a/Source/Core/VideoBackends/OGL/FramebufferManager.h +++ b/Source/Core/VideoBackends/OGL/FramebufferManager.h @@ -68,7 +68,7 @@ public: static GLuint GetEFBColorTexture(const EFBRectangle& sourceRc); static GLuint GetEFBDepthTexture(const EFBRectangle& sourceRc); - static GLuint GetEFBFramebuffer() { return m_efbFramebuffer[0]; } + static GLuint GetEFBFramebuffer(unsigned int layer = 0) { return (layer < m_EFBLayers) ? m_efbFramebuffer[layer] : m_efbFramebuffer[m_EFBLayers - 1]; } static GLuint GetXFBFramebuffer() { return m_xfbFramebuffer; } // Resolved framebuffer is only used in MSAA mode. @@ -92,8 +92,8 @@ public: static void ReinterpretPixelData(unsigned int convtype); private: - XFBSourceBase* CreateXFBSource(unsigned int target_width, unsigned int target_height) override; - void GetTargetSize(unsigned int *width, unsigned int *height, const EFBRectangle& sourceRc) override; + XFBSourceBase* CreateXFBSource(unsigned int target_width, unsigned int target_height, unsigned int layers) override; + void GetTargetSize(unsigned int *width, unsigned int *height) override; void CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma) override; diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp index a03f8cd61d..2def435a11 100644 --- a/Source/Core/VideoBackends/OGL/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Render.cpp @@ -1270,6 +1270,22 @@ void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaE ClearEFBCache(); } +void Renderer::BlitScreen(TargetRectangle src, TargetRectangle dst, GLuint src_texture, int src_width, int src_height) +{ + if (g_ActiveConfig.iStereoMode == STEREO_SBS || g_ActiveConfig.iStereoMode == STEREO_TAB) + { + TargetRectangle leftRc, rightRc; + ConvertStereoRectangle(dst, leftRc, rightRc); + + m_post_processor->BlitFromTexture(src, leftRc, src_texture, src_width, src_height, 0); + m_post_processor->BlitFromTexture(src, rightRc, src_texture, src_width, src_height, 1); + } + else + { + m_post_processor->BlitFromTexture(src, dst, src_texture, src_width, src_height); + } +} + void Renderer::ReinterpretPixelData(unsigned int convtype) { if (convtype == 0 || convtype == 2) @@ -1473,8 +1489,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co sourceRc.right -= fbStride - fbWidth; - // TODO: Virtual XFB stereoscopic 3D support. - m_post_processor->BlitFromTexture(sourceRc, drawRc, xfbSource->texture, xfbSource->texWidth, xfbSource->texHeight, 1); + BlitScreen(sourceRc, drawRc, xfbSource->texture, xfbSource->texWidth, xfbSource->texHeight); } } else @@ -1483,19 +1498,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co // for msaa mode, we must resolve the efb content to non-msaa GLuint tex = FramebufferManager::ResolveAndGetRenderTarget(rc); - - if (g_ActiveConfig.iStereoMode == STEREO_SBS || g_ActiveConfig.iStereoMode == STEREO_TAB) - { - TargetRectangle leftRc, rightRc; - ConvertStereoRectangle(flipped_trc, leftRc, rightRc); - - m_post_processor->BlitFromTexture(targetRc, leftRc, tex, s_target_width, s_target_height, 0); - m_post_processor->BlitFromTexture(targetRc, rightRc, tex, s_target_width, s_target_height, 1); - } - else - { - m_post_processor->BlitFromTexture(targetRc, flipped_trc, tex, s_target_width, s_target_height); - } + BlitScreen(targetRc, flipped_trc, tex, s_target_width, s_target_height); } glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); diff --git a/Source/Core/VideoBackends/OGL/Render.h b/Source/Core/VideoBackends/OGL/Render.h index b536d1cecb..cfa01a2e6f 100644 --- a/Source/Core/VideoBackends/OGL/Render.h +++ b/Source/Core/VideoBackends/OGL/Render.h @@ -91,6 +91,8 @@ public: private: void UpdateEFBCache(EFBAccessType type, u32 cacheRectIdx, const EFBRectangle& efbPixelRc, const TargetRectangle& targetPixelRc, const u32* data); + + void BlitScreen(TargetRectangle src, TargetRectangle dst, GLuint src_texture, int src_width, int src_height); }; } diff --git a/Source/Core/VideoCommon/FramebufferManagerBase.cpp b/Source/Core/VideoCommon/FramebufferManagerBase.cpp index e2a09c6527..178a157f9a 100644 --- a/Source/Core/VideoCommon/FramebufferManagerBase.cpp +++ b/Source/Core/VideoCommon/FramebufferManagerBase.cpp @@ -56,7 +56,7 @@ const XFBSourceBase* const* FramebufferManagerBase::GetRealXFBSource(u32 xfbAddr } if (!m_realXFBSource) - m_realXFBSource = g_framebuffer_manager->CreateXFBSource(fbWidth, fbHeight); + m_realXFBSource = g_framebuffer_manager->CreateXFBSource(fbWidth, fbHeight, 1); m_realXFBSource->srcAddr = xfbAddr; @@ -66,7 +66,6 @@ const XFBSourceBase* const* FramebufferManagerBase::GetRealXFBSource(u32 xfbAddr m_realXFBSource->texWidth = fbWidth; m_realXFBSource->texHeight = fbHeight; - // TODO: stuff only used by OGL... :/ // OpenGL texture coordinates originate at the lower left, which is why // sourceRc.top = fbHeight and sourceRc.bottom = 0. m_realXFBSource->sourceRc.left = 0; @@ -147,7 +146,7 @@ void FramebufferManagerBase::CopyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHe m_virtualXFBList.splice(m_virtualXFBList.begin(), m_virtualXFBList, vxfb); unsigned int target_width, target_height; - g_framebuffer_manager->GetTargetSize(&target_width, &target_height, sourceRc); + g_framebuffer_manager->GetTargetSize(&target_width, &target_height); // recreate if needed if (vxfb->xfbSource && (vxfb->xfbSource->texWidth != target_width || vxfb->xfbSource->texHeight != target_height)) @@ -158,7 +157,7 @@ void FramebufferManagerBase::CopyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHe if (!vxfb->xfbSource) { - vxfb->xfbSource = g_framebuffer_manager->CreateXFBSource(target_width, target_height); + vxfb->xfbSource = g_framebuffer_manager->CreateXFBSource(target_width, target_height, m_EFBLayers); vxfb->xfbSource->texWidth = target_width; vxfb->xfbSource->texHeight = target_height; } @@ -234,7 +233,7 @@ void FramebufferManagerBase::ReplaceVirtualXFB() } } -int FramebufferManagerBase::ScaleToVirtualXfbWidth(int x, unsigned int backbuffer_width) +int FramebufferManagerBase::ScaleToVirtualXfbWidth(int x) { if (g_ActiveConfig.RealXFBEnabled()) return x; @@ -242,7 +241,7 @@ int FramebufferManagerBase::ScaleToVirtualXfbWidth(int x, unsigned int backbuffe return x * (int)Renderer::GetTargetRectangle().GetWidth() / (int)FramebufferManagerBase::LastXfbWidth(); } -int FramebufferManagerBase::ScaleToVirtualXfbHeight(int y, unsigned int backbuffer_height) +int FramebufferManagerBase::ScaleToVirtualXfbHeight(int y) { if (g_ActiveConfig.RealXFBEnabled()) return y; diff --git a/Source/Core/VideoCommon/FramebufferManagerBase.h b/Source/Core/VideoCommon/FramebufferManagerBase.h index 592338e43c..661cfb7f31 100644 --- a/Source/Core/VideoCommon/FramebufferManagerBase.h +++ b/Source/Core/VideoCommon/FramebufferManagerBase.h @@ -13,9 +13,6 @@ struct XFBSourceBase { virtual ~XFBSourceBase() {} - virtual void Draw(const MathUtil::Rectangle &sourcerc, - const MathUtil::Rectangle &drawrc) const {}; - virtual void DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight) = 0; virtual void CopyEFB(float Gamma) = 0; @@ -52,8 +49,8 @@ public: static unsigned int LastXfbWidth() { return s_last_xfb_width; } static unsigned int LastXfbHeight() { return s_last_xfb_height; } - static int ScaleToVirtualXfbWidth(int x, unsigned int backbuffer_width); - static int ScaleToVirtualXfbHeight(int y, unsigned int backbuffer_height); + static int ScaleToVirtualXfbWidth(int x); + static int ScaleToVirtualXfbHeight(int y); static unsigned int GetEFBLayers() { return m_EFBLayers; } @@ -75,9 +72,9 @@ protected: static unsigned int m_EFBLayers; private: - virtual XFBSourceBase* CreateXFBSource(unsigned int target_width, unsigned int target_height) = 0; + virtual XFBSourceBase* CreateXFBSource(unsigned int target_width, unsigned int target_height, unsigned int layers) = 0; // TODO: figure out why OGL is different for this guy - virtual void GetTargetSize(unsigned int *width, unsigned int *height, const EFBRectangle& sourceRc) = 0; + virtual void GetTargetSize(unsigned int *width, unsigned int *height) = 0; static VirtualXFBListType::iterator FindVirtualXFB(u32 xfbAddr, u32 width, u32 height); diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp index 8db728842f..50778172cf 100644 --- a/Source/Core/VideoCommon/RenderBase.cpp +++ b/Source/Core/VideoCommon/RenderBase.cpp @@ -136,7 +136,7 @@ int Renderer::EFBToScaledX(int x) switch (g_ActiveConfig.iEFBScale) { case SCALE_AUTO: // fractional - return FramebufferManagerBase::ScaleToVirtualXfbWidth(x, s_backbuffer_width); + return FramebufferManagerBase::ScaleToVirtualXfbWidth(x); default: return x * (int)efb_scale_numeratorX / (int)efb_scale_denominatorX; @@ -148,7 +148,7 @@ int Renderer::EFBToScaledY(int y) switch (g_ActiveConfig.iEFBScale) { case SCALE_AUTO: // fractional - return FramebufferManagerBase::ScaleToVirtualXfbHeight(y, s_backbuffer_height); + return FramebufferManagerBase::ScaleToVirtualXfbHeight(y); default: return y * (int)efb_scale_numeratorY / (int)efb_scale_denominatorY; @@ -180,8 +180,8 @@ bool Renderer::CalculateTargetSize(unsigned int framebuffer_width, unsigned int { case SCALE_AUTO: case SCALE_AUTO_INTEGRAL: - newEFBWidth = FramebufferManagerBase::ScaleToVirtualXfbWidth(EFB_WIDTH, framebuffer_width); - newEFBHeight = FramebufferManagerBase::ScaleToVirtualXfbHeight(EFB_HEIGHT, framebuffer_height); + newEFBWidth = FramebufferManagerBase::ScaleToVirtualXfbWidth(EFB_WIDTH); + newEFBHeight = FramebufferManagerBase::ScaleToVirtualXfbHeight(EFB_HEIGHT); if (s_LastEFBScale == SCALE_AUTO_INTEGRAL) { diff --git a/Source/Core/VideoCommon/VideoConfig.cpp b/Source/Core/VideoCommon/VideoConfig.cpp index d4cff3ec42..867a97895f 100644 --- a/Source/Core/VideoCommon/VideoConfig.cpp +++ b/Source/Core/VideoCommon/VideoConfig.cpp @@ -217,10 +217,19 @@ void VideoConfig::VerifyValidity() if (iAdapter < 0 || iAdapter > ((int)backend_info.Adapters.size() - 1)) iAdapter = 0; if (iMultisampleMode < 0 || iMultisampleMode >= (int)backend_info.AAModes.size()) iMultisampleMode = 0; - if (iStereoMode > 0 && !backend_info.bSupportsGeometryShaders) + if (iStereoMode > 0) { - OSD::AddMessage("Stereoscopic 3D isn't supported by your GPU, support for OpenGL 3.2 is required.", 10000); - iStereoMode = 0; + if (!backend_info.bSupportsGeometryShaders) + { + OSD::AddMessage("Stereoscopic 3D isn't supported by your GPU, support for OpenGL 3.2 is required.", 10000); + iStereoMode = 0; + } + + if (bUseRealXFB) + { + OSD::AddMessage("Stereoscopic 3D isn't supported with Real XFB, turning off stereoscopy.", 10000); + iStereoMode = 0; + } } }