Wire VS interfaces onto spirv shader

Bug: b/124177079
Change-Id: Idd7ae86fc2d4e79a8d4b8e395eb0e547a0ba6470
Reviewed-on: https://swiftshader-review.googlesource.com/c/24591
Reviewed-by: Ben Clayton <bclayton@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Tested-by: Chris Forbes <chrisforbes@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
diff --git a/src/Device/VertexProcessor.hpp b/src/Device/VertexProcessor.hpp
index 51dbd5c..b9c6590 100644
--- a/src/Device/VertexProcessor.hpp
+++ b/src/Device/VertexProcessor.hpp
@@ -51,8 +51,6 @@
 			uint64_t shaderID;
 
 			bool textureSampling           : 1;   // TODO: Eliminate by querying shader.
-			unsigned int positionRegister  : BITS(MAX_VERTEX_OUTPUTS);   // TODO: Eliminate by querying shader.
-			unsigned int pointSizeRegister : BITS(MAX_VERTEX_OUTPUTS);   // TODO: Eliminate by querying shader.
 			unsigned char verticesPerPrimitive                : 2; // 1 (points), 2 (lines) or 3 (triangles)
 
 			bool multiSampling  : 1;
@@ -72,37 +70,7 @@
 				unsigned int attribType : BITS(SpirvShader::ATTRIBTYPE_LAST);
 			};
 
-			struct Output
-			{
-				union
-				{
-					unsigned char write : 4;
-
-					struct
-					{
-						unsigned char xWrite : 1;
-						unsigned char yWrite : 1;
-						unsigned char zWrite : 1;
-						unsigned char wWrite : 1;
-					};
-				};
-
-				union
-				{
-					unsigned char clamp : 4;
-
-					struct
-					{
-						unsigned char xClamp : 1;
-						unsigned char yClamp : 1;
-						unsigned char zClamp : 1;
-						unsigned char wClamp : 1;
-					};
-				};
-			};
-
 			Input input[MAX_VERTEX_INPUTS];
-			Output output[MAX_VERTEX_OUTPUTS];
 		};
 
 		struct State : States
diff --git a/src/Pipeline/SpirvShader.hpp b/src/Pipeline/SpirvShader.hpp
index e6bc13c..d39a4c7 100644
--- a/src/Pipeline/SpirvShader.hpp
+++ b/src/Pipeline/SpirvShader.hpp
@@ -26,6 +26,7 @@
 #include <type_traits>
 #include <memory>
 #include <spirv/unified1/spirv.hpp>
+#include <Device/Config.hpp>
 
 namespace sw
 {
@@ -33,6 +34,8 @@
 	{
 	public:
 		std::unordered_map<uint32_t, std::unique_ptr<Array<Float4>>> lvalues;
+		std::unique_ptr<Array<Float4>> inputs = std::unique_ptr<Array<Float4>>(new Array<Float4>(MAX_INTERFACE_COMPONENTS));
+		std::unique_ptr<Array<Float4>> outputs = std::unique_ptr<Array<Float4>>(new Array<Float4>(MAX_INTERFACE_COMPONENTS));
 	};
 
 	class SpirvShader
diff --git a/src/Pipeline/VertexRoutine.cpp b/src/Pipeline/VertexRoutine.cpp
index e1f0b3d..5b476f7 100644
--- a/src/Pipeline/VertexRoutine.cpp
+++ b/src/Pipeline/VertexRoutine.cpp
@@ -25,9 +25,7 @@
 namespace sw
 {
 	VertexRoutine::VertexRoutine(const VertexProcessor::State &state, SpirvShader const *spirvShader)
-		: v(true),		/* TODO: indirect addressable */
-		  o(true),
-		  state(state),
+		: state(state),
 		  spirvShader(spirvShader)
 	{
 	  	spirvShader->emitEarly(&routine);
@@ -84,12 +82,23 @@
 
 	void VertexRoutine::readInput(UInt &index)
 	{
-		for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
+		for(int i = 0; i < MAX_INTERFACE_COMPONENTS; i += 4)
 		{
-			Pointer<Byte> input = *Pointer<Pointer<Byte>>(data + OFFSET(DrawData,input) + sizeof(void*) * i);
-			UInt stride = *Pointer<UInt>(data + OFFSET(DrawData,stride) + sizeof(unsigned int) * i);
+			if (spirvShader->inputs[i].Type != SpirvShader::ATTRIBTYPE_UNUSED ||
+				spirvShader->inputs[i + 1].Type != SpirvShader::ATTRIBTYPE_UNUSED ||
+				spirvShader->inputs[i + 2].Type != SpirvShader::ATTRIBTYPE_UNUSED ||
+				spirvShader->inputs[i + 3].Type != SpirvShader::ATTRIBTYPE_UNUSED)
+			{
 
-			v[i] = readStream(input, stride, state.input[i], index);
+				Pointer<Byte> input = *Pointer<Pointer<Byte>>(data + OFFSET(DrawData, input) + sizeof(void *) * i);
+				UInt stride = *Pointer<UInt>(data + OFFSET(DrawData, stride) + sizeof(unsigned int) * i);
+
+				auto value = readStream(input, stride, state.input[i], index);
+				(*routine.inputs)[i] = value.x;
+				(*routine.inputs)[i+1] = value.y;
+				(*routine.inputs)[i+2] = value.z;
+				(*routine.inputs)[i+3] = value.w;
+			}
 		}
 	}
 
@@ -601,62 +610,24 @@
 	{
 		Vector4f v;
 
-		for(int i = 0; i < MAX_VERTEX_OUTPUTS; i++)
+		for (int i = 0; i < MAX_INTERFACE_COMPONENTS; i += 4)
 		{
-			if(state.output[i].write)
+			if (spirvShader->outputs[i].Type != SpirvShader::ATTRIBTYPE_UNUSED ||
+				spirvShader->outputs[i+1].Type != SpirvShader::ATTRIBTYPE_UNUSED ||
+				spirvShader->outputs[i+2].Type != SpirvShader::ATTRIBTYPE_UNUSED ||
+				spirvShader->outputs[i+3].Type != SpirvShader::ATTRIBTYPE_UNUSED)
 			{
-				v.x = o[i].x;
-				v.y = o[i].y;
-				v.z = o[i].z;
-				v.w = o[i].w;
+				v.x = (*routine.outputs)[i];
+				v.y = (*routine.outputs)[i+1];
+				v.z = (*routine.outputs)[i+2];
+				v.w = (*routine.outputs)[i+3];
 
-				if(state.output[i].xClamp)
-				{
-					v.x = Max(v.x, Float4(0.0f));
-					v.x = Min(v.x, Float4(1.0f));
-				}
+				transpose4x4(v.x, v.y, v.z, v.w);
 
-				if(state.output[i].yClamp)
-				{
-					v.y = Max(v.y, Float4(0.0f));
-					v.y = Min(v.y, Float4(1.0f));
-				}
-
-				if(state.output[i].zClamp)
-				{
-					v.z = Max(v.z, Float4(0.0f));
-					v.z = Min(v.z, Float4(1.0f));
-				}
-
-				if(state.output[i].wClamp)
-				{
-					v.w = Max(v.w, Float4(0.0f));
-					v.w = Min(v.w, Float4(1.0f));
-				}
-
-				if(state.output[i].write == 0x01)
-				{
-					*Pointer<Float>(cacheLine + OFFSET(Vertex,v[i]) + sizeof(Vertex) * 0) = v.x.x;
-					*Pointer<Float>(cacheLine + OFFSET(Vertex,v[i]) + sizeof(Vertex) * 1) = v.x.y;
-					*Pointer<Float>(cacheLine + OFFSET(Vertex,v[i]) + sizeof(Vertex) * 2) = v.x.z;
-					*Pointer<Float>(cacheLine + OFFSET(Vertex,v[i]) + sizeof(Vertex) * 3) = v.x.w;
-				}
-				else
-				{
-					if(state.output[i].write == 0x03)
-					{
-						transpose2x4(v.x, v.y, v.z, v.w);
-					}
-					else
-					{
-						transpose4x4(v.x, v.y, v.z, v.w);
-					}
-
-					*Pointer<Float4>(cacheLine + OFFSET(Vertex,v[i]) + sizeof(Vertex) * 0, 16) = v.x;
-					*Pointer<Float4>(cacheLine + OFFSET(Vertex,v[i]) + sizeof(Vertex) * 1, 16) = v.y;
-					*Pointer<Float4>(cacheLine + OFFSET(Vertex,v[i]) + sizeof(Vertex) * 2, 16) = v.z;
-					*Pointer<Float4>(cacheLine + OFFSET(Vertex,v[i]) + sizeof(Vertex) * 3, 16) = v.w;
-				}
+				*Pointer<Float4>(cacheLine + OFFSET(Vertex,v[i]) + sizeof(Vertex) * 0, 16) = v.x;
+				*Pointer<Float4>(cacheLine + OFFSET(Vertex,v[i]) + sizeof(Vertex) * 1, 16) = v.y;
+				*Pointer<Float4>(cacheLine + OFFSET(Vertex,v[i]) + sizeof(Vertex) * 2, 16) = v.z;
+				*Pointer<Float4>(cacheLine + OFFSET(Vertex,v[i]) + sizeof(Vertex) * 3, 16) = v.w;
 			}
 		}
 
diff --git a/src/Pipeline/VertexRoutine.hpp b/src/Pipeline/VertexRoutine.hpp
index 7b73b76..943e560 100644
--- a/src/Pipeline/VertexRoutine.hpp
+++ b/src/Pipeline/VertexRoutine.hpp
@@ -48,8 +48,6 @@
 
 		Int clipFlags;
 
-		RegisterArray<MAX_VERTEX_INPUTS> v;    // Input registers
-		RegisterArray<MAX_VERTEX_OUTPUTS> o;   // Output registers
 		SpirvRoutine routine;
 
 		const VertexProcessor::State &state;