Shader cleanup

A couple of class members from PixelShader and VertexShader
were still public. Fixed that in this cleanup.

Change-Id: I2dfaac7fd4cecdc791f1ef7236148e74c4b5b486
Reviewed-on: https://swiftshader-review.googlesource.com/5850
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/D3D9/Direct3DDevice9.cpp b/src/D3D9/Direct3DDevice9.cpp
index 96a0b9a..ddc6606 100644
--- a/src/D3D9/Direct3DDevice9.cpp
+++ b/src/D3D9/Direct3DDevice9.cpp
@@ -5789,8 +5789,8 @@
 				{
 					for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
 					{
-						if(usage == shader->input[i].usage &&
-						   index == shader->input[i].index)
+						const sw::Shader::Semantic& input = shader->getInput(i);
+						if((usage == input.usage) && (index == input.index))
 						{
 							renderer->setInputStream(i, attribute);
 
@@ -5802,8 +5802,9 @@
 				{
 					for(int i = 0; i < MAX_VERTEX_OUTPUTS; i++)
 					{
-						if((usage == shader->output[i][0].usage || (usage == D3DDECLUSAGE_POSITIONT && shader->output[i][0].usage == D3DDECLUSAGE_POSITION)) &&
-						    index == shader->output[i][0].index)
+						const sw::Shader::Semantic& output = shader->getOutput(i, 0);
+						if(((usage == output.usage) || (usage == D3DDECLUSAGE_POSITIONT && output.usage == D3DDECLUSAGE_POSITION)) &&
+						   (index == output.index))
 						{
 							renderer->setInputStream(i, attribute);
 
diff --git a/src/OpenGL/compiler/OutputASM.cpp b/src/OpenGL/compiler/OutputASM.cpp
index 502e372..29da8e4 100644
--- a/src/OpenGL/compiler/OutputASM.cpp
+++ b/src/OpenGL/compiler/OutputASM.cpp
@@ -2597,9 +2597,9 @@
 		case EvqConstReadOnly:       return temporaryRegister(operand);
 		case EvqPosition:            return varyingRegister(operand);
 		case EvqPointSize:           return varyingRegister(operand);
-		case EvqInstanceID:          vertexShader->instanceIdDeclared = true; return 0;
-		case EvqFragCoord:           pixelShader->vPosDeclared = true;  return 0;
-		case EvqFrontFacing:         pixelShader->vFaceDeclared = true; return 1;
+		case EvqInstanceID:          vertexShader->declareInstanceId(); return 0;
+		case EvqFragCoord:           pixelShader->declareVPos();  return 0;
+		case EvqFrontFacing:         pixelShader->declareVFace(); return 1;
 		case EvqPointCoord:          return varyingRegister(operand);
 		case EvqFragColor:           return 0;
 		case EvqFragData:            return fragmentOutputRegister(operand);
@@ -2764,10 +2764,7 @@
 				if(varying->getQualifier() == EvqPointCoord)
 				{
 					ASSERT(varying->isRegister());
-					if(componentCount >= 1) pixelShader->semantic[var][0] = sw::Shader::Semantic(sw::Shader::USAGE_TEXCOORD, var);
-					if(componentCount >= 2) pixelShader->semantic[var][1] = sw::Shader::Semantic(sw::Shader::USAGE_TEXCOORD, var);
-					if(componentCount >= 3) pixelShader->semantic[var][2] = sw::Shader::Semantic(sw::Shader::USAGE_TEXCOORD, var);
-					if(componentCount >= 4) pixelShader->semantic[var][3] = sw::Shader::Semantic(sw::Shader::USAGE_TEXCOORD, var);
+					pixelShader->setInput(var, componentCount, sw::Shader::Semantic(sw::Shader::USAGE_TEXCOORD, var));
 				}
 				else
 				{
@@ -2775,10 +2772,7 @@
 					{
 						bool flat = hasFlatQualifier(varying);
 
-						if(componentCount >= 1) pixelShader->semantic[var + i][0] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, var + i, flat);
-						if(componentCount >= 2) pixelShader->semantic[var + i][1] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, var + i, flat);
-						if(componentCount >= 3) pixelShader->semantic[var + i][2] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, var + i, flat);
-						if(componentCount >= 4) pixelShader->semantic[var + i][3] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, var + i, flat);
+						pixelShader->setInput(var + i, componentCount, sw::Shader::Semantic(sw::Shader::USAGE_COLOR, var + i, flat));
 					}
 				}
 			}
@@ -2793,20 +2787,12 @@
 				if(varying->getQualifier() == EvqPosition)
 				{
 					ASSERT(varying->isRegister());
-					vertexShader->output[var][0] = sw::Shader::Semantic(sw::Shader::USAGE_POSITION, 0);
-					vertexShader->output[var][1] = sw::Shader::Semantic(sw::Shader::USAGE_POSITION, 0);
-					vertexShader->output[var][2] = sw::Shader::Semantic(sw::Shader::USAGE_POSITION, 0);
-					vertexShader->output[var][3] = sw::Shader::Semantic(sw::Shader::USAGE_POSITION, 0);
-					vertexShader->positionRegister = var;
+					vertexShader->setPositionRegister(var);
 				}
 				else if(varying->getQualifier() == EvqPointSize)
 				{
 					ASSERT(varying->isRegister());
-					vertexShader->output[var][0] = sw::Shader::Semantic(sw::Shader::USAGE_PSIZE, 0);
-					vertexShader->output[var][1] = sw::Shader::Semantic(sw::Shader::USAGE_PSIZE, 0);
-					vertexShader->output[var][2] = sw::Shader::Semantic(sw::Shader::USAGE_PSIZE, 0);
-					vertexShader->output[var][3] = sw::Shader::Semantic(sw::Shader::USAGE_PSIZE, 0);
-					vertexShader->pointSizeRegister = var;
+					vertexShader->setPointSizeRegister(var);
 				}
 				else
 				{
@@ -2909,7 +2895,7 @@
 				{
 					for(int i = 0; i < registerCount; i++)
 					{
-						vertexShader->input[index + i] = sw::Shader::Semantic(sw::Shader::USAGE_TEXCOORD, index + i);
+						vertexShader->setInput(index + i, sw::Shader::Semantic(sw::Shader::USAGE_TEXCOORD, index + i));
 					}
 				}
 
diff --git a/src/OpenGL/libGL/Program.cpp b/src/OpenGL/libGL/Program.cpp
index a8f91d2..db3a860 100644
--- a/src/OpenGL/libGL/Program.cpp
+++ b/src/OpenGL/libGL/Program.cpp
@@ -1148,20 +1148,14 @@
 
 						for(int i = 0; i < registers; i++)
 						{
-							if(components >= 1) vertexBinary->output[out + i][0] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i);
-							if(components >= 2) vertexBinary->output[out + i][1] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i);
-							if(components >= 3) vertexBinary->output[out + i][2] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i);
-							if(components >= 4) vertexBinary->output[out + i][3] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i);
+							vertexBinary->setOutput(out + i, components, sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i));
 						}
 					}
 					else   // Vertex varying is declared but not written to
 					{
 						for(int i = 0; i < registers; i++)
 						{
-							if(components >= 1) pixelBinary->semantic[in + i][0] = sw::Shader::Semantic();
-							if(components >= 2) pixelBinary->semantic[in + i][1] = sw::Shader::Semantic();
-							if(components >= 3) pixelBinary->semantic[in + i][2] = sw::Shader::Semantic();
-							if(components >= 4) pixelBinary->semantic[in + i][3] = sw::Shader::Semantic();
+							pixelBinary->setInput(in + i, components, sw::Shader::Semantic());
 						}
 					}
 
diff --git a/src/OpenGL/libGLESv2/Program.cpp b/src/OpenGL/libGLESv2/Program.cpp
index af3b21d..0027996 100644
--- a/src/OpenGL/libGLESv2/Program.cpp
+++ b/src/OpenGL/libGLESv2/Program.cpp
@@ -1330,22 +1330,14 @@
 
 						for(int i = 0; i < registers; i++)
 						{
-							bool flat = pixelBinary->semantic[in + i][0].flat;
-
-							if(components >= 1) vertexBinary->output[out + i][0] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i, flat);
-							if(components >= 2) vertexBinary->output[out + i][1] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i, flat);
-							if(components >= 3) vertexBinary->output[out + i][2] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i, flat);
-							if(components >= 4) vertexBinary->output[out + i][3] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i, flat);
+							vertexBinary->setOutput(out + i, components, sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i, pixelBinary->getInput(in + i, 0).flat));
 						}
 					}
 					else   // Vertex varying is declared but not written to
 					{
 						for(int i = 0; i < registers; i++)
 						{
-							if(components >= 1) pixelBinary->semantic[in + i][0] = sw::Shader::Semantic();
-							if(components >= 2) pixelBinary->semantic[in + i][1] = sw::Shader::Semantic();
-							if(components >= 3) pixelBinary->semantic[in + i][2] = sw::Shader::Semantic();
-							if(components >= 4) pixelBinary->semantic[in + i][3] = sw::Shader::Semantic();
+							pixelBinary->setInput(in + i, components, sw::Shader::Semantic());
 						}
 					}
 
diff --git a/src/Renderer/Context.cpp b/src/Renderer/Context.cpp
index b206dde..1a35873 100644
--- a/src/Renderer/Context.cpp
+++ b/src/Renderer/Context.cpp
@@ -550,7 +550,7 @@
 		{
 			if(!preTransformed)
 			{
-				if(vertexShader->output[T0 + coordinate][component].usage == Shader::USAGE_TEXCOORD)
+				if(vertexShader->getOutput(T0 + coordinate, component).usage == Shader::USAGE_TEXCOORD)
 				{
 					hasTexture = true;
 				}
@@ -1260,7 +1260,7 @@
 
 		if(vertexShader)
 		{
-			vertexDiffuse = vertexShader->output[C0][component].active();
+			vertexDiffuse = vertexShader->getOutput(C0, component).active();
 		}
 		else if(!preTransformed)
 		{
@@ -1327,7 +1327,7 @@
 		}
 		else
 		{
-			vertexSpecular = vertexShader->output[C1][component].active();
+			vertexSpecular = vertexShader->getOutput(C1, component).active();
 		}
 
 		// Pixel processor requires specular component
diff --git a/src/Renderer/PixelProcessor.cpp b/src/Renderer/PixelProcessor.cpp
index 7b6580a..76356e4 100644
--- a/src/Renderer/PixelProcessor.cpp
+++ b/src/Renderer/PixelProcessor.cpp
@@ -1111,7 +1111,7 @@
 			{
 				for(int component = 0; component < 4; component++)
 				{
-					const Shader::Semantic &semantic = context->pixelShader->semantic[interpolant][component];
+					const Shader::Semantic &semantic = context->pixelShader->getInput(interpolant, component);
 
 					if(semantic.active())
 					{
@@ -1140,7 +1140,7 @@
 			{
 				for(int component = 0; component < 4; component++)
 				{
-					state.interpolant[interpolant].centroid = context->pixelShader->semantic[interpolant][0].centroid;
+					state.interpolant[interpolant].centroid = context->pixelShader->getInput(interpolant, 0).centroid;
 				}
 			}
 		}
diff --git a/src/Renderer/QuadRasterizer.cpp b/src/Renderer/QuadRasterizer.cpp
index 691d325..f88c39e 100644
--- a/src/Renderer/QuadRasterizer.cpp
+++ b/src/Renderer/QuadRasterizer.cpp
@@ -332,11 +332,11 @@
 
 	bool QuadRasterizer::interpolateZ() const
 	{
-		return state.depthTestActive || state.pixelFogActive() || (shader && shader->vPosDeclared && fullPixelPositionRegister);
+		return state.depthTestActive || state.pixelFogActive() || (shader && shader->isVPosDeclared() && fullPixelPositionRegister);
 	}
 
 	bool QuadRasterizer::interpolateW() const
 	{
-		return state.perspective || (shader && shader->vPosDeclared && fullPixelPositionRegister);
+		return state.perspective || (shader && shader->isVPosDeclared() && fullPixelPositionRegister);
 	}
 }
diff --git a/src/Renderer/Renderer.cpp b/src/Renderer/Renderer.cpp
index d854deb..38b19ec 100644
--- a/src/Renderer/Renderer.cpp
+++ b/src/Renderer/Renderer.cpp
@@ -445,7 +445,7 @@
 					draw->vsDirtyConstB = 0;
 				}
 
-				if(context->vertexShader->instanceIdDeclared)
+				if(context->vertexShader->isInstanceIdDeclared())
 				{
 					data->instanceID = context->instanceID;
 				}
diff --git a/src/Renderer/SetupProcessor.cpp b/src/Renderer/SetupProcessor.cpp
index 750846f..772327f 100644
--- a/src/Renderer/SetupProcessor.cpp
+++ b/src/Renderer/SetupProcessor.cpp
@@ -73,7 +73,7 @@
 	{
 		State state;
 
-		bool vPosZW = (context->pixelShader && context->pixelShader->vPosDeclared && fullPixelPositionRegister);
+		bool vPosZW = (context->pixelShader && context->pixelShader->isVPosDeclared() && fullPixelPositionRegister);
 
 		state.isDrawPoint = context->isDrawPoint(true);
 		state.isDrawLine = context->isDrawLine(true);
@@ -86,7 +86,7 @@
 		state.cullMode = context->cullMode;
 		state.twoSidedStencil = context->stencilActive() && context->twoSidedStencil;
 		state.slopeDepthBias = slopeDepthBias != 0.0f;
-		state.vFace = context->pixelShader && context->pixelShader->vFaceDeclared;
+		state.vFace = context->pixelShader && context->pixelShader->isVFaceDeclared();
 
 		state.positionRegister = Pos;
 		state.pointSizeRegister = Unused;
@@ -96,8 +96,8 @@
 
 		if(context->vertexShader)
 		{
-			state.positionRegister = context->vertexShader->positionRegister;
-			state.pointSizeRegister = context->vertexShader->pointSizeRegister;
+			state.positionRegister = context->vertexShader->getPositionRegister();
+			state.pointSizeRegister = context->vertexShader->getPointSizeRegister();
 		}
 		else if(context->pointSizeActive())
 		{
@@ -129,14 +129,14 @@
 				for(int component = 0; component < 4; component++)
 				{
 					int project = context->isProjectionComponent(interpolant - 2, component) ? 1 : 0;
-					const Shader::Semantic& semantic = context->pixelShader->semantic[interpolant][component - project];
+					const Shader::Semantic& semantic = context->pixelShader->getInput(interpolant, component - project);
 
 					if(semantic.active())
 					{
 						int input = interpolant;
 						for(int i = 0; i < MAX_VERTEX_OUTPUTS; i++)
 						{
-							if(semantic == context->vertexShader->output[i][component - project])
+							if(semantic == context->vertexShader->getOutput(i, component - project))
 							{
 								input = i;
 								break;
@@ -163,7 +163,7 @@
 			{
 				for(int component = 0; component < 4; component++)
 				{
-					const Shader::Semantic& semantic = context->pixelShader->semantic[interpolant][component];
+					const Shader::Semantic& semantic = context->pixelShader->getInput(interpolant, component);
 
 					switch(semantic.usage)
 					{
diff --git a/src/Renderer/VertexProcessor.cpp b/src/Renderer/VertexProcessor.cpp
index 574cdbb..ced0870 100644
--- a/src/Renderer/VertexProcessor.cpp
+++ b/src/Renderer/VertexProcessor.cpp
@@ -909,8 +909,8 @@
 
 		state.fixedFunction = !context->vertexShader && context->pixelShaderVersion() < 0x0300;
 		state.textureSampling = context->vertexShader ? context->vertexShader->containsTextureSampling() : false;
-		state.positionRegister = context->vertexShader ? context->vertexShader->positionRegister : Pos;
-		state.pointSizeRegister = context->vertexShader ? context->vertexShader->pointSizeRegister : Pts;
+		state.positionRegister = context->vertexShader ? context->vertexShader->getPositionRegister() : Pos;
+		state.pointSizeRegister = context->vertexShader ? context->vertexShader->getPointSizeRegister() : Pts;
 
 		state.vertexBlendMatrixCount = context->vertexBlendMatrixCountActive();
 		state.indexedVertexBlendEnable = context->indexedVertexBlendActive();
@@ -985,10 +985,10 @@
 		{
 			for(int i = 0; i < MAX_VERTEX_OUTPUTS; i++)
 			{
-				state.output[i].xWrite = context->vertexShader->output[i][0].active();
-				state.output[i].yWrite = context->vertexShader->output[i][1].active();
-				state.output[i].zWrite = context->vertexShader->output[i][2].active();
-				state.output[i].wWrite = context->vertexShader->output[i][3].active();
+				state.output[i].xWrite = context->vertexShader->getOutput(i, 0).active();
+				state.output[i].yWrite = context->vertexShader->getOutput(i, 1).active();
+				state.output[i].zWrite = context->vertexShader->getOutput(i, 2).active();
+				state.output[i].wWrite = context->vertexShader->getOutput(i, 3).active();
 			}
 		}
 		else if(!context->preTransformed || context->pixelShaderVersion() < 0x0300)
diff --git a/src/Shader/PixelProgram.cpp b/src/Shader/PixelProgram.cpp
index 5c04196..1f50547 100644
--- a/src/Shader/PixelProgram.cpp
+++ b/src/Shader/PixelProgram.cpp
@@ -28,7 +28,7 @@
 	{
 		if(shader->getVersion() >= 0x0300)
 		{
-			if(shader->vPosDeclared)
+			if(shader->isVPosDeclared())
 			{
 				if(!halfIntegerCoordinates)
 				{
@@ -48,7 +48,7 @@
 				}
 			}
 
-			if(shader->vFaceDeclared)
+			if(shader->isVFaceDeclared())
 			{
 				Float4 area = *Pointer<Float>(primitive + OFFSET(Primitive, area));
 				Float4 face = booleanFaceRegister ? Float4(As<Float4>(CmpNLT(area, Float4(0.0f)))) : area;
diff --git a/src/Shader/PixelShader.cpp b/src/Shader/PixelShader.cpp
index 806b6e8..0b78c14 100644
--- a/src/Shader/PixelShader.cpp
+++ b/src/Shader/PixelShader.cpp
@@ -34,7 +34,7 @@
 				append(new sw::Shader::Instruction(*ps->getInstruction(i)));
 			}
 
-			memcpy(semantic, ps->semantic, sizeof(semantic));
+			memcpy(input, ps->input, sizeof(input));
 			vPosDeclared = ps->vPosDeclared;
 			vFaceDeclared = ps->vFaceDeclared;
 			usedSamplers = ps->usedSamplers;
@@ -125,17 +125,30 @@
 
 	bool PixelShader::usesDiffuse(int component) const
 	{
-		return semantic[0][component].active();
+		return input[0][component].active();
 	}
 
 	bool PixelShader::usesSpecular(int component) const
 	{
-		return semantic[1][component].active();
+		return input[1][component].active();
 	}
 
 	bool PixelShader::usesTexture(int coordinate, int component) const
 	{
-		return semantic[2 + coordinate][component].active();
+		return input[2 + coordinate][component].active();
+	}
+
+	void PixelShader::setInput(int inputIdx, int nbComponents, const sw::Shader::Semantic& semantic)
+	{
+		for(int i = 0; i < nbComponents; ++i)
+		{
+			input[inputIdx][i] = semantic;
+		}
+	}
+
+	const sw::Shader::Semantic& PixelShader::getInput(int inputIdx, int component) const
+	{
+		return input[inputIdx][component];
 	}
 
 	void PixelShader::analyze()
@@ -188,22 +201,22 @@
 		if(version < 0x0300)
 		{
 			// Set default mapping; disable unused interpolants below
-			semantic[0][0] = Semantic(Shader::USAGE_COLOR, 0);
-			semantic[0][1] = Semantic(Shader::USAGE_COLOR, 0);
-			semantic[0][2] = Semantic(Shader::USAGE_COLOR, 0);
-			semantic[0][3] = Semantic(Shader::USAGE_COLOR, 0);
+			input[0][0] = Semantic(Shader::USAGE_COLOR, 0);
+			input[0][1] = Semantic(Shader::USAGE_COLOR, 0);
+			input[0][2] = Semantic(Shader::USAGE_COLOR, 0);
+			input[0][3] = Semantic(Shader::USAGE_COLOR, 0);
 
-			semantic[1][0] = Semantic(Shader::USAGE_COLOR, 1);
-			semantic[1][1] = Semantic(Shader::USAGE_COLOR, 1);
-			semantic[1][2] = Semantic(Shader::USAGE_COLOR, 1);
-			semantic[1][3] = Semantic(Shader::USAGE_COLOR, 1);
+			input[1][0] = Semantic(Shader::USAGE_COLOR, 1);
+			input[1][1] = Semantic(Shader::USAGE_COLOR, 1);
+			input[1][2] = Semantic(Shader::USAGE_COLOR, 1);
+			input[1][3] = Semantic(Shader::USAGE_COLOR, 1);
 
 			for(int i = 0; i < 8; i++)
 			{
-				semantic[2 + i][0] = Semantic(Shader::USAGE_TEXCOORD, i);
-				semantic[2 + i][1] = Semantic(Shader::USAGE_TEXCOORD, i);
-				semantic[2 + i][2] = Semantic(Shader::USAGE_TEXCOORD, i);
-				semantic[2 + i][3] = Semantic(Shader::USAGE_TEXCOORD, i);
+				input[2 + i][0] = Semantic(Shader::USAGE_TEXCOORD, i);
+				input[2 + i][1] = Semantic(Shader::USAGE_TEXCOORD, i);
+				input[2 + i][2] = Semantic(Shader::USAGE_TEXCOORD, i);
+				input[2 + i][3] = Semantic(Shader::USAGE_TEXCOORD, i);
 			}
 
 			Shader::SamplerType samplerType[16];
@@ -660,7 +673,7 @@
 				{
 					if(!interpolant[index][component])
 					{
-						semantic[index][component] = Semantic();
+						input[index][component] = Semantic();
 					}
 				}
 			}
@@ -678,10 +691,10 @@
 						unsigned char mask = instruction[i]->dst.mask;
 						unsigned char reg = instruction[i]->dst.index;
 
-						if(mask & 0x01)	semantic[reg][0] = Semantic(usage, index);
-						if(mask & 0x02) semantic[reg][1] = Semantic(usage, index);
-						if(mask & 0x04) semantic[reg][2] = Semantic(usage, index);
-						if(mask & 0x08)	semantic[reg][3] = Semantic(usage, index);
+						if(mask & 0x01)	input[reg][0] = Semantic(usage, index);
+						if(mask & 0x02) input[reg][1] = Semantic(usage, index);
+						if(mask & 0x04) input[reg][2] = Semantic(usage, index);
+						if(mask & 0x08)	input[reg][3] = Semantic(usage, index);
 					}
 					else if(instruction[i]->dst.type == Shader::PARAMETER_MISCTYPE)
 					{
@@ -713,10 +726,10 @@
 					switch(instruction[i]->dst.type)
 					{
 					case Shader::PARAMETER_INPUT:
-						semantic[reg][0].centroid = centroid;
+						input[reg][0].centroid = centroid;
 						break;
 					case Shader::PARAMETER_TEXTURE:
-						semantic[2 + reg][0].centroid = centroid;
+						input[2 + reg][0].centroid = centroid;
 						break;
 					default:
 						break;
diff --git a/src/Shader/PixelShader.hpp b/src/Shader/PixelShader.hpp
index 2fbde6b..a06aaaa 100644
--- a/src/Shader/PixelShader.hpp
+++ b/src/Shader/PixelShader.hpp
@@ -36,18 +36,24 @@
 		bool usesSpecular(int component) const;
 		bool usesTexture(int coordinate, int component) const;
 
-		virtual void analyze();
+		void setInput(int inputIdx, int nbComponents, const Semantic& semantic);
+		const Semantic& getInput(int inputIdx, int component) const;
 
-		Semantic semantic[MAX_FRAGMENT_INPUTS][4];   // FIXME: Private
-
-		bool vPosDeclared;
-		bool vFaceDeclared;
+		void declareVPos() { vPosDeclared = true; }
+		void declareVFace() { vFaceDeclared = true; }
+		bool isVPosDeclared() const { return vPosDeclared; }
+		bool isVFaceDeclared() const { return vFaceDeclared; }
 
 	private:
+		void analyze();
 		void analyzeZOverride();
 		void analyzeKill();
 		void analyzeInterpolants();
 
+		Semantic input[MAX_FRAGMENT_INPUTS][4];
+
+		bool vPosDeclared;
+		bool vFaceDeclared;
 		bool zOverride;
 		bool kill;
 		bool centroid;
diff --git a/src/Shader/Shader.hpp b/src/Shader/Shader.hpp
index 3cd08a3..ae8b90f 100644
--- a/src/Shader/Shader.hpp
+++ b/src/Shader/Shader.hpp
@@ -593,7 +593,6 @@
 		};
 
 		void optimize();
-		virtual void analyze() = 0;
 
 		// FIXME: Private
 		unsigned int dirtyConstantsF;
diff --git a/src/Shader/VertexProgram.cpp b/src/Shader/VertexProgram.cpp
index 5fda7e7..20caa49 100644
--- a/src/Shader/VertexProgram.cpp
+++ b/src/Shader/VertexProgram.cpp
@@ -50,7 +50,7 @@
 			enableContinue = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
 		}
 
-		if(shader->instanceIdDeclared)
+		if(shader->isInstanceIdDeclared())
 		{
 			instanceID = *Pointer<Int>(data + OFFSET(DrawData,instanceID));
 		}
@@ -596,7 +596,7 @@
 		{
 			for(int i = 0; i < MAX_VERTEX_OUTPUTS; i++)
 			{
-				unsigned char usage = shader->output[i][0].usage;
+				unsigned char usage = shader->getOutput(i, 0).usage;
 
 				switch(usage)
 				{
diff --git a/src/Shader/VertexShader.cpp b/src/Shader/VertexShader.cpp
index 733c113..dd62b4b 100644
--- a/src/Shader/VertexShader.cpp
+++ b/src/Shader/VertexShader.cpp
@@ -27,6 +27,7 @@
 		positionRegister = Pos;
 		pointSizeRegister = Unused;
 		instanceIdDeclared = false;
+		textureSampling = false;
 
 		for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
 		{
@@ -59,6 +60,7 @@
 		positionRegister = Pos;
 		pointSizeRegister = Unused;
 		instanceIdDeclared = false;
+		textureSampling = false;
 
 		for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
 		{
@@ -149,6 +151,41 @@
 		return textureSampling;
 	}
 
+	void VertexShader::setInput(int inputIdx, const sw::Shader::Semantic& semantic)
+	{
+		input[inputIdx] = semantic;
+	}
+
+	void VertexShader::setOutput(int outputIdx, int nbComponents, const sw::Shader::Semantic& semantic)
+	{
+		for(int i = 0; i < nbComponents; ++i)
+		{
+			output[outputIdx][i] = semantic;
+		}
+	}
+
+	void VertexShader::setPositionRegister(int posReg)
+	{
+		setOutput(posReg, 4, sw::Shader::Semantic(sw::Shader::USAGE_POSITION, 0));
+		positionRegister = posReg;
+	}
+	
+	void VertexShader::setPointSizeRegister(int ptSizeReg)
+	{
+		setOutput(ptSizeReg, 4, sw::Shader::Semantic(sw::Shader::USAGE_PSIZE, 0));
+		pointSizeRegister = ptSizeReg;
+	}
+
+	const sw::Shader::Semantic& VertexShader::getInput(int inputIdx) const
+	{
+		return input[inputIdx];
+	}
+
+	const sw::Shader::Semantic& VertexShader::getOutput(int outputIdx, int component) const
+	{
+		return output[outputIdx][component];
+	}
+
 	void VertexShader::analyze()
 	{
 		analyzeInput();
diff --git a/src/Shader/VertexShader.hpp b/src/Shader/VertexShader.hpp
index 0fdd09c..4eb6786 100644
--- a/src/Shader/VertexShader.hpp
+++ b/src/Shader/VertexShader.hpp
@@ -31,21 +31,31 @@
 		static int validate(const unsigned long *const token);   // Returns number of instructions if valid
 		bool containsTextureSampling() const;
 
-		virtual void analyze();
+		void setInput(int inputIdx, const Semantic& semantic);
+		void setOutput(int outputIdx, int nbComponents, const Semantic& semantic);
+		void setPositionRegister(int posReg);
+		void setPointSizeRegister(int ptSizeReg);
+		void declareInstanceId() { instanceIdDeclared = true; }
 
-		int positionRegister;     // FIXME: Private
-		int pointSizeRegister;    // FIXME: Private
-
-		bool instanceIdDeclared;
-
-		Semantic input[MAX_VERTEX_INPUTS];        // FIXME: Private
-		Semantic output[MAX_VERTEX_OUTPUTS][4];   // FIXME: Private
+		const Semantic& getInput(int inputIdx) const;
+		const Semantic& getOutput(int outputIdx, int component) const;
+		int getPositionRegister() const { return positionRegister; }
+		int getPointSizeRegister() const { return pointSizeRegister; }
+		bool isInstanceIdDeclared() const { return instanceIdDeclared; }
 
 	private:
+		void analyze();
 		void analyzeInput();
 		void analyzeOutput();
 		void analyzeTextureSampling();
 
+		Semantic input[MAX_VERTEX_INPUTS];
+		Semantic output[MAX_VERTEX_OUTPUTS][4];
+
+		int positionRegister;
+		int pointSizeRegister;
+
+		bool instanceIdDeclared;
 		bool textureSampling;
 	};
 }