Minor PixelRoutine cleanup

- Removed redundant parameters from fogBlend()
- Moved computation registers and color output
  registers from PixelRoutine to PixelProgram.
- Made many PixelRoutine member functions
  private rather than protected when possible.

Change-Id: I748333626d993c0d46b369991d74bc3a22c972c2
Reviewed-on: https://swiftshader-review.googlesource.com/3850
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
Tested-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/Shader/PixelPipeline.cpp b/src/Shader/PixelPipeline.cpp
index c89d058..24ffd9b 100644
--- a/src/Shader/PixelPipeline.cpp
+++ b/src/Shader/PixelPipeline.cpp
@@ -1,39 +1,39 @@
-// SwiftShader Software Renderer
-//
-// Copyright(c) 2015 Google Inc.
-//
-// All rights reserved. No part of this software may be copied, distributed, transmitted,
-// transcribed, stored in a retrieval system, translated into any human or computer
-// language by any means, or disclosed to third parties without the explicit written
-// agreement of Google Inc. Without such an agreement, no rights or licenses, express
-// or implied, including but not limited to any patent rights, are granted to you.
-//
+// SwiftShader Software Renderer

+//

+// Copyright(c) 2015 Google Inc.

+//

+// All rights reserved. No part of this software may be copied, distributed, transmitted,

+// transcribed, stored in a retrieval system, translated into any human or computer

+// language by any means, or disclosed to third parties without the explicit written

+// agreement of Google Inc. Without such an agreement, no rights or licenses, express

+// or implied, including but not limited to any patent rights, are granted to you.

+//

+

+#include "PixelPipeline.hpp"

+#include "Renderer.hpp"

+#include "SamplerCore.hpp"

+

+namespace sw

+{

+	extern bool postBlendSRGB;

+

+	void PixelPipeline::setBuiltins(PixelRoutine::Registers &rBase, Int &x, Int &y, Float4(&z)[4], Float4 &w)

+	{

+		Registers& r = *static_cast<Registers*>(&rBase);

+

+		if(state.color[0].component & 0x1) r.diffuse.x = convertFixed12(r.v[0].x); else r.diffuse.x = Short4(0x1000);
+		if(state.color[0].component & 0x2) r.diffuse.y = convertFixed12(r.v[0].y); else r.diffuse.y = Short4(0x1000);
+		if(state.color[0].component & 0x4) r.diffuse.z = convertFixed12(r.v[0].z); else r.diffuse.z = Short4(0x1000);
+		if(state.color[0].component & 0x8) r.diffuse.w = convertFixed12(r.v[0].w); else r.diffuse.w = Short4(0x1000);
 
-#include "PixelPipeline.hpp"
-#include "Renderer.hpp"
-#include "SamplerCore.hpp"
-
-namespace sw
-{
-	extern bool postBlendSRGB;
-
-	void PixelPipeline::setBuiltins(PixelRoutine::Registers &rBase, Int &x, Int &y, Float4(&z)[4], Float4 &w)
-	{
-		Registers& r = *static_cast<Registers*>(&rBase);
-
-		if(state.color[0].component & 0x1) r.diffuse.x = convertFixed12(r.vf[0].x); else r.diffuse.x = Short4(0x1000);
-		if(state.color[0].component & 0x2) r.diffuse.y = convertFixed12(r.vf[0].y); else r.diffuse.y = Short4(0x1000);
-		if(state.color[0].component & 0x4) r.diffuse.z = convertFixed12(r.vf[0].z); else r.diffuse.z = Short4(0x1000);
-		if(state.color[0].component & 0x8) r.diffuse.w = convertFixed12(r.vf[0].w); else r.diffuse.w = Short4(0x1000);
-
-		if(state.color[1].component & 0x1) r.specular.x = convertFixed12(r.vf[1].x); else r.specular.x = Short4(0x0000, 0x0000, 0x0000, 0x0000);
-		if(state.color[1].component & 0x2) r.specular.y = convertFixed12(r.vf[1].y); else r.specular.y = Short4(0x0000, 0x0000, 0x0000, 0x0000);
-		if(state.color[1].component & 0x4) r.specular.z = convertFixed12(r.vf[1].z); else r.specular.z = Short4(0x0000, 0x0000, 0x0000, 0x0000);
-		if(state.color[1].component & 0x8) r.specular.w = convertFixed12(r.vf[1].w); else r.specular.w = Short4(0x0000, 0x0000, 0x0000, 0x0000);
-	}
-
+		if(state.color[1].component & 0x1) r.specular.x = convertFixed12(r.v[1].x); else r.specular.x = Short4(0x0000, 0x0000, 0x0000, 0x0000);
+		if(state.color[1].component & 0x2) r.specular.y = convertFixed12(r.v[1].y); else r.specular.y = Short4(0x0000, 0x0000, 0x0000, 0x0000);
+		if(state.color[1].component & 0x4) r.specular.z = convertFixed12(r.v[1].z); else r.specular.z = Short4(0x0000, 0x0000, 0x0000, 0x0000);
+		if(state.color[1].component & 0x8) r.specular.w = convertFixed12(r.v[1].w); else r.specular.w = Short4(0x0000, 0x0000, 0x0000, 0x0000);

+	}

+

 	void PixelPipeline::fixedFunction(Registers& r)
-	{
+	{

 		r.current = r.diffuse;
 		Vector4s temp(0x0000, 0x0000, 0x0000, 0x0000);
 
@@ -54,9 +54,9 @@
 			blendTexture(r, temp, texture, stage);
 		}
 
-		specularPixel(r.current, r.specular);
-	}
-
+		specularPixel(r.current, r.specular);

+	}

+

 	void PixelPipeline::applyShader(PixelRoutine::Registers &rBase, Int cMask[4])
 	{
 		Registers& r = *static_cast<Registers*>(&rBase);
@@ -102,10 +102,10 @@
 			if(src1.type != Shader::PARAMETER_VOID) s1 = fetchRegisterS(r, src1);
 			if(src2.type != Shader::PARAMETER_VOID) s2 = fetchRegisterS(r, src2);
 
-			Float4 u = version < 0x0104 ? r.vf[2 + dst.index].x : r.vf[2 + src0.index].x;
-			Float4 v = version < 0x0104 ? r.vf[2 + dst.index].y : r.vf[2 + src0.index].y;
-			Float4 s = version < 0x0104 ? r.vf[2 + dst.index].z : r.vf[2 + src0.index].z;
-			Float4 t = version < 0x0104 ? r.vf[2 + dst.index].w : r.vf[2 + src0.index].w;
+			Float4 u = version < 0x0104 ? r.v[2 + dst.index].x : r.v[2 + src0.index].x;
+			Float4 v = version < 0x0104 ? r.v[2 + dst.index].y : r.v[2 + src0.index].y;
+			Float4 s = version < 0x0104 ? r.v[2 + dst.index].z : r.v[2 + src0.index].z;
+			Float4 t = version < 0x0104 ? r.v[2 + dst.index].w : r.v[2 + src0.index].w;
 
 			switch(opcode)
 			{
@@ -257,12 +257,12 @@
 				}
 			}
 		}
-	}
-
-	Bool PixelPipeline::alphaTest(PixelRoutine::Registers &rBase, Int cMask[4])
-	{
-		Registers& r = *static_cast<Registers*>(&rBase);
-
+	}

+

+	Bool PixelPipeline::alphaTest(PixelRoutine::Registers &rBase, Int cMask[4])

+	{

+		Registers& r = *static_cast<Registers*>(&rBase);

+

 		r.current.x = Min(r.current.x, Short4(0x0FFF, 0x0FFF, 0x0FFF, 0x0FFF)); r.current.x = Max(r.current.x, Short4(0x0000, 0x0000, 0x0000, 0x0000));
 		r.current.y = Min(r.current.y, Short4(0x0FFF, 0x0FFF, 0x0FFF, 0x0FFF)); r.current.y = Max(r.current.y, Short4(0x0000, 0x0000, 0x0000, 0x0000));
 		r.current.z = Min(r.current.z, Short4(0x0FFF, 0x0FFF, 0x0FFF, 0x0FFF)); r.current.z = Max(r.current.z, Short4(0x0000, 0x0000, 0x0000, 0x0000));
@@ -299,13 +299,13 @@
 			pass = pass | cMask[q];
 		}
 
-		return pass != 0x0;
-	}
-
-	void PixelPipeline::rasterOperation(PixelRoutine::Registers &rBase, Float4 &fog, Pointer<Byte> cBuffer[4], Int &x, Int sMask[4], Int zMask[4], Int cMask[4])
-	{
-		Registers& r = *static_cast<Registers*>(&rBase);
-
+		return pass != 0x0;

+	}

+

+	void PixelPipeline::rasterOperation(PixelRoutine::Registers &rBase, Float4 &fog, Pointer<Byte> cBuffer[4], Int &x, Int sMask[4], Int zMask[4], Int cMask[4])

+	{

+		Registers& r = *static_cast<Registers*>(&rBase);

+

 		if(!state.colorWriteActive(0))
 		{
 			return;
@@ -342,7 +342,7 @@
 				r.current.z &= Short4(0xF800u);
 			}
 
-			fogBlend(r, r.current, fog, r.z[0], r.rhw);
+			fogBlend(r, r.current, fog);
 
 			for(unsigned int q = 0; q < state.multiSample; q++)
 			{
@@ -361,7 +361,7 @@
 		case FORMAT_G32R32F:
 		case FORMAT_A32B32G32R32F:
 			convertSigned12(oC, r.current);
-			PixelRoutine::fogBlend(r, oC, fog, r.z[0], r.rhw);
+			PixelRoutine::fogBlend(r, oC, fog);
 
 			for(unsigned int q = 0; q < state.multiSample; q++)
 			{
@@ -377,9 +377,9 @@
 			break;
 		default:
 			ASSERT(false);
-		}
-	}
-
+		}

+	}

+

 	void PixelPipeline::blendTexture(Registers &r, Vector4s &temp, Vector4s &texture, int stage)
 	{
 		Vector4s *arg1;
@@ -1172,9 +1172,9 @@
 		default:
 			ASSERT(false);
 		}
-	}
-
-	void PixelPipeline::fogBlend(Registers &r, Vector4s &current, Float4 &f, Float4 &z, Float4 &rhw)
+	}

+

+	void PixelPipeline::fogBlend(Registers &r, Vector4s &current, Float4 &f)
 	{
 		if(!state.fogActive)
 		{
@@ -1183,7 +1183,7 @@
 
 		if(state.pixelFogMode != FOG_NONE)
 		{
-			pixelFog(r, f, z, rhw);
+			pixelFog(r, f);
 		}
 
 		UShort4 fog = convertFixed16(f, true);
@@ -1197,8 +1197,8 @@
 		current.x += As<Short4>(MulHigh(invFog, *Pointer<UShort4>(r.data + OFFSET(DrawData, fog.color4[0]))));
 		current.y += As<Short4>(MulHigh(invFog, *Pointer<UShort4>(r.data + OFFSET(DrawData, fog.color4[1]))));
 		current.z += As<Short4>(MulHigh(invFog, *Pointer<UShort4>(r.data + OFFSET(DrawData, fog.color4[2]))));
-	}
-
+	}

+

 	void PixelPipeline::specularPixel(Vector4s &current, Vector4s &specular)
 	{
 		if(!state.specularAdd)
@@ -1209,14 +1209,14 @@
 		current.x = AddSat(current.x, specular.x);
 		current.y = AddSat(current.y, specular.y);
 		current.z = AddSat(current.z, specular.z);
-	}
-
+	}

+

 	void PixelPipeline::sampleTexture(Registers &r, Vector4s &c, int coordinates, int stage, bool project)
 	{
-		Float4 u = r.vf[2 + coordinates].x;
-		Float4 v = r.vf[2 + coordinates].y;
-		Float4 w = r.vf[2 + coordinates].z;
-		Float4 q = r.vf[2 + coordinates].w;
+		Float4 u = r.v[2 + coordinates].x;
+		Float4 v = r.v[2 + coordinates].y;
+		Float4 w = r.v[2 + coordinates].z;
+		Float4 q = r.v[2 + coordinates].w;
 
 		if(perturbate)
 		{
@@ -1264,7 +1264,7 @@
 		r.cycles[PERF_TEX] += Ticks() - texTime;
 #endif
 	}
-
+

 	Short4 PixelPipeline::convertFixed12(RValue<Float4> cf)
 	{
 		return RoundShort4(cf * Float4(0x1000));
@@ -1290,7 +1290,7 @@
 		cf.z = convertSigned12(cs.z);
 		cf.w = convertSigned12(cs.w);
 	}
-
+

 	void PixelPipeline::writeDestination(Registers &r, Vector4s &d, const Dst &dst)
 	{
 		switch(dst.type)
@@ -1324,7 +1324,7 @@
 			ASSERT(false);
 		}
 	}
-
+

 	Vector4s PixelPipeline::fetchRegisterS(Registers &r, const Src &src)
 	{
 		Vector4s *reg;
@@ -1451,7 +1451,7 @@
 
 		return mod;
 	}
-
+

 	void PixelPipeline::MOV(Vector4s &dst, Vector4s &src0)
 	{
 		dst.x = src0.x;
@@ -1887,9 +1887,9 @@
 
 		Float4 E[3];   // Eye vector
 
-		E[0] = r.vf[2 + stage - 2].w;
-		E[1] = r.vf[2 + stage - 1].w;
-		E[2] = r.vf[2 + stage - 0].w;
+		E[0] = r.v[2 + stage - 2].w;
+		E[1] = r.v[2 + stage - 1].w;
+		E[2] = r.v[2 + stage - 0].w;
 
 		// Reflection
 		Float4 u__;
@@ -1964,5 +1964,5 @@
 		t0 = AddSat(t0, src0.y);
 		dst.y = t0;
 	}
-}
-
+}

+

diff --git a/src/Shader/PixelPipeline.hpp b/src/Shader/PixelPipeline.hpp
index 2b49ad7..1b3bfa1 100644
--- a/src/Shader/PixelPipeline.hpp
+++ b/src/Shader/PixelPipeline.hpp
@@ -59,7 +59,7 @@
 

 		void fixedFunction(Registers& r);

 		void blendTexture(Registers &r, Vector4s &temp, Vector4s &texture, int stage);

-		void fogBlend(Registers &r, Vector4s &current, Float4 &fog, Float4 &z, Float4 &rhw);

+		void fogBlend(Registers &r, Vector4s &current, Float4 &fog);
 		void specularPixel(Vector4s &current, Vector4s &specular);

 

 		void sampleTexture(Registers &r, Vector4s &c, int coordinates, int sampler, bool project = false);
diff --git a/src/Shader/PixelProgram.cpp b/src/Shader/PixelProgram.cpp
index 9b5673d..df629d9 100644
--- a/src/Shader/PixelProgram.cpp
+++ b/src/Shader/PixelProgram.cpp
@@ -121,14 +121,14 @@
 			{
 				if(dst.type == Shader::PARAMETER_TEXTURE)
 				{
-					d.x = r.vf[2 + dst.index].x;
-					d.y = r.vf[2 + dst.index].y;
-					d.z = r.vf[2 + dst.index].z;
-					d.w = r.vf[2 + dst.index].w;
+					d.x = r.v[2 + dst.index].x;
+					d.y = r.v[2 + dst.index].y;
+					d.z = r.v[2 + dst.index].z;
+					d.w = r.v[2 + dst.index].w;
 				}
 				else
 				{
-					d = r.rf[dst.index];
+					d = r.r[dst.index];
 				}
 			}
 
@@ -342,19 +342,19 @@
 					case Shader::PARAMETER_TEMP:
 						if(dst.rel.type == Shader::PARAMETER_VOID)
 						{
-							if(dst.x) pDst.x = r.rf[dst.index].x;
-							if(dst.y) pDst.y = r.rf[dst.index].y;
-							if(dst.z) pDst.z = r.rf[dst.index].z;
-							if(dst.w) pDst.w = r.rf[dst.index].w;
+							if(dst.x) pDst.x = r.r[dst.index].x;
+							if(dst.y) pDst.y = r.r[dst.index].y;
+							if(dst.z) pDst.z = r.r[dst.index].z;
+							if(dst.w) pDst.w = r.r[dst.index].w;
 						}
 						else
 						{
 							Int a = relativeAddress(r, dst);
 
-							if(dst.x) pDst.x = r.rf[dst.index + a].x;
-							if(dst.y) pDst.y = r.rf[dst.index + a].y;
-							if(dst.z) pDst.z = r.rf[dst.index + a].z;
-							if(dst.w) pDst.w = r.rf[dst.index + a].w;
+							if(dst.x) pDst.x = r.r[dst.index + a].x;
+							if(dst.y) pDst.y = r.r[dst.index + a].y;
+							if(dst.z) pDst.z = r.r[dst.index + a].z;
+							if(dst.w) pDst.w = r.r[dst.index + a].w;
 						}
 						break;
 					case Shader::PARAMETER_COLOROUT:
@@ -425,19 +425,19 @@
 				case Shader::PARAMETER_TEMP:
 					if(dst.rel.type == Shader::PARAMETER_VOID)
 					{
-						if(dst.x) r.rf[dst.index].x = d.x;
-						if(dst.y) r.rf[dst.index].y = d.y;
-						if(dst.z) r.rf[dst.index].z = d.z;
-						if(dst.w) r.rf[dst.index].w = d.w;
+						if(dst.x) r.r[dst.index].x = d.x;
+						if(dst.y) r.r[dst.index].y = d.y;
+						if(dst.z) r.r[dst.index].z = d.z;
+						if(dst.w) r.r[dst.index].w = d.w;
 					}
 					else
 					{
 						Int a = relativeAddress(r, dst);
 
-						if(dst.x) r.rf[dst.index + a].x = d.x;
-						if(dst.y) r.rf[dst.index + a].y = d.y;
-						if(dst.z) r.rf[dst.index + a].z = d.z;
-						if(dst.w) r.rf[dst.index + a].w = d.w;
+						if(dst.x) r.r[dst.index + a].x = d.x;
+						if(dst.y) r.r[dst.index + a].y = d.y;
+						if(dst.z) r.r[dst.index + a].z = d.z;
+						if(dst.w) r.r[dst.index + a].w = d.w;
 					}
 					break;
 				case Shader::PARAMETER_COLOROUT:
@@ -539,7 +539,7 @@
 
 			if(index == 0)
 			{
-				fogBlend(r, r.oC[index], fog, r.z[0], r.rhw);
+				fogBlend(r, r.oC[index], fog);
 			}
 
 			switch(state.targetFormat[index])
@@ -714,32 +714,32 @@
 		case Shader::PARAMETER_TEMP:
 			if(src.rel.type == Shader::PARAMETER_VOID)
 			{
-				reg = r.rf[i];
+				reg = r.r[i];
 			}
 			else
 			{
 				Int a = relativeAddress(r, src);
 
-				reg = r.rf[i + a];
+				reg = r.r[i + a];
 			}
 			break;
 		case Shader::PARAMETER_INPUT:
 			{
 				if(src.rel.type == Shader::PARAMETER_VOID)   // Not relative
 				{
-					reg = r.vf[i];
+					reg = r.v[i];
 				}
 				else if(src.rel.type == Shader::PARAMETER_LOOP)
 				{
 					Int aL = r.aL[r.loopDepth];
 
-					reg = r.vf[i + aL];
+					reg = r.v[i + aL];
 				}
 				else
 				{
 					Int a = relativeAddress(r, src);
 
-					reg = r.vf[i + a];
+					reg = r.v[i + a];
 				}
 			}
 			break;
@@ -747,7 +747,7 @@
 			reg = readConstant(r, src, offset);
 			break;
 		case Shader::PARAMETER_TEXTURE:
-			reg = r.vf[2 + i];
+			reg = r.v[2 + i];
 			break;
 		case Shader::PARAMETER_MISCTYPE:
 			if(src.index == 0) reg = r.vPos;
@@ -760,7 +760,7 @@
 			}
 			else if(src.rel.type == Shader::PARAMETER_TEMP)
 			{
-				reg.x = As<Float4>(Int4(i) + As<Int4>(r.rf[src.rel.index].x));
+				reg.x = As<Float4>(Int4(i) + As<Int4>(r.r[src.rel.index].x));
 			}
 			return reg;
 		case Shader::PARAMETER_PREDICATE:   return reg; // Dummy
@@ -898,11 +898,11 @@
 
 		if(var.rel.type == Shader::PARAMETER_TEMP)
 		{
-			return As<Int>(Extract(r.rf[var.rel.index].x, 0)) * var.rel.scale;
+			return As<Int>(Extract(r.r[var.rel.index].x, 0)) * var.rel.scale;
 		}
 		else if(var.rel.type == Shader::PARAMETER_INPUT)
 		{
-			return As<Int>(Extract(r.vf[var.rel.index].x, 0)) * var.rel.scale;
+			return As<Int>(Extract(r.v[var.rel.index].x, 0)) * var.rel.scale;
 		}
 		else if(var.rel.type == Shader::PARAMETER_OUTPUT)
 		{
diff --git a/src/Shader/PixelProgram.hpp b/src/Shader/PixelProgram.hpp
index 276b11c..82d2c87 100644
--- a/src/Shader/PixelProgram.hpp
+++ b/src/Shader/PixelProgram.hpp
@@ -38,7 +38,10 @@
 	private:

 		struct Registers : public PixelRoutine::Registers
 		{
-			Registers(const PixelShader *shader) : PixelRoutine::Registers(shader), loopDepth(-1)
+			Registers(const PixelShader *shader) :
+				PixelRoutine::Registers(shader),
+				r(shader && shader->dynamicallyIndexedTemporaries),
+				loopDepth(-1)
 			{
 				enableStack[0] = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
 
@@ -53,6 +56,12 @@
 				}
 			}
 
+			// Temporary registers
+			RegisterArray<4096> r;
+
+			// Color outputs
+			Vector4f oC[4];
+
 			// Shader variables
 			Vector4f vPos;
 			Vector4f vFace;
diff --git a/src/Shader/PixelRoutine.cpp b/src/Shader/PixelRoutine.cpp
index 52f9038..ccb750f 100644
--- a/src/Shader/PixelRoutine.cpp
+++ b/src/Shader/PixelRoutine.cpp
@@ -29,17 +29,16 @@
 
 	PixelRoutine::Registers::Registers(const PixelShader *shader) :
 		QuadRasterizer::Registers(),
-		rf(shader && shader->dynamicallyIndexedTemporaries),
-		vf(shader && shader->dynamicallyIndexedInput)
+		v(shader && shader->dynamicallyIndexedInput)
 	{
 		if(!shader || shader->getVersion() < 0x0200 || forceClearRegisters)
 		{
 			for(int i = 0; i < 10; i++)
 			{
-				vf[i].x = Float4(0.0f);
-				vf[i].y = Float4(0.0f);
-				vf[i].z = Float4(0.0f);
-				vf[i].w = Float4(0.0f);
+				v[i].x = Float4(0.0f);
+				v[i].y = Float4(0.0f);
+				v[i].z = Float4(0.0f);
+				v[i].w = Float4(0.0f);
 			}
 		}
 	}
@@ -169,11 +168,11 @@
 					{
 						if(!state.interpolant[interpolant].centroid)
 						{
-							r.vf[interpolant][component] = interpolate(xxxx, r.Dv[interpolant][component], rhw, r.primitive + OFFSET(Primitive, V[interpolant][component]), (state.interpolant[interpolant].flat & (1 << component)) != 0, state.perspective);
+							r.v[interpolant][component] = interpolate(xxxx, r.Dv[interpolant][component], rhw, r.primitive + OFFSET(Primitive, V[interpolant][component]), (state.interpolant[interpolant].flat & (1 << component)) != 0, state.perspective);
 						}
 						else
 						{
-							r.vf[interpolant][component] = interpolateCentroid(XXXX, YYYY, rhwCentroid, r.primitive + OFFSET(Primitive, V[interpolant][component]), (state.interpolant[interpolant].flat & (1 << component)) != 0, state.perspective);
+							r.v[interpolant][component] = interpolateCentroid(XXXX, YYYY, rhwCentroid, r.primitive + OFFSET(Primitive, V[interpolant][component]), (state.interpolant[interpolant].flat & (1 << component)) != 0, state.perspective);
 						}
 					}
 				}
@@ -185,19 +184,19 @@
 				case 0:
 					break;
 				case 1:
-					rcp = reciprocal(r.vf[interpolant].y);
-					r.vf[interpolant].x = r.vf[interpolant].x * rcp;
+					rcp = reciprocal(r.v[interpolant].y);
+					r.v[interpolant].x = r.v[interpolant].x * rcp;
 					break;
 				case 2:
-					rcp = reciprocal(r.vf[interpolant].z);
-					r.vf[interpolant].x = r.vf[interpolant].x * rcp;
-					r.vf[interpolant].y = r.vf[interpolant].y * rcp;
+					rcp = reciprocal(r.v[interpolant].z);
+					r.v[interpolant].x = r.v[interpolant].x * rcp;
+					r.v[interpolant].y = r.v[interpolant].y * rcp;
 					break;
 				case 3:
-					rcp = reciprocal(r.vf[interpolant].w);
-					r.vf[interpolant].x = r.vf[interpolant].x * rcp;
-					r.vf[interpolant].y = r.vf[interpolant].y * rcp;
-					r.vf[interpolant].z = r.vf[interpolant].z * rcp;
+					rcp = reciprocal(r.v[interpolant].w);
+					r.v[interpolant].x = r.v[interpolant].x * rcp;
+					r.v[interpolant].y = r.v[interpolant].y * rcp;
+					r.v[interpolant].z = r.v[interpolant].z * rcp;
 					break;
 				}
 			}
@@ -602,7 +601,7 @@
 		cMask[3] &= aMask3;
 	}
 
-	void PixelRoutine::fogBlend(Registers &r, Vector4f &c0, Float4 &fog, Float4 &z, Float4 &rhw)
+	void PixelRoutine::fogBlend(Registers &r, Vector4f &c0, Float4 &fog)
 	{
 		if(!state.fogActive)
 		{
@@ -611,7 +610,7 @@
 
 		if(state.pixelFogMode != FOG_NONE)
 		{
-			pixelFog(r, fog, z, rhw);
+			pixelFog(r, fog);
 
 			fog = Min(fog, Float4(1.0f));
 			fog = Max(fog, Float4(0.0f));
@@ -630,7 +629,7 @@
 		c0.z += *Pointer<Float4>(r.data + OFFSET(DrawData,fog.colorF[2]));
 	}
 
-	void PixelRoutine::pixelFog(Registers &r, Float4 &visibility, Float4 &z, Float4 &rhw)
+	void PixelRoutine::pixelFog(Registers &r, Float4 &visibility)
 	{
 		Float4 &zw = visibility;
 
@@ -638,17 +637,17 @@
 		{
 			if(state.wBasedFog)
 			{
-				zw = rhw;
+				zw = r.rhw;
 			}
 			else
 			{
 				if(complementaryDepthBuffer)
 				{
-					zw = Float4(1.0f) - z;
+					zw = Float4(1.0f) - r.z[0];
 				}
 				else
 				{
-					zw = z;
+					zw = r.z[0];
 				}
 			}
 		}
diff --git a/src/Shader/PixelRoutine.hpp b/src/Shader/PixelRoutine.hpp
index f86105e..38fb3a4 100644
--- a/src/Shader/PixelRoutine.hpp
+++ b/src/Shader/PixelRoutine.hpp
@@ -37,11 +37,9 @@
 			Float4 w;    // Used as is
 			Float4 rhw;  // Reciprocal w
 
-			RegisterArray<4096> rf; // Computation registers
-			RegisterArray<10> vf;   // Varying registers
+			RegisterArray<10> v;   // Varying registers
 
-			// Outputs
-			Vector4f oC[4];
+			// Depth output
 			Float4 oDepth;
 		};
 
@@ -56,41 +54,46 @@
 
 		virtual void quad(QuadRasterizer::Registers &r, Pointer<Byte> cBuffer[4], Pointer<Byte> &zBuffer, Pointer<Byte> &sBuffer, Int cMask[4], Int &x, Int &y);
 
+		void alphaTest(Registers &r, Int &aMask, Short4 &alpha);
+		void alphaToCoverage(Registers &r, Int cMask[4], Float4 &alpha);
+		void fogBlend(Registers &r, Vector4f &c0, Float4 &fog);
+		void pixelFog(Registers &r, Float4 &visibility);
+
+		// Raster operations
+		void alphaBlend(Registers &r, int index, Pointer<Byte> &cBuffer, Vector4s &current, Int &x);
+		void logicOperation(Registers &r, int index, Pointer<Byte> &cBuffer, Vector4s &current, Int &x);
+		void writeColor(Registers &r, int index, Pointer<Byte> &cBuffer, Int &i, Vector4s &current, Int &sMask, Int &zMask, Int &cMask);
+		void alphaBlend(Registers &r, int index, Pointer<Byte> &cBuffer, Vector4f &oC, Int &x);
+		void writeColor(Registers &r, int index, Pointer<Byte> &cBuffer, Int &i, Vector4f &oC, Int &sMask, Int &zMask, Int &cMask);
+
+		UShort4 convertFixed16(Float4 &cf, bool saturate = true);
+		void linearToSRGB12_16(Registers &r, Vector4s &c);
+
+		SamplerCore *sampler[TEXTURE_IMAGE_UNITS];
+
+	private:
 		Float4 interpolateCentroid(Float4 &x, Float4 &y, Float4 &rhw, Pointer<Byte> planeEquation, bool flat, bool perspective);
 		void stencilTest(Registers &r, Pointer<Byte> &sBuffer, int q, Int &x, Int &sMask, Int &cMask);
 		void stencilTest(Registers &r, Byte8 &value, StencilCompareMode stencilCompareMode, bool CCW);
 		void stencilOperation(Registers &r, Byte8 &newValue, Byte8 &bufferValue, StencilOperation stencilPassOperation, StencilOperation stencilZFailOperation, StencilOperation stencilFailOperation, bool CCW, Int &zMask, Int &sMask);
 		void stencilOperation(Registers &r, Byte8 &output, Byte8 &bufferValue, StencilOperation operation, bool CCW);
 		Bool depthTest(Registers &r, Pointer<Byte> &zBuffer, int q, Int &x, Float4 &z, Int &sMask, Int &zMask, Int &cMask);
-		void alphaTest(Registers &r, Int &aMask, Short4 &alpha);
-		void alphaToCoverage(Registers &r, Int cMask[4], Float4 &alpha);
-		void fogBlend(Registers &r, Vector4f &c0, Float4 &fog, Float4 &z, Float4 &rhw);
-		void pixelFog(Registers &r, Float4 &visibility, Float4 &z, Float4 &rhw);
 
 		// Raster operations
 		void blendFactor(Registers &r, const Vector4s &blendFactor, const Vector4s &current, const Vector4s &pixel, BlendFactor blendFactorActive);
 		void blendFactorAlpha(Registers &r, const Vector4s &blendFactor, const Vector4s &current, const Vector4s &pixel, BlendFactor blendFactorAlphaActive);
 		void readPixel(Registers &r, int index, Pointer<Byte> &cBuffer, Int &x, Vector4s &pixel);
-		void alphaBlend(Registers &r, int index, Pointer<Byte> &cBuffer, Vector4s &current, Int &x);
-		void logicOperation(Registers &r, int index, Pointer<Byte> &cBuffer, Vector4s &current, Int &x);
-		void writeColor(Registers &r, int index, Pointer<Byte> &cBuffer, Int &i, Vector4s &current, Int &sMask, Int &zMask, Int &cMask);
 		void blendFactor(Registers &r, const Vector4f &blendFactor, const Vector4f &oC, const Vector4f &pixel, BlendFactor blendFactorActive);
 		void blendFactorAlpha(Registers &r, const Vector4f &blendFactor, const Vector4f &oC, const Vector4f &pixel, BlendFactor blendFactorAlphaActive);
-		void alphaBlend(Registers &r, int index, Pointer<Byte> &cBuffer, Vector4f &oC, Int &x);
-		void writeColor(Registers &r, int index, Pointer<Byte> &cBuffer, Int &i, Vector4f &oC, Int &sMask, Int &zMask, Int &cMask);
 		void writeStencil(Registers &r, Pointer<Byte> &sBuffer, int q, Int &x, Int &sMask, Int &zMask, Int &cMask);
 		void writeDepth(Registers &r, Pointer<Byte> &zBuffer, int q, Int &x, Float4 &z, Int &zMask);
 
-		UShort4 convertFixed16(Float4 &cf, bool saturate = true);
 		void sRGBtoLinear16_12_16(Registers &r, Vector4s &c);
 		void sRGBtoLinear12_16(Registers &r, Vector4s &c);
 		void linearToSRGB16_12_16(Registers &r, Vector4s &c);
-		void linearToSRGB12_16(Registers &r, Vector4s &c);
 		Float4 sRGBtoLinear(const Float4 &x);
 
 		bool colorUsed();
-
-		SamplerCore *sampler[TEXTURE_IMAGE_UNITS];
 	};
 }