diff --git a/Source/Core/VideoBackends/D3D/Src/Render.cpp b/Source/Core/VideoBackends/D3D/Src/Render.cpp index d58cc59e98..7f9218de11 100644 --- a/Source/Core/VideoBackends/D3D/Src/Render.cpp +++ b/Source/Core/VideoBackends/D3D/Src/Render.cpp @@ -513,50 +513,38 @@ void Renderer::UpdateViewport(Matrix44& vpCorrection) int scissorXOff = bpmem.scissorOffset.x * 2; int scissorYOff = bpmem.scissorOffset.y * 2; - // TODO: ceil, floor or just cast to int? - // TODO: Directly use the floats instead of rounding them? - int intendedX = Renderer::EFBToScaledX((int)ceil(xfregs.viewport.xOrig - xfregs.viewport.wd - scissorXOff)); - int intendedY = Renderer::EFBToScaledY((int)ceil(xfregs.viewport.yOrig + xfregs.viewport.ht - scissorYOff)); - int intendedWd = Renderer::EFBToScaledX((int)ceil(2.0f * xfregs.viewport.wd)); - int intendedHt = Renderer::EFBToScaledY((int)ceil(-2.0f * xfregs.viewport.ht)); - if (intendedWd < 0) + float intendedX = Renderer::EFBToScaledXf(xfregs.viewport.xOrig - xfregs.viewport.wd - scissorXOff); + float intendedY = Renderer::EFBToScaledYf(xfregs.viewport.yOrig + xfregs.viewport.ht - scissorYOff); + float intendedWd = Renderer::EFBToScaledXf(2.0f * xfregs.viewport.wd); + float intendedHt = Renderer::EFBToScaledYf(-2.0f * xfregs.viewport.ht); + if (intendedWd < 0.f) { intendedX += intendedWd; intendedWd = -intendedWd; } - if (intendedHt < 0) + if (intendedHt < 0.f) { intendedY += intendedHt; intendedHt = -intendedHt; } // In D3D, the viewport rectangle must fit within the render target. - int X = intendedX; - if (X < 0) - X = 0; + float X = (intendedX >= 0.f) ? intendedX : 0.f; + float Y = (intendedY >= 0.f) ? intendedY : 0.f; + float Wd = (X + intendedWd <= GetTargetWidth()) ? intendedWd : (GetTargetWidth() - X); + float Ht = (Y + intendedHt <= GetTargetHeight()) ? intendedHt : (GetTargetHeight() - Y); - int Y = intendedY; - if (Y < 0) - Y = 0; - - int Wd = intendedWd; - if (X + Wd > GetTargetWidth()) - Wd = GetTargetWidth() - X; - int Ht = intendedHt; - if (Y + Ht > GetTargetHeight()) - Ht = GetTargetHeight() - Y; - // If GX viewport is off the render target, we must clamp our viewport // within the bounds. Use the correction matrix to compensate. ViewportCorrectionMatrix(vpCorrection, - (float)intendedX, (float)intendedY, - (float)intendedWd, (float)intendedHt, - (float)X, (float)Y, - (float)Wd, (float)Ht); + intendedX, intendedY, + intendedWd, intendedHt, + X, Y, + Wd, Ht); // Some games set invalid values for z-min and z-max so fix them to the max and min allowed and let the shaders do this work - D3D11_VIEWPORT vp = CD3D11_VIEWPORT((float)X, (float)Y, - (float)Wd, (float)Ht, + D3D11_VIEWPORT vp = CD3D11_VIEWPORT(X, Y, + Wd, Ht, 0.f, // (xfregs.viewport.farZ - xfregs.viewport.zRange) / 16777216.0f; 1.f); // xfregs.viewport.farZ / 16777216.0f; D3D::context->RSSetViewports(1, &vp); diff --git a/Source/Core/VideoBackends/OGL/Src/GLUtil.h b/Source/Core/VideoBackends/OGL/Src/GLUtil.h index 54a2ac5735..4dbbd06e05 100644 --- a/Source/Core/VideoBackends/OGL/Src/GLUtil.h +++ b/Source/Core/VideoBackends/OGL/Src/GLUtil.h @@ -33,6 +33,7 @@ #define glDrawElementsBaseVertex(...) #define glDrawRangeElementsBaseVertex(...) #define glRenderbufferStorageMultisampleCoverageNV(...) +#define glViewportIndexedf(...) #endif #else #define TEX2D GL_TEXTURE_RECTANGLE_ARB diff --git a/Source/Core/VideoBackends/OGL/Src/Render.cpp b/Source/Core/VideoBackends/OGL/Src/Render.cpp index 4dca112031..e507fc45cd 100644 --- a/Source/Core/VideoBackends/OGL/Src/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Src/Render.cpp @@ -386,6 +386,7 @@ Renderer::Renderer() g_ogl_config.bSupportCoverageMSAA = false; // XXX: GLES3 spec has MSAA g_ogl_config.bSupportSampleShading = false; g_ogl_config.bSupportOGL31 = false; + g_ogl_config.bSupportViewportFloat = false; if (DriverDetails::HasBug(DriverDetails::BUG_ISTEGRA) || DriverDetails::HasBug(DriverDetails::BUG_ISPOWERVR)) g_ogl_config.eSupportedGLSLVersion = GLSLES2; else @@ -496,6 +497,7 @@ Renderer::Renderer() g_ogl_config.bSupportCoverageMSAA = GLEW_NV_framebuffer_multisample_coverage; g_ogl_config.bSupportSampleShading = GLEW_ARB_sample_shading; g_ogl_config.bSupportOGL31 = GLEW_VERSION_3_1; + g_ogl_config.bSupportViewportFloat = GLEW_ARB_viewport_array; if(strstr(g_ogl_config.glsl_version, "1.00") || strstr(g_ogl_config.glsl_version, "1.10") || strstr(g_ogl_config.glsl_version, "1.20")) { @@ -1105,12 +1107,12 @@ void Renderer::UpdateViewport(Matrix44& vpCorrection) int scissorYOff = bpmem.scissorOffset.y * 2; // TODO: ceil, floor or just cast to int? - int X = EFBToScaledX((int)ceil(xfregs.viewport.xOrig - xfregs.viewport.wd - (float)scissorXOff)); - int Y = EFBToScaledY((int)ceil((float)EFB_HEIGHT - xfregs.viewport.yOrig + xfregs.viewport.ht + (float)scissorYOff)); - int Width = EFBToScaledX((int)ceil(2.0f * xfregs.viewport.wd)); - int Height = EFBToScaledY((int)ceil(-2.0f * xfregs.viewport.ht)); - double GLNear = (xfregs.viewport.farZ - xfregs.viewport.zRange) / 16777216.0f; - double GLFar = xfregs.viewport.farZ / 16777216.0f; + float X = EFBToScaledXf(xfregs.viewport.xOrig - xfregs.viewport.wd - (float)scissorXOff); + float Y = EFBToScaledYf((float)EFB_HEIGHT - xfregs.viewport.yOrig + xfregs.viewport.ht + (float)scissorYOff); + float Width = EFBToScaledXf(2.0f * xfregs.viewport.wd); + float Height = EFBToScaledYf(-2.0f * xfregs.viewport.ht); + float GLNear = (xfregs.viewport.farZ - xfregs.viewport.zRange) / 16777216.0f; + float GLFar = xfregs.viewport.farZ / 16777216.0f; if (Width < 0) { X += Width; @@ -1126,7 +1128,14 @@ void Renderer::UpdateViewport(Matrix44& vpCorrection) Matrix44::LoadIdentity(vpCorrection); // Update the view port - glViewport(X, Y, Width, Height); + if(g_ogl_config.bSupportViewportFloat) + { + glViewportIndexedf(0, X, Y, Width, Height); + } + else + { + glViewport(round(X), round(Y), round(Width), round(Height)); + } glDepthRangef(GLNear, GLFar); } diff --git a/Source/Core/VideoBackends/OGL/Src/Render.h b/Source/Core/VideoBackends/OGL/Src/Render.h index 8c6a8ca8f8..efafb8708d 100644 --- a/Source/Core/VideoBackends/OGL/Src/Render.h +++ b/Source/Core/VideoBackends/OGL/Src/Render.h @@ -27,6 +27,7 @@ extern struct VideoConfig { bool bSupportSampleShading; GLSL_VERSION eSupportedGLSLVersion; bool bSupportOGL31; + bool bSupportViewportFloat; const char *gl_vendor; const char *gl_renderer;