Merge branch 'viewport_float'

This commit is contained in:
degasus 2013-10-29 18:33:56 +01:00
commit 0002236e3e
4 changed files with 34 additions and 35 deletions

View File

@ -513,50 +513,38 @@ void Renderer::UpdateViewport(Matrix44& vpCorrection)
int scissorXOff = bpmem.scissorOffset.x * 2; int scissorXOff = bpmem.scissorOffset.x * 2;
int scissorYOff = bpmem.scissorOffset.y * 2; int scissorYOff = bpmem.scissorOffset.y * 2;
// TODO: ceil, floor or just cast to int? float intendedX = Renderer::EFBToScaledXf(xfregs.viewport.xOrig - xfregs.viewport.wd - scissorXOff);
// TODO: Directly use the floats instead of rounding them? float intendedY = Renderer::EFBToScaledYf(xfregs.viewport.yOrig + xfregs.viewport.ht - scissorYOff);
int intendedX = Renderer::EFBToScaledX((int)ceil(xfregs.viewport.xOrig - xfregs.viewport.wd - scissorXOff)); float intendedWd = Renderer::EFBToScaledXf(2.0f * xfregs.viewport.wd);
int intendedY = Renderer::EFBToScaledY((int)ceil(xfregs.viewport.yOrig + xfregs.viewport.ht - scissorYOff)); float intendedHt = Renderer::EFBToScaledYf(-2.0f * xfregs.viewport.ht);
int intendedWd = Renderer::EFBToScaledX((int)ceil(2.0f * xfregs.viewport.wd)); if (intendedWd < 0.f)
int intendedHt = Renderer::EFBToScaledY((int)ceil(-2.0f * xfregs.viewport.ht));
if (intendedWd < 0)
{ {
intendedX += intendedWd; intendedX += intendedWd;
intendedWd = -intendedWd; intendedWd = -intendedWd;
} }
if (intendedHt < 0) if (intendedHt < 0.f)
{ {
intendedY += intendedHt; intendedY += intendedHt;
intendedHt = -intendedHt; intendedHt = -intendedHt;
} }
// In D3D, the viewport rectangle must fit within the render target. // In D3D, the viewport rectangle must fit within the render target.
int X = intendedX; float X = (intendedX >= 0.f) ? intendedX : 0.f;
if (X < 0) float Y = (intendedY >= 0.f) ? intendedY : 0.f;
X = 0; 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 // If GX viewport is off the render target, we must clamp our viewport
// within the bounds. Use the correction matrix to compensate. // within the bounds. Use the correction matrix to compensate.
ViewportCorrectionMatrix(vpCorrection, ViewportCorrectionMatrix(vpCorrection,
(float)intendedX, (float)intendedY, intendedX, intendedY,
(float)intendedWd, (float)intendedHt, intendedWd, intendedHt,
(float)X, (float)Y, X, Y,
(float)Wd, (float)Ht); 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 // 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, D3D11_VIEWPORT vp = CD3D11_VIEWPORT(X, Y,
(float)Wd, (float)Ht, Wd, Ht,
0.f, // (xfregs.viewport.farZ - xfregs.viewport.zRange) / 16777216.0f; 0.f, // (xfregs.viewport.farZ - xfregs.viewport.zRange) / 16777216.0f;
1.f); // xfregs.viewport.farZ / 16777216.0f; 1.f); // xfregs.viewport.farZ / 16777216.0f;
D3D::context->RSSetViewports(1, &vp); D3D::context->RSSetViewports(1, &vp);

View File

@ -33,6 +33,7 @@
#define glDrawElementsBaseVertex(...) #define glDrawElementsBaseVertex(...)
#define glDrawRangeElementsBaseVertex(...) #define glDrawRangeElementsBaseVertex(...)
#define glRenderbufferStorageMultisampleCoverageNV(...) #define glRenderbufferStorageMultisampleCoverageNV(...)
#define glViewportIndexedf(...)
#endif #endif
#else #else
#define TEX2D GL_TEXTURE_RECTANGLE_ARB #define TEX2D GL_TEXTURE_RECTANGLE_ARB

View File

@ -386,6 +386,7 @@ Renderer::Renderer()
g_ogl_config.bSupportCoverageMSAA = false; // XXX: GLES3 spec has MSAA g_ogl_config.bSupportCoverageMSAA = false; // XXX: GLES3 spec has MSAA
g_ogl_config.bSupportSampleShading = false; g_ogl_config.bSupportSampleShading = false;
g_ogl_config.bSupportOGL31 = false; g_ogl_config.bSupportOGL31 = false;
g_ogl_config.bSupportViewportFloat = false;
if (DriverDetails::HasBug(DriverDetails::BUG_ISTEGRA) || DriverDetails::HasBug(DriverDetails::BUG_ISPOWERVR)) if (DriverDetails::HasBug(DriverDetails::BUG_ISTEGRA) || DriverDetails::HasBug(DriverDetails::BUG_ISPOWERVR))
g_ogl_config.eSupportedGLSLVersion = GLSLES2; g_ogl_config.eSupportedGLSLVersion = GLSLES2;
else else
@ -496,6 +497,7 @@ Renderer::Renderer()
g_ogl_config.bSupportCoverageMSAA = GLEW_NV_framebuffer_multisample_coverage; g_ogl_config.bSupportCoverageMSAA = GLEW_NV_framebuffer_multisample_coverage;
g_ogl_config.bSupportSampleShading = GLEW_ARB_sample_shading; g_ogl_config.bSupportSampleShading = GLEW_ARB_sample_shading;
g_ogl_config.bSupportOGL31 = GLEW_VERSION_3_1; 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")) 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; int scissorYOff = bpmem.scissorOffset.y * 2;
// TODO: ceil, floor or just cast to int? // TODO: ceil, floor or just cast to int?
int X = EFBToScaledX((int)ceil(xfregs.viewport.xOrig - xfregs.viewport.wd - (float)scissorXOff)); float X = EFBToScaledXf(xfregs.viewport.xOrig - xfregs.viewport.wd - (float)scissorXOff);
int Y = EFBToScaledY((int)ceil((float)EFB_HEIGHT - xfregs.viewport.yOrig + xfregs.viewport.ht + (float)scissorYOff)); float Y = EFBToScaledYf((float)EFB_HEIGHT - xfregs.viewport.yOrig + xfregs.viewport.ht + (float)scissorYOff);
int Width = EFBToScaledX((int)ceil(2.0f * xfregs.viewport.wd)); float Width = EFBToScaledXf(2.0f * xfregs.viewport.wd);
int Height = EFBToScaledY((int)ceil(-2.0f * xfregs.viewport.ht)); float Height = EFBToScaledYf(-2.0f * xfregs.viewport.ht);
double GLNear = (xfregs.viewport.farZ - xfregs.viewport.zRange) / 16777216.0f; float GLNear = (xfregs.viewport.farZ - xfregs.viewport.zRange) / 16777216.0f;
double GLFar = xfregs.viewport.farZ / 16777216.0f; float GLFar = xfregs.viewport.farZ / 16777216.0f;
if (Width < 0) if (Width < 0)
{ {
X += Width; X += Width;
@ -1126,7 +1128,14 @@ void Renderer::UpdateViewport(Matrix44& vpCorrection)
Matrix44::LoadIdentity(vpCorrection); Matrix44::LoadIdentity(vpCorrection);
// Update the view port // 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); glDepthRangef(GLNear, GLFar);
} }

View File

@ -27,6 +27,7 @@ extern struct VideoConfig {
bool bSupportSampleShading; bool bSupportSampleShading;
GLSL_VERSION eSupportedGLSLVersion; GLSL_VERSION eSupportedGLSLVersion;
bool bSupportOGL31; bool bSupportOGL31;
bool bSupportViewportFloat;
const char *gl_vendor; const char *gl_vendor;
const char *gl_renderer; const char *gl_renderer;