TextureSize implementation

Initial TextureSize parsing and implementation

Change-Id: I8b9b1808366b1013a5001e2dfa15a26d8471ab6a
Reviewed-on: https://swiftshader-review.googlesource.com/3753
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/Shader/PixelProgram.cpp b/src/Shader/PixelProgram.cpp
index aca41bd..80fe7d6 100644
--- a/src/Shader/PixelProgram.cpp
+++ b/src/Shader/PixelProgram.cpp
@@ -267,6 +267,7 @@
 			case Shader::OPCODE_TEX:        TEXLD(r, d, s0, src1, project, bias);          break;
 			case Shader::OPCODE_TEXLDD:     TEXLDD(r, d, s0, src1, s2, s3, project, bias); break;
 			case Shader::OPCODE_TEXLDL:     TEXLDL(r, d, s0, src1, project, bias);         break;
+			case Shader::OPCODE_TEXSIZE:    TEXSIZE(r, d, s0.x, src1);                     break;
 			case Shader::OPCODE_TEXKILL:    TEXKILL(cMask, d, dst.mask);                   break;
 			case Shader::OPCODE_DISCARD:    DISCARD(r, cMask, instruction);                break;
 			case Shader::OPCODE_DFDX:       DFDX(d, s0);                                   break;
@@ -1020,6 +1021,18 @@
 		dst.w = tmp[(src1.swizzle >> 6) & 0x3];
 	}
 
+	void PixelProgram::TEXSIZE(Registers &r, Vector4f &dst, Float4 &lod, const Src &src1)
+	{
+		Pointer<Byte> textureMipmap = r.data + OFFSET(DrawData, mipmap) + src1.index * sizeof(Texture) + OFFSET(Texture, mipmap);
+		for(int i = 0; i < 4; ++i)
+		{
+			Pointer<Byte> mipmap = textureMipmap + (As<Int>(Extract(lod, i)) + Int(1)) * sizeof(Mipmap);
+			dst.x = Insert(dst.x, As<Float>(Int(*Pointer<Short>(mipmap + OFFSET(Mipmap, width)))), i);
+			dst.y = Insert(dst.y, As<Float>(Int(*Pointer<Short>(mipmap + OFFSET(Mipmap, height)))), i);
+			dst.z = Insert(dst.z, As<Float>(Int(*Pointer<Short>(mipmap + OFFSET(Mipmap, depth)))), i);
+		}
+	}
+
 	void PixelProgram::TEXKILL(Int cMask[4], Vector4f &src, unsigned char mask)
 	{
 		Int kill = -1;