Added an ignoreViewport parameter to Renderer::setViewport.

TRAC #22145

Signed-off-by: Nicolas Capens
Signed-off-by: Daniel Koch

git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1518 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index 01d4e55..4ec766a 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -1738,23 +1738,9 @@
     mRenderTargetDesc.format = renderbufferObject->getActualFormat();
     // D3D9_REPLACE end
 
-    Rectangle viewport = mState.viewport;
-    float zNear = clamp01(mState.zNear);
-    float zFar = clamp01(mState.zFar);
-
-    if (ignoreViewport)
-    {
-        viewport.x = 0;
-        viewport.y = 0;
-        viewport.width = mRenderTargetDesc.width;
-        viewport.height = mRenderTargetDesc.height;
-        zNear = 0.0f;
-        zFar = 1.0f;
-    }
-
     ProgramBinary *programBinary = mState.currentProgram ? getCurrentProgramBinary() : NULL;
-
-    if (!mRenderer->setViewport(viewport, zNear, zFar, programBinary, mDxUniformsDirty))
+    if (!mRenderer->setViewport(mState.viewport, mState.zNear, mState.zFar, ignoreViewport,
+                                programBinary, mDxUniformsDirty))
     {
         return false;
     }
diff --git a/src/libGLESv2/renderer/Renderer.h b/src/libGLESv2/renderer/Renderer.h
index c47fbe5..8f0a96d 100644
--- a/src/libGLESv2/renderer/Renderer.h
+++ b/src/libGLESv2/renderer/Renderer.h
@@ -88,7 +88,7 @@
                                       int stencilBackRef, bool frontFaceCCW) = 0;
 
     virtual void setScissorRectangle(const gl::Rectangle &scissor) = 0;
-    virtual bool setViewport(const gl::Rectangle &viewport, float zNear, float zFar,
+    virtual bool setViewport(const gl::Rectangle &viewport, float zNear, float zFar, bool ignoreViewport,
                              gl::ProgramBinary *currentProgram, bool forceSetUniforms) = 0;
 
     virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer) = 0;
diff --git a/src/libGLESv2/renderer/Renderer11.cpp b/src/libGLESv2/renderer/Renderer11.cpp
index 4f36920..befdb15 100644
--- a/src/libGLESv2/renderer/Renderer11.cpp
+++ b/src/libGLESv2/renderer/Renderer11.cpp
@@ -365,32 +365,45 @@
     mForceSetScissor = false;
 }
 
-bool Renderer11::setViewport(const gl::Rectangle &viewport, float zNear, float zFar,
+bool Renderer11::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, bool ignoreViewport,
                              gl::ProgramBinary *currentProgram, bool forceSetUniforms)
 {
-    bool viewportChanged =  mForceSetViewport || memcmp(&viewport, &mCurViewport, sizeof(gl::Rectangle)) != 0 ||
-                            zNear != mCurNear || zFar != mCurFar;
+    gl::Rectangle actualViewport = viewport;
+    float actualZNear = gl::clamp01(zNear);
+    float actualZFar = gl::clamp01(zFar);
+    if (ignoreViewport)
+    {
+        actualViewport.x = 0;
+        actualViewport.y = 0;
+        actualViewport.width = mRenderTargetDesc.width;
+        actualViewport.height = mRenderTargetDesc.height;
+        actualZNear = 0.0f;
+        actualZFar = 1.0f;
+    }
 
     D3D11_VIEWPORT dxViewport;
-    dxViewport.TopLeftX = gl::clamp(viewport.x, 0, static_cast<int>(mRenderTargetDesc.width));
-    dxViewport.TopLeftY = gl::clamp(viewport.y, 0, static_cast<int>(mRenderTargetDesc.height));
-    dxViewport.Width = gl::clamp(viewport.width, 0, static_cast<int>(mRenderTargetDesc.width) - static_cast<int>(dxViewport.TopLeftX));
-    dxViewport.Height = gl::clamp(viewport.height, 0, static_cast<int>(mRenderTargetDesc.height) - static_cast<int>(dxViewport.TopLeftY));
-    dxViewport.MinDepth = zNear;
-    dxViewport.MaxDepth = zFar;
+    dxViewport.TopLeftX = gl::clamp(actualViewport.x, 0, static_cast<int>(mRenderTargetDesc.width));
+    dxViewport.TopLeftY = gl::clamp(actualViewport.y, 0, static_cast<int>(mRenderTargetDesc.height));
+    dxViewport.Width = gl::clamp(actualViewport.width, 0, static_cast<int>(mRenderTargetDesc.width) - static_cast<int>(dxViewport.TopLeftX));
+    dxViewport.Height = gl::clamp(actualViewport.height, 0, static_cast<int>(mRenderTargetDesc.height) - static_cast<int>(dxViewport.TopLeftY));
+    dxViewport.MinDepth = actualZNear;
+    dxViewport.MaxDepth = actualZFar;
 
     if (dxViewport.Width <= 0 || dxViewport.Height <= 0)
     {
         return false;   // Nothing to render
     }
 
+    bool viewportChanged =  mForceSetViewport || memcmp(&actualViewport, &mCurViewport, sizeof(gl::Rectangle)) != 0 ||
+                            actualZNear != mCurNear || actualZFar != mCurFar;
+
     if (viewportChanged)
     {
         mDeviceContext->RSSetViewports(1, &dxViewport);
 
-        mCurViewport = viewport;
-        mCurNear = zNear;
-        mCurFar = zFar;
+        mCurViewport = actualViewport;
+        mCurNear = actualZNear;
+        mCurFar = actualZFar;
     }
 
     if (currentProgram && (viewportChanged || forceSetUniforms))
@@ -401,18 +414,18 @@
 
         // These values are used for computing gl_FragCoord in Program::linkVaryings().
         GLint coord = currentProgram->getDxCoordLocation();
-        GLfloat whxy[4] = { viewport.width  * 0.5f,
-                            viewport.height * 0.5f,
-                            viewport.x + (viewport.width  * 0.5f),
-                            viewport.y + (viewport.height * 0.5f) };
+        GLfloat whxy[4] = { actualViewport.width  * 0.5f,
+                            actualViewport.height * 0.5f,
+                            actualViewport.x + (actualViewport.width  * 0.5f),
+                            actualViewport.y + (actualViewport.height * 0.5f) };
         currentProgram->setUniform4fv(coord, 1, whxy);
 
         GLint depth = currentProgram->getDxDepthLocation();
-        GLfloat dz[2] = { (zFar - zNear) * 0.5f, (zNear + zFar) * 0.5f };
+        GLfloat dz[2] = { (actualZFar - actualZNear) * 0.5f, (actualZNear + actualZFar) * 0.5f };
         currentProgram->setUniform2fv(depth, 1, dz);
 
         GLint depthRange = currentProgram->getDxDepthRangeLocation();
-        GLfloat nearFarDiff[3] = { zNear, zFar, zFar - zNear };
+        GLfloat nearFarDiff[3] = { actualZNear, actualZFar, actualZFar - actualZNear };
         currentProgram->setUniform3fv(depthRange, 1, nearFarDiff);
     }
 
diff --git a/src/libGLESv2/renderer/Renderer11.h b/src/libGLESv2/renderer/Renderer11.h
index 7cf7c93..b95e57a 100644
--- a/src/libGLESv2/renderer/Renderer11.h
+++ b/src/libGLESv2/renderer/Renderer11.h
@@ -55,7 +55,7 @@
                                       int stencilBackRef, bool frontFaceCCW);
 
     virtual void setScissorRectangle(const gl::Rectangle &scissor);
-    virtual bool setViewport(const gl::Rectangle &viewport, float zNear, float zFar,
+    virtual bool setViewport(const gl::Rectangle &viewport, float zNear, float zFar, bool ignoreViewport,
                              gl::ProgramBinary *currentProgram, bool forceSetUniforms);
 
     virtual bool applyPrimitiveType(GLenum mode, GLsizei count);
diff --git a/src/libGLESv2/renderer/Renderer9.cpp b/src/libGLESv2/renderer/Renderer9.cpp
index 14a5e37..c89959f 100644
--- a/src/libGLESv2/renderer/Renderer9.cpp
+++ b/src/libGLESv2/renderer/Renderer9.cpp
@@ -911,32 +911,44 @@
     mForceSetScissor = false;
 }
 
-bool Renderer9::setViewport(const gl::Rectangle &viewport, float zNear, float zFar,
+bool Renderer9::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, bool ignoreViewport,
                             gl::ProgramBinary *currentProgram, bool forceSetUniforms)
 {
-    bool viewportChanged =  mForceSetViewport || memcmp(&viewport, &mCurViewport, sizeof(gl::Rectangle)) != 0 ||
-                            zNear != mCurNear || zFar != mCurFar;
+    gl::Rectangle actualViewport = viewport;
+    float actualZNear = gl::clamp01(zNear);
+    float actualZFar = gl::clamp01(zFar);
+    if (ignoreViewport)
+    {
+        actualViewport.x = 0;
+        actualViewport.y = 0;
+        actualViewport.width = mRenderTargetDesc.width;
+        actualViewport.height = mRenderTargetDesc.height;
+        actualZNear = 0.0f;
+        actualZFar = 1.0f;
+    }
 
     D3DVIEWPORT9 dxViewport;
-    dxViewport.X = gl::clamp(viewport.x, 0, static_cast<int>(mRenderTargetDesc.width));
-    dxViewport.Y = gl::clamp(viewport.y, 0, static_cast<int>(mRenderTargetDesc.height));
-    dxViewport.Width = gl::clamp(viewport.width, 0, static_cast<int>(mRenderTargetDesc.width) - static_cast<int>(dxViewport.X));
-    dxViewport.Height = gl::clamp(viewport.height, 0, static_cast<int>(mRenderTargetDesc.height) - static_cast<int>(dxViewport.Y));
-    dxViewport.MinZ = zNear;
-    dxViewport.MaxZ = zFar;
+    dxViewport.X = gl::clamp(actualViewport.x, 0, static_cast<int>(mRenderTargetDesc.width));
+    dxViewport.Y = gl::clamp(actualViewport.y, 0, static_cast<int>(mRenderTargetDesc.height));
+    dxViewport.Width = gl::clamp(actualViewport.width, 0, static_cast<int>(mRenderTargetDesc.width) - static_cast<int>(dxViewport.X));
+    dxViewport.Height = gl::clamp(actualViewport.height, 0, static_cast<int>(mRenderTargetDesc.height) - static_cast<int>(dxViewport.Y));
+    dxViewport.MinZ = actualZNear;
+    dxViewport.MaxZ = actualZFar;
 
     if (dxViewport.Width <= 0 || dxViewport.Height <= 0)
     {
         return false;   // Nothing to render
     }
 
+    bool viewportChanged =  mForceSetViewport || memcmp(&actualViewport, &mCurViewport, sizeof(gl::Rectangle)) != 0 ||
+                            actualZNear != mCurNear || actualZFar != mCurFar;
     if (viewportChanged)
     {
         mDevice->SetViewport(&dxViewport);
 
-        mCurViewport = viewport;
-        mCurNear = zNear;
-        mCurFar = zFar;
+        mCurViewport = actualViewport;
+        mCurNear = actualZNear;
+        mCurFar = actualZFar;
     }
 
     if (currentProgram && (viewportChanged || forceSetUniforms))
@@ -947,18 +959,18 @@
 
         // These values are used for computing gl_FragCoord in Program::linkVaryings().
         GLint coord = currentProgram->getDxCoordLocation();
-        GLfloat whxy[4] = { viewport.width  * 0.5f,
-                            viewport.height * 0.5f,
-                            viewport.x + (viewport.width  * 0.5f),
-                            viewport.y + (viewport.height * 0.5f) };
+        GLfloat whxy[4] = { actualViewport.width  * 0.5f,
+                            actualViewport.height * 0.5f,
+                            actualViewport.x + (actualViewport.width  * 0.5f),
+                            actualViewport.y + (actualViewport.height * 0.5f) };
         currentProgram->setUniform4fv(coord, 1, whxy);
 
         GLint depth = currentProgram->getDxDepthLocation();
-        GLfloat dz[2] = { (zFar - zNear) * 0.5f, (zNear + zFar) * 0.5f };
+        GLfloat dz[2] = { (actualZFar - actualZNear) * 0.5f, (actualZNear + actualZFar) * 0.5f };
         currentProgram->setUniform2fv(depth, 1, dz);
 
         GLint depthRange = currentProgram->getDxDepthRangeLocation();
-        GLfloat nearFarDiff[3] = { zNear, zFar, zFar - zNear };
+        GLfloat nearFarDiff[3] = { actualZNear, actualZFar, actualZFar - actualZNear };
         currentProgram->setUniform3fv(depthRange, 1, nearFarDiff);
     }
 
diff --git a/src/libGLESv2/renderer/Renderer9.h b/src/libGLESv2/renderer/Renderer9.h
index 285edf4..f6a7d2c 100644
--- a/src/libGLESv2/renderer/Renderer9.h
+++ b/src/libGLESv2/renderer/Renderer9.h
@@ -90,7 +90,7 @@
                                       int stencilBackRef, bool frontFaceCCW);
 
     virtual void setScissorRectangle(const gl::Rectangle &scissor);
-    virtual bool setViewport(const gl::Rectangle &viewport, float zNear, float zFar,
+    virtual bool setViewport(const gl::Rectangle &viewport, float zNear, float zFar, bool ignoreViewport,
                              gl::ProgramBinary *currentProgram, bool forceSetUniforms);
 
     virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer);