Reimplement Direct3D GetFunction().

Copied from old Shader::GetFunction().

Bug 22533227

Change-Id: I587a4112bc97f75c010b6f572f8f4388d5af9225
Reviewed-on: https://swiftshader-review.googlesource.com/3734
Reviewed-by: Nicolas Capens <capn@google.com>
Tested-by: Nicolas Capens <capn@google.com>
diff --git a/src/D3D9/Direct3DPixelShader9.cpp b/src/D3D9/Direct3DPixelShader9.cpp
index ea86793..810c1fb 100644
--- a/src/D3D9/Direct3DPixelShader9.cpp
+++ b/src/D3D9/Direct3DPixelShader9.cpp
@@ -18,10 +18,23 @@
 {
 	Direct3DPixelShader9::Direct3DPixelShader9(Direct3DDevice9 *device, const unsigned long *shaderToken) : device(device), pixelShader(shaderToken)
 	{
+		tokenCount = 0;
+
+		while(shaderToken[tokenCount] != 0x0000FFFF)
+		{
+			tokenCount += sw::Shader::size(shaderToken[tokenCount], (unsigned short)(shaderToken[0] & 0xFFFF)) + 1;
+		}
+
+		tokenCount += 1;
+
+		this->shaderToken = new unsigned long[tokenCount];
+		memcpy(this->shaderToken, shaderToken, tokenCount * sizeof(unsigned long));
 	}
 
 	Direct3DPixelShader9::~Direct3DPixelShader9()
 	{
+		delete[] shaderToken;
+		shaderToken = 0;
 	}
 
 	long Direct3DPixelShader9::QueryInterface(const IID &iid, void **object)
@@ -86,7 +99,12 @@
 			return INVALIDCALL();
 		}
 
-		UNIMPLEMENTED();
+		if(data)
+		{
+			memcpy(data, shaderToken, tokenCount * 4);
+		}
+
+		*size = tokenCount * 4;
 
 		return D3D_OK;
 	}
diff --git a/src/D3D9/Direct3DPixelShader9.hpp b/src/D3D9/Direct3DPixelShader9.hpp
index a3f511e..312a6b7 100644
--- a/src/D3D9/Direct3DPixelShader9.hpp
+++ b/src/D3D9/Direct3DPixelShader9.hpp
@@ -45,6 +45,9 @@
 		// Creation parameters
 		Direct3DDevice9 *const device;
 
+		unsigned long *shaderToken;
+		int tokenCount;
+
 		sw::PixelShader pixelShader;
 	};
 }
diff --git a/src/D3D9/Direct3DVertexShader9.cpp b/src/D3D9/Direct3DVertexShader9.cpp
index 2c4ece7..6a1220b 100644
--- a/src/D3D9/Direct3DVertexShader9.cpp
+++ b/src/D3D9/Direct3DVertexShader9.cpp
@@ -18,10 +18,23 @@
 {
 	Direct3DVertexShader9::Direct3DVertexShader9(Direct3DDevice9 *device, const unsigned long *shaderToken) : device(device), vertexShader(shaderToken)
 	{
+		tokenCount = 0;
+
+		while(shaderToken[tokenCount] != 0x0000FFFF)
+		{
+			tokenCount += sw::Shader::size(shaderToken[tokenCount], (unsigned short)(shaderToken[0] & 0xFFFF)) + 1;
+		}
+
+		tokenCount += 1;
+
+		this->shaderToken = new unsigned long[tokenCount];
+		memcpy(this->shaderToken, shaderToken, tokenCount * sizeof(unsigned long));
 	}
 
 	Direct3DVertexShader9::~Direct3DVertexShader9()
 	{
+		delete[] shaderToken;
+		shaderToken = 0;
 	}
 
 	long Direct3DVertexShader9::QueryInterface(const IID &iid, void **object)
@@ -86,7 +99,12 @@
 			return INVALIDCALL();
 		}
 
-		UNIMPLEMENTED();
+		if(data)
+		{
+			memcpy(data, shaderToken, tokenCount * 4);
+		}
+
+		*size = tokenCount * 4;
 
 		return D3D_OK;
 	}
diff --git a/src/D3D9/Direct3DVertexShader9.hpp b/src/D3D9/Direct3DVertexShader9.hpp
index da317a4..f582810 100644
--- a/src/D3D9/Direct3DVertexShader9.hpp
+++ b/src/D3D9/Direct3DVertexShader9.hpp
@@ -45,6 +45,9 @@
 		// Creation parameters
 		Direct3DDevice9 *const device;
 
+		unsigned long *shaderToken;
+		int tokenCount;
+
 		sw::VertexShader vertexShader;
 	};
 }