Rasterizer discard implementation

Implemented rasterizer discard by not using the SetupRoutine
and always returning 0 when rasterizer discard is enabled.
Also guarded all clear calls with a check for rasterizer
discard. Passes all rasterizer discard related dEQP tests.

Change-Id: I1e5c107e3dba550f7a5b01eb302ff51bdac303dc
Reviewed-on: https://swiftshader-review.googlesource.com/4876
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/OpenGL/libGLESv2/Context.cpp b/src/OpenGL/libGLESv2/Context.cpp
index 742ec61..add3aff 100644
--- a/src/OpenGL/libGLESv2/Context.cpp
+++ b/src/OpenGL/libGLESv2/Context.cpp
@@ -635,7 +635,6 @@
 

 void Context::setRasterizerDiscardEnabled(bool enabled)

 {

-    UNIMPLEMENTED();

     mState.rasterizerDiscardEnabled = enabled;

 }

 

@@ -3019,6 +3018,8 @@
 

         mDitherStateDirty = false;

     }

+

+	device->setRasterizerDiscard(mState.rasterizerDiscardEnabled);

 }

 

 GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count, GLsizei instanceId)

@@ -3356,6 +3357,11 @@
 

 void Context::clear(GLbitfield mask)

 {

+	if(mState.rasterizerDiscardEnabled)

+	{

+		return;

+	}

+

     Framebuffer *framebuffer = getDrawFramebuffer();

 

     if(!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)

@@ -3400,7 +3406,7 @@
 void Context::clearColorBuffer(GLint drawbuffer, void *value, sw::Format format)

 {

 	unsigned int rgbaMask = getColorMask();

-	if(device && rgbaMask)

+	if(device && rgbaMask && !mState.rasterizerDiscardEnabled)

 	{

 		int x0(0), y0(0), width(0), height(0);

 		egl::Image* image = getScissoredImage(drawbuffer, x0, y0, width, height, false);

@@ -3432,7 +3438,7 @@
 

 void Context::clearDepthBuffer(GLint drawbuffer, const GLfloat *value)

 {

-	if(device && mState.depthMask)

+	if(device && mState.depthMask && !mState.rasterizerDiscardEnabled)

 	{

 		int x0(0), y0(0), width(0), height(0);

 		egl::Image* image = getScissoredImage(drawbuffer, x0, y0, width, height, true);

@@ -3446,7 +3452,7 @@
 

 void Context::clearStencilBuffer(GLint drawbuffer, const GLint *value)

 {

-	if(device && mState.stencilWritemask)

+	if(device && mState.stencilWritemask && !mState.rasterizerDiscardEnabled)

 	{

 		int x0(0), y0(0), width(0), height(0);

 		egl::Image* image = getScissoredImage(drawbuffer, x0, y0, width, height, true);

@@ -3460,7 +3466,7 @@
 

 void Context::clearDepthStencilBuffer(GLint drawbuffer, GLfloat depth, GLint stencil)

 {

-	if(device && (mState.depthMask || mState.stencilWritemask))

+	if(device && (mState.depthMask || mState.stencilWritemask) && !mState.rasterizerDiscardEnabled)

 	{

 		int x0(0), y0(0), width(0), height(0);

 		egl::Image* image = getScissoredImage(drawbuffer, x0, y0, width, height, true);

diff --git a/src/Renderer/Context.cpp b/src/Renderer/Context.cpp
index 640f26a..bde6c94 100644
--- a/src/Renderer/Context.cpp
+++ b/src/Renderer/Context.cpp
@@ -253,6 +253,8 @@
 		fillMode = FILL_SOLID;
 		shadingMode = SHADING_GOURAUD;
 
+		rasterizerDiscard = false;
+
 		depthCompareMode = DEPTH_LESS;
 		depthBufferEnable = true;
 		depthWriteEnable = true;
diff --git a/src/Renderer/Context.hpp b/src/Renderer/Context.hpp
index ee2bef8..169df8a 100644
--- a/src/Renderer/Context.hpp
+++ b/src/Renderer/Context.hpp
@@ -494,6 +494,7 @@
 		bool occlusionEnabled;

 

 		// Pixel processor states

+		bool rasterizerDiscard;

 		bool depthBufferEnable;

 		DepthCompareMode depthCompareMode;

 		bool depthWriteEnable;

diff --git a/src/Renderer/Renderer.cpp b/src/Renderer/Renderer.cpp
index ca5e67a..cc95546 100644
--- a/src/Renderer/Renderer.cpp
+++ b/src/Renderer/Renderer.cpp
@@ -821,7 +821,7 @@
 					startTick = time;
 				#endif
 
-				int visible = setupPrimitives(this, unit, count);
+				int visible = draw->setupState.rasterizerDiscard ? 0 : setupPrimitives(this, unit, count);
 
 				primitiveProgress[unit].visible = visible;
 				primitiveProgress[unit].references = clusterCount;
@@ -2315,6 +2315,11 @@
 		slopeDepthBias = slopeBias;
 	}
 
+	void Renderer::setRasterizerDiscard(bool rasterizerDiscard)
+	{
+		context->rasterizerDiscard = rasterizerDiscard;
+	}
+
 	void Renderer::setPixelShader(const PixelShader *shader)
 	{
 		context->pixelShader = shader;
diff --git a/src/Renderer/Renderer.hpp b/src/Renderer/Renderer.hpp
index a818eaa..30fccc5 100644
--- a/src/Renderer/Renderer.hpp
+++ b/src/Renderer/Renderer.hpp
@@ -340,6 +340,8 @@
 		virtual void setDepthBias(float bias);
 		virtual void setSlopeDepthBias(float slopeBias);
 
+		virtual void setRasterizerDiscard(bool rasterizerDiscard);
+
 		// Programmable pipelines
 		virtual void setPixelShader(const PixelShader *shader);
 		virtual void setVertexShader(const VertexShader *shader);
diff --git a/src/Renderer/SetupProcessor.cpp b/src/Renderer/SetupProcessor.cpp
index 34b11be..6d4d7cb 100644
--- a/src/Renderer/SetupProcessor.cpp
+++ b/src/Renderer/SetupProcessor.cpp
@@ -89,6 +89,7 @@
 		state.pointSizeRegister = 0xF;   // No vertex point size
 
 		state.multiSample = context->getMultiSampleCount();
+		state.rasterizerDiscard = context->rasterizerDiscard;
 
 		if(context->vertexShader)
 		{
diff --git a/src/Renderer/SetupProcessor.hpp b/src/Renderer/SetupProcessor.hpp
index 0d2c81a..02133f0 100644
--- a/src/Renderer/SetupProcessor.hpp
+++ b/src/Renderer/SetupProcessor.hpp
@@ -49,6 +49,7 @@
 			bool slopeDepthBias            : 1;

 			bool vFace                     : 1;

 			unsigned int multiSample       : 3;   // 1, 2 or 4

+			bool rasterizerDiscard         : 1;

 

 			struct Gradient

 			{