Implement support for wide lines.

Bug 18962347

Change-Id: I673610bfd50bc0e09aedd764336c7e10cfa11e08
Reviewed-on: https://swiftshader-review.googlesource.com/1831
Reviewed-by: Nicolas Capens <capn@google.com>
Tested-by: Nicolas Capens <capn@google.com>
diff --git a/src/OpenGL/libGL/Context.cpp b/src/OpenGL/libGL/Context.cpp
index cbb03a0..af598f8 100644
--- a/src/OpenGL/libGL/Context.cpp
+++ b/src/OpenGL/libGL/Context.cpp
@@ -591,6 +591,7 @@
 void Context::setLineWidth(GLfloat width)

 {

     mState.lineWidth = width;

+	device->setLineWidth(clamp(width, ALIASED_LINE_WIDTH_RANGE_MIN, ALIASED_LINE_WIDTH_RANGE_MAX));

 }

 

 void Context::setGenerateMipmapHint(GLenum hint)

diff --git a/src/OpenGL/libGL/Context.h b/src/OpenGL/libGL/Context.h
index 5383de0..cd1bf15 100644
--- a/src/OpenGL/libGL/Context.h
+++ b/src/OpenGL/libGL/Context.h
@@ -94,7 +94,7 @@
 const GLint NUM_COMPRESSED_TEXTURE_FORMATS = sizeof(compressedTextureFormats) / sizeof(compressedTextureFormats[0]);

 

 const float ALIASED_LINE_WIDTH_RANGE_MIN = 1.0f;

-const float ALIASED_LINE_WIDTH_RANGE_MAX = 1.0f;

+const float ALIASED_LINE_WIDTH_RANGE_MAX = 128.0f;

 const float ALIASED_POINT_SIZE_RANGE_MIN = 0.125f;

 const float ALIASED_POINT_SIZE_RANGE_MAX = 8192.0f;

 const float MAX_TEXTURE_MAX_ANISOTROPY = 16.0f;

diff --git a/src/OpenGL/libGL/Device.cpp b/src/OpenGL/libGL/Device.cpp
index dbd2bf5..569ffa4 100644
--- a/src/OpenGL/libGL/Device.cpp
+++ b/src/OpenGL/libGL/Device.cpp
@@ -68,7 +68,6 @@
 		setClipFlags(0);

 		setPointSize(1.0f);

 		setPointSizeMin(0.125f);

-		setPointSpriteEnable(false);

         setPointSizeMax(8192.0f);

 		setColorWriteMask(0, 0x0000000F);

 		setBlendOperation(BLENDOP_ADD);

diff --git a/src/OpenGL/libGLES_CM/Context.cpp b/src/OpenGL/libGLES_CM/Context.cpp
index ba0025a..130d694 100644
--- a/src/OpenGL/libGLES_CM/Context.cpp
+++ b/src/OpenGL/libGLES_CM/Context.cpp
@@ -626,6 +626,7 @@
 void Context::setLineWidth(GLfloat width)

 {

     mState.lineWidth = width;

+	device->setLineWidth(clamp(width, ALIASED_LINE_WIDTH_RANGE_MIN, ALIASED_LINE_WIDTH_RANGE_MAX));

 }

 

 void Context::setGenerateMipmapHint(GLenum hint)

diff --git a/src/OpenGL/libGLES_CM/Device.cpp b/src/OpenGL/libGLES_CM/Device.cpp
index a814bf6..52e169d 100644
--- a/src/OpenGL/libGLES_CM/Device.cpp
+++ b/src/OpenGL/libGLES_CM/Device.cpp
@@ -68,7 +68,6 @@
 		setClipFlags(0);

 		setPointSize(1.0f);

 		setPointSizeMin(0.125f);

-		setPointSpriteEnable(false);

         setPointSizeMax(8192.0f);

 		setColorWriteMask(0, 0x0000000F);

 		setBlendOperation(BLENDOP_ADD);

diff --git a/src/OpenGL/libGLESv2/Context.cpp b/src/OpenGL/libGLESv2/Context.cpp
index d228d29..d184154 100644
--- a/src/OpenGL/libGLESv2/Context.cpp
+++ b/src/OpenGL/libGLESv2/Context.cpp
@@ -593,6 +593,7 @@
 void Context::setLineWidth(GLfloat width)

 {

     mState.lineWidth = width;

+	device->setLineWidth(clamp(width, ALIASED_LINE_WIDTH_RANGE_MIN, ALIASED_LINE_WIDTH_RANGE_MAX));

 }

 

 void Context::setGenerateMipmapHint(GLenum hint)

diff --git a/src/OpenGL/libGLESv2/Device.cpp b/src/OpenGL/libGLESv2/Device.cpp
index 2ff7774..777cbd4 100644
--- a/src/OpenGL/libGLESv2/Device.cpp
+++ b/src/OpenGL/libGLESv2/Device.cpp
@@ -68,7 +68,6 @@
 		setClipFlags(0);

 		setPointSize(1.0f);

 		setPointSizeMin(0.125f);

-		setPointSpriteEnable(false);

         setPointSizeMax(8192.0f);

 		setColorWriteMask(0, 0x0000000F);

 		setBlendOperation(BLENDOP_ADD);

diff --git a/src/Radiance/libRAD/Context.cpp b/src/Radiance/libRAD/Context.cpp
index b3764f4..3861dc5 100644
--- a/src/Radiance/libRAD/Context.cpp
+++ b/src/Radiance/libRAD/Context.cpp
@@ -491,6 +491,7 @@
 void Context::setLineWidth(GLfloat width)

 {

     mState.lineWidth = width;

+	device->setLineWidth(clamp(width, ALIASED_LINE_WIDTH_RANGE_MIN, ALIASED_LINE_WIDTH_RANGE_MAX));

 }

 

 void Context::setGenerateMipmapHint(GLenum hint)

diff --git a/src/Radiance/libRAD/Device.cpp b/src/Radiance/libRAD/Device.cpp
index 2ff7774..777cbd4 100644
--- a/src/Radiance/libRAD/Device.cpp
+++ b/src/Radiance/libRAD/Device.cpp
@@ -68,7 +68,6 @@
 		setClipFlags(0);

 		setPointSize(1.0f);

 		setPointSizeMin(0.125f);

-		setPointSpriteEnable(false);

         setPointSizeMax(8192.0f);

 		setColorWriteMask(0, 0x0000000F);

 		setBlendOperation(BLENDOP_ADD);

diff --git a/src/Renderer/Context.cpp b/src/Renderer/Context.cpp
index eb4c135..dedd574 100644
--- a/src/Renderer/Context.cpp
+++ b/src/Renderer/Context.cpp
@@ -288,6 +288,7 @@
 
 		pointSpriteEnable = false;
 		pointScaleEnable = false;
+		lineWidth = 1.0f;
 
 		writeSRGB = false;
 		sampleMask = 0xFFFFFFFF;
diff --git a/src/Renderer/Context.hpp b/src/Renderer/Context.hpp
index 29aee0b..848794a 100644
--- a/src/Renderer/Context.hpp
+++ b/src/Renderer/Context.hpp
@@ -472,6 +472,7 @@
 

 		bool pointSpriteEnable;

 		bool pointScaleEnable;

+		float lineWidth;

 

 		int colorWriteMask[4];   // RGBA

 		bool writeSRGB;

diff --git a/src/Renderer/Renderer.cpp b/src/Renderer/Renderer.cpp
index 290322a..df794ab 100644
--- a/src/Renderer/Renderer.cpp
+++ b/src/Renderer/Renderer.cpp
@@ -220,6 +220,10 @@
 
 			sync->lock(sw::PRIVATE);
 
+			Routine *vertexRoutine;
+			Routine *setupRoutine;
+			Routine *pixelRoutine;
+
 			if(update || oldMultiSampleMask != context->multiSampleMask)
 			{
 				vertexState = VertexProcessor::update();
@@ -233,6 +237,8 @@
 
 			int batch = batchSize / ms;
 
+			int (*setupPrimitives)(Renderer *renderer, int batch, int count);
+
 			if(context->isDrawTriangle())
 			{
 				switch(context->fillMode)
@@ -438,6 +444,8 @@
 				data->point = point;
 			}
 
+			data->lineWidth = context->lineWidth;
+
 			data->factor = factor;
 
 			if(pixelState.transparencyAntialiasing == TRANSPARENCY_ALPHA_TO_COVERAGE)
@@ -1545,6 +1553,8 @@
 		const SetupProcessor::State &state = draw.setupState;
 		const DrawData &data = *draw.data;
 
+		float lineWidth = data.lineWidth;
+
 		Vertex &v0 = triangle.v0;
 		Vertex &v1 = triangle.v1;
 
@@ -1579,7 +1589,7 @@
 			P[2] = P1;
 			P[3] = P0;
 
-			float scale = 0.5f / sqrt(dx*dx + dy*dy);
+			float scale = lineWidth * 0.5f / sqrt(dx*dx + dy*dy);
 
 			dx *= scale;
 			dy *= scale;
@@ -1641,11 +1651,11 @@
 			P[6] = P1;
 			P[7] = P1;
 
-			float dx0 = 0.5f * P0.w / W;
-			float dy0 = 0.5f * P0.w / H;
+			float dx0 = lineWidth * 0.5f * P0.w / W;
+			float dy0 = lineWidth * 0.5f * P0.w / H;
 
-			float dx1 = 0.5f * P1.w / W;
-			float dy1 = 0.5f * P1.w / H;
+			float dx1 = lineWidth * 0.5f * P1.w / W;
+			float dy1 = lineWidth * 0.5f * P1.w / H;
 
 			P[0].x += -dx0;
 			C[0] = computeClipFlags(P[0], data);
@@ -2193,6 +2203,11 @@
 		context->setPointScaleEnable(pointScaleEnable);
 	}
 
+	void Renderer::setLineWidth(float width)
+	{
+		context->lineWidth = width;
+	}
+
 	void Renderer::setDepthBias(float bias)
 	{
 		depthBias = bias;
diff --git a/src/Renderer/Renderer.hpp b/src/Renderer/Renderer.hpp
index 0211e69..fddd459 100644
--- a/src/Renderer/Renderer.hpp
+++ b/src/Renderer/Renderer.hpp
@@ -111,6 +111,7 @@
 		PS ps;
 
 		VertexProcessor::PointSprite point;
+		float lineWidth;
 
 		PixelProcessor::Stencil stencil[2];   // clockwise, counterclockwise
 		PixelProcessor::Stencil stencilCCW;
@@ -293,6 +294,7 @@
 		
 		virtual void setPointSpriteEnable(bool pointSpriteEnable);
 		virtual void setPointScaleEnable(bool pointScaleEnable);
+		virtual void setLineWidth(float width);
 
 		virtual void setDepthBias(float bias);
 		virtual void setSlopeDepthBias(float slopeBias);
@@ -419,11 +421,6 @@
 		VertexProcessor::State vertexState;
 		SetupProcessor::State setupState;
 		PixelProcessor::State pixelState;
-		int (*setupPrimitives)(Renderer *renderer, int batch, int count);
-
-		Routine *vertexRoutine;
-		Routine *setupRoutine;
-		Routine *pixelRoutine;
 
 		Blitter blitter;
 	};