32-bit integer vertex attribute

Added 32-bit signed and unsigned vertex attribute

Change-Id: Ibbf9c035294584db71713ae7aeca36b32a8564c0
Reviewed-on: https://swiftshader-review.googlesource.com/4974
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/OpenGL/libGL/VertexDataManager.cpp b/src/OpenGL/libGL/VertexDataManager.cpp
index f0efce2..7481359 100644
--- a/src/OpenGL/libGL/VertexDataManager.cpp
+++ b/src/OpenGL/libGL/VertexDataManager.cpp
@@ -179,6 +179,8 @@
 				case GL_UNSIGNED_BYTE:  translated[i].type = sw::STREAMTYPE_BYTE;   break;

 				case GL_SHORT:          translated[i].type = sw::STREAMTYPE_SHORT;  break;

 				case GL_UNSIGNED_SHORT: translated[i].type = sw::STREAMTYPE_USHORT; break;

+				case GL_INT:            translated[i].type = sw::STREAMTYPE_INT;    break;

+				case GL_UNSIGNED_INT:   translated[i].type = sw::STREAMTYPE_UINT;   break;

 				case GL_FIXED:          translated[i].type = sw::STREAMTYPE_FIXED;  break;

 				case GL_FLOAT:          translated[i].type = sw::STREAMTYPE_FLOAT;  break;

 				default: UNREACHABLE(attribs[i].mType); translated[i].type = sw::STREAMTYPE_FLOAT;  break;

diff --git a/src/OpenGL/libGLES_CM/VertexDataManager.cpp b/src/OpenGL/libGLES_CM/VertexDataManager.cpp
index 8e44304..99e8a7f 100644
--- a/src/OpenGL/libGLES_CM/VertexDataManager.cpp
+++ b/src/OpenGL/libGLES_CM/VertexDataManager.cpp
@@ -174,6 +174,8 @@
 			case GL_UNSIGNED_BYTE:  translated[i].type = sw::STREAMTYPE_BYTE;   break;

 			case GL_SHORT:          translated[i].type = sw::STREAMTYPE_SHORT;  break;

 			case GL_UNSIGNED_SHORT: translated[i].type = sw::STREAMTYPE_USHORT; break;

+			case GL_INT:            translated[i].type = sw::STREAMTYPE_INT;    break;

+			case GL_UNSIGNED_INT:   translated[i].type = sw::STREAMTYPE_UINT;   break;

 			case GL_FIXED:          translated[i].type = sw::STREAMTYPE_FIXED;  break;

 			case GL_FLOAT:          translated[i].type = sw::STREAMTYPE_FLOAT;  break;

 			default: UNREACHABLE(attribs[i].mType); translated[i].type = sw::STREAMTYPE_FLOAT;  break;

diff --git a/src/OpenGL/libGLESv2/Context.h b/src/OpenGL/libGLESv2/Context.h
index b460d6f..5aa6f28 100644
--- a/src/OpenGL/libGLESv2/Context.h
+++ b/src/OpenGL/libGLESv2/Context.h
@@ -189,6 +189,8 @@
         case GL_UNSIGNED_BYTE:  return mSize * sizeof(GLubyte);

         case GL_SHORT:          return mSize * sizeof(GLshort);

         case GL_UNSIGNED_SHORT: return mSize * sizeof(GLushort);

+		case GL_INT:            return mSize * sizeof(GLint);

+		case GL_UNSIGNED_INT:   return mSize * sizeof(GLuint);

         case GL_FIXED:          return mSize * sizeof(GLfixed);

         case GL_FLOAT:          return mSize * sizeof(GLfloat);

         default: UNREACHABLE(mType); return mSize * sizeof(GLfloat);

diff --git a/src/OpenGL/libGLESv2/VertexDataManager.cpp b/src/OpenGL/libGLESv2/VertexDataManager.cpp
index 6e1c03c..0fb8f4e 100644
--- a/src/OpenGL/libGLESv2/VertexDataManager.cpp
+++ b/src/OpenGL/libGLESv2/VertexDataManager.cpp
@@ -187,6 +187,8 @@
 				case GL_UNSIGNED_BYTE:  translated[i].type = sw::STREAMTYPE_BYTE;   break;

 				case GL_SHORT:          translated[i].type = sw::STREAMTYPE_SHORT;  break;

 				case GL_UNSIGNED_SHORT: translated[i].type = sw::STREAMTYPE_USHORT; break;

+				case GL_INT:            translated[i].type = sw::STREAMTYPE_INT;    break;

+				case GL_UNSIGNED_INT:   translated[i].type = sw::STREAMTYPE_UINT;   break;

 				case GL_FIXED:          translated[i].type = sw::STREAMTYPE_FIXED;  break;

 				case GL_FLOAT:          translated[i].type = sw::STREAMTYPE_FLOAT;  break;

 				default: UNREACHABLE(attrib.mType); translated[i].type = sw::STREAMTYPE_FLOAT;  break;

diff --git a/src/Renderer/Stream.hpp b/src/Renderer/Stream.hpp
index 5bf9862..a3555f4 100644
--- a/src/Renderer/Stream.hpp
+++ b/src/Renderer/Stream.hpp
@@ -29,6 +29,8 @@
 		STREAMTYPE_SBYTE,
 		STREAMTYPE_SHORT,
 		STREAMTYPE_USHORT,
+		STREAMTYPE_INT,
+		STREAMTYPE_UINT,
 		STREAMTYPE_FIXED,     // Normalization ignored (16.16 format)
 		STREAMTYPE_HALF,      // Normalization ignored
 
diff --git a/src/Shader/Constants.cpp b/src/Shader/Constants.cpp
index 474842b..bd15a1f 100644
--- a/src/Shader/Constants.cpp
+++ b/src/Shader/Constants.cpp
@@ -354,12 +354,16 @@
 		static const float4 unscaleSByte = {1.0f / 0x7F, 1.0f / 0x7F, 1.0f / 0x7F, 1.0f / 0x7F};
 		static const float4 unscaleShort = {1.0f / 0x7FFF, 1.0f / 0x7FFF, 1.0f / 0x7FFF, 1.0f / 0x7FFF};
 		static const float4 unscaleUShort = {1.0f / 0xFFFF, 1.0f / 0xFFFF, 1.0f / 0xFFFF, 1.0f / 0xFFFF};
+		static const float4 unscaleInt = {1.0f / 0x7FFFFFFF, 1.0f / 0x7FFFFFFF, 1.0f / 0x7FFFFFFF, 1.0f / 0x7FFFFFFF};
+		static const float4 unscaleUInt = {1.0f / 0xFFFFFFFF, 1.0f / 0xFFFFFFFF, 1.0f / 0xFFFFFFFF, 1.0f / 0xFFFFFFFF};
 		static const float4 unscaleFixed = {1.0f / 0x00010000, 1.0f / 0x00010000, 1.0f / 0x00010000, 1.0f / 0x00010000};
 
 		memcpy(&this->unscaleByte, &unscaleByte, sizeof(unscaleByte));
 		memcpy(&this->unscaleSByte, &unscaleSByte, sizeof(unscaleSByte));
 		memcpy(&this->unscaleShort, &unscaleShort, sizeof(unscaleShort));
 		memcpy(&this->unscaleUShort, &unscaleUShort, sizeof(unscaleUShort));
+		memcpy(&this->unscaleInt, &unscaleInt, sizeof(unscaleInt));
+		memcpy(&this->unscaleUInt, &unscaleUInt, sizeof(unscaleUInt));
 		memcpy(&this->unscaleFixed, &unscaleFixed, sizeof(unscaleFixed));
 
 		for(int i = 0; i <= 0xFFFF; i++)
diff --git a/src/Shader/Constants.hpp b/src/Shader/Constants.hpp
index a7bebb4..859955c 100644
--- a/src/Shader/Constants.hpp
+++ b/src/Shader/Constants.hpp
@@ -100,6 +100,8 @@
 		float4 unscaleSByte;

 		float4 unscaleShort;

 		float4 unscaleUShort;

+		float4 unscaleInt;

+		float4 unscaleUInt;

 		float4 unscaleFixed;

 

 		float half2float[65536];

diff --git a/src/Shader/VertexRoutine.cpp b/src/Shader/VertexRoutine.cpp
index 74f1285..812bf0c 100644
--- a/src/Shader/VertexRoutine.cpp
+++ b/src/Shader/VertexRoutine.cpp
@@ -253,6 +253,60 @@
 				}
 			}
 			break;
+		case STREAMTYPE_INT:
+			{
+				if(stream.normalized)
+				{
+					v.x = Float4(*Pointer<Int4>(source0));
+					v.y = Float4(*Pointer<Int4>(source1));
+					v.z = Float4(*Pointer<Int4>(source2));
+					v.w = Float4(*Pointer<Int4>(source3));
+
+					transpose4xN(v.x, v.y, v.z, v.w, stream.count);
+
+					if(stream.count >= 1) v.x *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleInt));
+					if(stream.count >= 2) v.y *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleInt));
+					if(stream.count >= 3) v.z *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleInt));
+					if(stream.count >= 4) v.w *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleInt));
+				}
+				else
+				{
+					v.x = As<Float4>(*Pointer<Int4>(source0));
+					v.y = As<Float4>(*Pointer<Int4>(source1));
+					v.z = As<Float4>(*Pointer<Int4>(source2));
+					v.w = As<Float4>(*Pointer<Int4>(source3));
+
+					transpose4xN(v.x, v.y, v.z, v.w, stream.count);
+				}
+			}
+			break;
+		case STREAMTYPE_UINT:
+			{
+				if(stream.normalized)
+				{
+					v.x = Float4(*Pointer<UInt4>(source0));
+					v.y = Float4(*Pointer<UInt4>(source1));
+					v.z = Float4(*Pointer<UInt4>(source2));
+					v.w = Float4(*Pointer<UInt4>(source3));
+
+					transpose4xN(v.x, v.y, v.z, v.w, stream.count);
+
+					if(stream.count >= 1) v.x *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUInt));
+					if(stream.count >= 2) v.y *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUInt));
+					if(stream.count >= 3) v.z *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUInt));
+					if(stream.count >= 4) v.w *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUInt));
+				}
+				else
+				{
+					v.x = As<Float4>(*Pointer<UInt4>(source0));
+					v.y = As<Float4>(*Pointer<UInt4>(source1));
+					v.z = As<Float4>(*Pointer<UInt4>(source2));
+					v.w = As<Float4>(*Pointer<UInt4>(source3));
+
+					transpose4xN(v.x, v.y, v.z, v.w, stream.count);
+				}
+			}
+			break;
 		case STREAMTYPE_UDEC3:
 			{
 				// FIXME: Vectorize