Perform texture coordinate projection early.

Change-Id: Ia907ff073bf00114b2a3e72c495bf96c5a57154e
Reviewed-on: https://swiftshader-review.googlesource.com/5592
Tested-by: Nicolas Capens <capn@google.com>
Reviewed-by: Meng-Lin Wu <marleymoo@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/OpenGL/compiler/OutputASM.cpp b/src/OpenGL/compiler/OutputASM.cpp
index 519b613..502e372 100644
--- a/src/OpenGL/compiler/OutputASM.cpp
+++ b/src/OpenGL/compiler/OutputASM.cpp
@@ -1236,25 +1236,12 @@
 
 					if(textureFunction.proj)
 					{
-						TIntermConstantUnion* constant = arg[1]->getAsConstantUnion();
-						if(constant)
-						{
-							float projFactor = 1.0f / constant->getFConst(t->getNominalSize() - 1);
-							Constant projCoord(constant->getFConst(0) * projFactor,
-							                   constant->getFConst(1) * projFactor,
-							                   constant->getFConst(2) * projFactor,
-							                   0.0f);
-							emit(sw::Shader::OPCODE_MOV, &coord, &projCoord);
-						}
-						else
-						{
-							Instruction *rcp = emit(sw::Shader::OPCODE_RCPX, &coord, arg[1]);
-							rcp->src[0].swizzle = 0x55 * (t->getNominalSize() - 1);
-							rcp->dst.mask = 0x7;
+						Instruction *rcp = emit(sw::Shader::OPCODE_RCPX, &coord, arg[1]);
+						rcp->src[0].swizzle = 0x55 * (t->getNominalSize() - 1);
+						rcp->dst.mask = 0x7;
 
-							Instruction *mul = emit(sw::Shader::OPCODE_MUL, &coord, arg[1], &coord);
-							mul->dst.mask = 0x7;
-						}
+						Instruction *mul = emit(sw::Shader::OPCODE_MUL, &coord, arg[1], &coord);
+						mul->dst.mask = 0x7;
 					}
 					else
 					{
diff --git a/src/Shader/PixelProgram.cpp b/src/Shader/PixelProgram.cpp
index d3e688c..567561a 100644
--- a/src/Shader/PixelProgram.cpp
+++ b/src/Shader/PixelProgram.cpp
@@ -281,12 +281,12 @@
 			case Shader::OPCODE_M3X3:       M3X3(d, s0, src1);                             break;
 			case Shader::OPCODE_M3X2:       M3X2(d, s0, src1);                             break;
 			case Shader::OPCODE_TEX:        TEXLD(d, s0, src1, project, bias);             break;
-			case Shader::OPCODE_TEXLDD:     TEXLDD(d, s0, src1, s2, s3, project);          break;
-			case Shader::OPCODE_TEXLDL:     TEXLDL(d, s0, src1, project);                  break;
+			case Shader::OPCODE_TEXLDD:     TEXLDD(d, s0, src1, s2, s3);                   break;
+			case Shader::OPCODE_TEXLDL:     TEXLDL(d, s0, src1);                           break;
 			case Shader::OPCODE_TEXSIZE:    TEXSIZE(d, s0.x, src1);                        break;
 			case Shader::OPCODE_TEXKILL:    TEXKILL(cMask, d, dst.mask);                   break;
-			case Shader::OPCODE_TEXOFFSET:  TEXOFFSET(d, s0, src1, s2, project, bias);     break;
-			case Shader::OPCODE_TEXLDLOFFSET: TEXLDL(d, s0, src1, s2, project, bias);      break;
+			case Shader::OPCODE_TEXOFFSET:  TEXOFFSET(d, s0, src1, s2, bias);              break;
+			case Shader::OPCODE_TEXLDLOFFSET: TEXLDL(d, s0, src1, s2, bias);               break;
 			case Shader::OPCODE_TEXELFETCH: TEXELFETCH(d, s0, src1);                       break;
 			case Shader::OPCODE_TEXELFETCHOFFSET: TEXELFETCH(d, s0, src1, s2);             break;
 			case Shader::OPCODE_TEXGRAD:    TEXGRAD(d, s0, src1, s2, s3);                  break;
@@ -714,21 +714,7 @@
 		#endif
 
 		Pointer<Byte> texture = data + OFFSET(DrawData, mipmap) + samplerIndex * sizeof(Texture);
-
-		if(!(options & Project))
-		{
-			sampler[samplerIndex]->sampleTexture(texture, c, uvwq.x, uvwq.y, uvwq.z, uvwq.w, dsx, dsy, offset, options, method);
-		}
-		else
-		{
-			Float4 rq = reciprocal(uvwq.w);
-
-			Float4 u_q = uvwq.x * rq;
-			Float4 v_q = uvwq.y * rq;
-			Float4 w_q = uvwq.z * rq;
-
-			sampler[samplerIndex]->sampleTexture(texture, c, u_q, v_q, w_q, uvwq.w, dsx, dsy, offset, options, method);
-		}
+		sampler[samplerIndex]->sampleTexture(texture, c, uvwq.x, uvwq.y, uvwq.z, uvwq.w, dsx, dsy, offset, options, method);
 
 		#if PERF_PROFILE
 			cycles[PERF_TEX] += Ticks() - texTime;
@@ -1109,17 +1095,30 @@
 
 	void PixelProgram::TEXLD(Vector4f &dst, Vector4f &src0, const Src &src1, bool project, bool bias)
 	{
-		sampleTexture(dst, src1, src0, src0, src0, src0, bias ? Bias : Implicit, project ? Project : None);
+		if(project)
+		{
+			Vector4f proj;
+			Float4 rw = reciprocal(src0.w);
+			proj.x = src0.x * rw;
+			proj.y = src0.y * rw;
+			proj.z = src0.z * rw;
+
+			sampleTexture(dst, src1, proj, src0, src0, src0, Implicit, None);
+		}
+		else
+		{
+			sampleTexture(dst, src1, src0, src0, src0, src0, bias ? Bias : Implicit, None);
+		}
 	}
 
-	void PixelProgram::TEXOFFSET(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &src2, bool project, bool bias)
+	void PixelProgram::TEXOFFSET(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &src2, bool bias)
 	{
-		sampleTexture(dst, src1, src0, src0, src0, src2, bias ? Bias : Implicit, project ? (Project | Offset) : Offset);
+		sampleTexture(dst, src1, src0, src0, src0, src2, bias ? Bias : Implicit, Offset);
 	}
 
-	void PixelProgram::TEXLDL(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &offset, bool project, bool bias)
+	void PixelProgram::TEXLDL(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &offset, bool bias)
 	{
-		sampleTexture(dst, src1, src0, src0, src0, offset, Lod, project ? (Project | Offset) : Offset);
+		sampleTexture(dst, src1, src0, src0, src0, offset, Lod, Offset);
 	}
 
 	void PixelProgram::TEXELFETCH(Vector4f &dst, Vector4f &src0, const Src& src1)
@@ -1142,14 +1141,14 @@
 		sampleTexture(dst, src1, src0, src2, src3, offset, Grad, Offset);
 	}
 
-	void PixelProgram::TEXLDD(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &src2, Vector4f &src3, bool project)
+	void PixelProgram::TEXLDD(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &src2, Vector4f &src3)
 	{
-		sampleTexture(dst, src1, src0, src2, src3, src0, Grad, project ? Project : None);
+		sampleTexture(dst, src1, src0, src2, src3, src0, Grad, None);
 	}
 
-	void PixelProgram::TEXLDL(Vector4f &dst, Vector4f &src0, const Src &src1, bool project)
+	void PixelProgram::TEXLDL(Vector4f &dst, Vector4f &src0, const Src &src1)
 	{
-		sampleTexture(dst, src1, src0, src0, src0, src0, Lod, project ? Project : None);
+		sampleTexture(dst, src1, src0, src0, src0, src0, Lod, None);
 	}
 
 	void PixelProgram::TEXSIZE(Vector4f &dst, Float4 &lod, const Src &src1)
diff --git a/src/Shader/PixelProgram.hpp b/src/Shader/PixelProgram.hpp
index 4454171..6b60cc0 100644
--- a/src/Shader/PixelProgram.hpp
+++ b/src/Shader/PixelProgram.hpp
@@ -107,12 +107,12 @@
 		void M4X3(Vector4f &dst, Vector4f &src0, const Src &src1);
 		void M4X4(Vector4f &dst, Vector4f &src0, const Src &src1);
 		void TEXLD(Vector4f &dst, Vector4f &src0, const Src &src1, bool project, bool bias);
-		void TEXLDD(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &src2, Vector4f &src3, bool project);
-		void TEXLDL(Vector4f &dst, Vector4f &src0, const Src &src1, bool project);
+		void TEXLDD(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &src2, Vector4f &src3);
+		void TEXLDL(Vector4f &dst, Vector4f &src0, const Src &src1);
 		void TEXSIZE(Vector4f &dst, Float4 &lod, const Src &src1);
 		void TEXKILL(Int cMask[4], Vector4f &src, unsigned char mask);
-		void TEXOFFSET(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &src2, bool project, bool bias);
-		void TEXLDL(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &src2, bool project, bool bias);
+		void TEXOFFSET(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &src2, bool bias);
+		void TEXLDL(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &src2, bool bias);
 		void TEXELFETCH(Vector4f &dst, Vector4f &src, const Src&);
 		void TEXELFETCH(Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2);
 		void TEXGRAD(Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2, Vector4f &src3);
diff --git a/src/Shader/SamplerCore.hpp b/src/Shader/SamplerCore.hpp
index 9bd07c2..17322b9 100644
--- a/src/Shader/SamplerCore.hpp
+++ b/src/Shader/SamplerCore.hpp
@@ -28,12 +28,11 @@
 		Grad
 	};
 
-	enum TextureFunction

-	{

-		None = 0x00,

-		Project = 0x01,

-		Offset = 0x02,

-		Fetch = 0x04

+	enum TextureFunction
+	{
+		None = 0x00,
+		Offset = 0x01,
+		Fetch = 0x02
 	};
 
 	class SamplerCore