Fix regressions in the unit tests related to setting gl_PointSize, and using other draw modes.

This had two regressions, using gl_PointSize and drawing triangles, and drawing points and triangles
with the same binary program.

TRAC #22526

Signed-off-by: Nicolas Capens
Signed-off-by: Shannon Woods
Author: Jamie Madill

git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1853 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index cbd827a..8e4b703 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -59,6 +59,7 @@
     mState.rasterizer.polygonOffsetFill = false;
     mState.rasterizer.polygonOffsetFactor = 0.0f;
     mState.rasterizer.polygonOffsetUnits = 0.0f;
+    mState.rasterizer.pointDrawMode = false;
     mState.scissorTest = false;
     mState.scissor.x = 0;
     mState.scissor.y = 0;
@@ -1712,17 +1713,8 @@
 // Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D 9 device
 void Context::applyState(GLenum drawMode)
 {
-    // disable face culling for point sprite emulation (done as geometry shader quads)
-    if (getCurrentProgramBinary()->usesPointSpriteEmulation())
-    {
-        RasterizerState rasterizerStateCopy = mState.rasterizer;
-        rasterizerStateCopy.cullFace = false;
-        mRenderer->setRasterizerState(rasterizerStateCopy);
-    }
-    else
-    {
-        mRenderer->setRasterizerState(mState.rasterizer);
-    }
+    mState.rasterizer.pointDrawMode = (drawMode == GL_POINTS);
+    mRenderer->setRasterizerState(mState.rasterizer);
 
     unsigned int mask = 0;
     if (mState.sampleCoverage)
diff --git a/src/libGLESv2/angletypes.h b/src/libGLESv2/angletypes.h
index 3b73037..8a29e9b 100644
--- a/src/libGLESv2/angletypes.h
+++ b/src/libGLESv2/angletypes.h
@@ -55,6 +55,8 @@
     bool polygonOffsetFill;
     GLfloat polygonOffsetFactor;
     GLfloat polygonOffsetUnits;
+
+    bool pointDrawMode;
 };
 
 struct BlendState
diff --git a/src/libGLESv2/renderer/RenderStateCache.cpp b/src/libGLESv2/renderer/RenderStateCache.cpp
index 620fce6..79b2a90 100644
--- a/src/libGLESv2/renderer/RenderStateCache.cpp
+++ b/src/libGLESv2/renderer/RenderStateCache.cpp
@@ -213,9 +213,17 @@
             mRasterizerStateCache.erase(leastRecentlyUsed);
         }
 
+        D3D11_CULL_MODE cullMode = gl_d3d11::ConvertCullMode(rasterState.cullFace, rasterState.cullMode);
+
+        // Disable culling if drawing points
+        if (rasterState.pointDrawMode)
+        {
+            cullMode = D3D11_CULL_NONE;
+        }
+
         D3D11_RASTERIZER_DESC rasterDesc;
         rasterDesc.FillMode = D3D11_FILL_SOLID;
-        rasterDesc.CullMode = gl_d3d11::ConvertCullMode(rasterState.cullFace, rasterState.cullMode);
+        rasterDesc.CullMode = cullMode;
         rasterDesc.FrontCounterClockwise = (rasterState.frontFace == GL_CCW) ? FALSE: TRUE;
         rasterDesc.DepthBias = ldexp(rasterState.polygonOffsetUnits, -static_cast<int>(depthSize));
         rasterDesc.DepthBiasClamp = 0.0f; // MSDN documentation of DepthBiasClamp implies a value of zero will preform no clamping, must be tested though.
diff --git a/src/libGLESv2/renderer/Renderer11.cpp b/src/libGLESv2/renderer/Renderer11.cpp
index d43a7be..2088ac2 100644
--- a/src/libGLESv2/renderer/Renderer11.cpp
+++ b/src/libGLESv2/renderer/Renderer11.cpp
@@ -101,6 +101,8 @@
     mDriverConstantBufferPS = NULL;
 
     mBGRATextureSupport = false;
+
+    mIsGeometryShaderActive = false;
 }
 
 Renderer11::~Renderer11()
@@ -1096,7 +1098,6 @@
     {
         ShaderExecutable *vertexExe = programBinary->getVertexExecutable();
         ShaderExecutable *pixelExe = programBinary->getPixelExecutable();
-        ShaderExecutable *geometryExe = programBinary->getGeometryExecutable();
 
         ID3D11VertexShader *vertexShader = NULL;
         if (vertexExe) vertexShader = ShaderExecutable11::makeShaderExecutable11(vertexExe)->getVertexShader();
@@ -1104,14 +1105,23 @@
         ID3D11PixelShader *pixelShader = NULL;
         if (pixelExe) pixelShader = ShaderExecutable11::makeShaderExecutable11(pixelExe)->getPixelShader();
 
-        ID3D11GeometryShader *geometryShader = NULL;
-        if (geometryExe) geometryShader = ShaderExecutable11::makeShaderExecutable11(geometryExe)->getGeometryShader();
-
         mDeviceContext->PSSetShader(pixelShader, NULL, 0);
         mDeviceContext->VSSetShader(vertexShader, NULL, 0);
 
-        if (geometryShader)
+        programBinary->dirtyAllUniforms();
+
+        mAppliedProgramBinarySerial = programBinarySerial;
+    }
+
+    // Only use the geometry shader currently for point sprite drawing
+    const bool usesGeometryShader = programBinary->usesGeometryShader() && mCurRasterState.pointDrawMode;
+
+    if (programBinarySerial != mAppliedProgramBinarySerial || usesGeometryShader != mIsGeometryShaderActive)
+    {
+        if (usesGeometryShader)
         {
+            ShaderExecutable *geometryExe = programBinary->getGeometryExecutable();
+            ID3D11GeometryShader *geometryShader = ShaderExecutable11::makeShaderExecutable11(geometryExe)->getGeometryShader();
             mDeviceContext->GSSetShader(geometryShader, NULL, 0);
         }
         else
@@ -1119,9 +1129,7 @@
             mDeviceContext->GSSetShader(NULL, NULL, 0);
         }
 
-        programBinary->dirtyAllUniforms();
-
-        mAppliedProgramBinarySerial = programBinarySerial;
+        mIsGeometryShaderActive = usesGeometryShader;
     }
 }
 
diff --git a/src/libGLESv2/renderer/Renderer11.h b/src/libGLESv2/renderer/Renderer11.h
index 6a50bbd..373f118 100644
--- a/src/libGLESv2/renderer/Renderer11.h
+++ b/src/libGLESv2/renderer/Renderer11.h
@@ -251,6 +251,7 @@
     unsigned int mAppliedIBOffset;
 
     unsigned int mAppliedProgramBinarySerial;
+    bool mIsGeometryShaderActive;
 
     dx_VertexConstants mVertexConstants;
     dx_VertexConstants mAppliedVertexConstants;