Browse Source

Removed low level shader support for GL
Partially ported GL to new shader parameter system

Marko Pintera 13 years ago
parent
commit
2175dabfe5
27 changed files with 629 additions and 4677 deletions
  1. 8 3
      CamelotD3D9Renderer/Source/CmD3D9HLSLProgram.cpp
  2. 0 8
      CamelotGLRenderer/CamelotGLRenderer.vcxproj
  3. 0 27
      CamelotGLRenderer/CamelotGLRenderer.vcxproj.filters
  4. 0 41
      CamelotGLRenderer/Include/CmGLATIFSInit.h
  5. 2 34
      CamelotGLRenderer/Include/CmGLGpuProgram.h
  6. 5 0
      CamelotGLRenderer/Include/CmGLRenderSystem.h
  7. 0 104
      CamelotGLRenderer/Source/CmGLATIFSInit.cpp
  8. 71 168
      CamelotGLRenderer/Source/CmGLGpuProgram.cpp
  9. 7 103
      CamelotGLRenderer/Source/CmGLRenderSystem.cpp
  10. 16 4
      CamelotGLRenderer/Source/GLSL/include/CmGLSLExtSupport.h
  11. 7 8
      CamelotGLRenderer/Source/GLSL/include/CmGLSLGpuProgram.h
  12. 7 3
      CamelotGLRenderer/Source/GLSL/include/CmGLSLLinkProgram.h
  13. 42 52
      CamelotGLRenderer/Source/GLSL/include/CmGLSLLinkProgramManager.h
  14. 0 16
      CamelotGLRenderer/Source/GLSL/include/CmGLSLProgram.h
  15. 40 12
      CamelotGLRenderer/Source/GLSL/src/CmGLSLExtSupport.cpp
  16. 48 27
      CamelotGLRenderer/Source/GLSL/src/CmGLSLGpuProgram.cpp
  17. 50 59
      CamelotGLRenderer/Source/GLSL/src/CmGLSLLinkProgram.cpp
  18. 279 378
      CamelotGLRenderer/Source/GLSL/src/CmGLSLLinkProgramManager.cpp
  19. 33 191
      CamelotGLRenderer/Source/GLSL/src/CmGLSLProgram.cpp
  20. 0 71
      CamelotGLRenderer/Source/atifs/include/ATI_FS_GLGpuProgram.h
  21. 0 280
      CamelotGLRenderer/Source/atifs/include/Compiler2Pass.h
  22. 0 367
      CamelotGLRenderer/Source/atifs/include/ps_1_4.h
  23. 0 137
      CamelotGLRenderer/Source/atifs/src/ATI_FS_GLGpuProgram.cpp
  24. 0 379
      CamelotGLRenderer/Source/atifs/src/Compiler2Pass.cpp
  25. 0 2149
      CamelotGLRenderer/Source/atifs/src/ps_1_4.cpp
  26. 14 55
      CamelotRenderer/TODO.txt
  27. 0 1
      CamelotUtility/Include/CmException.h

+ 8 - 3
CamelotD3D9Renderer/Source/CmD3D9HLSLProgram.cpp

@@ -111,7 +111,7 @@ namespace CamelotEngine {
 			CM_EXCEPT(InternalErrorException, "Cannot retrieve constant descriptions from HLSL program.");
 		
 		// DX9 has no concept of parameter blocks so we just put all members in one global block
-		String name = "Globals";
+		String name = "CM_INTERNAL_Globals";
 		mParamDesc.paramBlocks.insert(std::make_pair(name, GpuParamBlockDesc()));
 		GpuParamBlockDesc& blockDesc = mParamDesc.paramBlocks[name];
 		blockDesc.name = name;
@@ -181,8 +181,7 @@ namespace CamelotEngine {
 
 				blockDesc.blockSize += memberDesc.elementSize * memberDesc.arraySize;
 			}
-
-			if(desc.Type == D3DXPT_SAMPLER1D || desc.Type == D3DXPT_SAMPLER2D || desc.Type == D3DXPT_SAMPLER3D || desc.Type == D3DXPT_SAMPLERCUBE)
+			else if(desc.Type == D3DXPT_SAMPLER1D || desc.Type == D3DXPT_SAMPLER2D || desc.Type == D3DXPT_SAMPLER3D || desc.Type == D3DXPT_SAMPLERCUBE)
 			{
 				GpuParamSpecialDesc samplerDesc;
 				samplerDesc.name = paramName;
@@ -210,11 +209,17 @@ namespace CamelotEngine {
 					samplerDesc.type = GST_SAMPLERCUBE;
 					textureDesc.type = GST_TEXTURECUBE;
 					break;
+				default:
+					CM_EXCEPT(InternalErrorException, "Invalid sampler type: " + toString(desc.Type) + " for parameter " + paramName);
 				}
 
 				mParamDesc.samplers.insert(std::make_pair(paramName, samplerDesc));
 				mParamDesc.textures.insert(std::make_pair(paramName, textureDesc));
 			}
+			else
+			{
+				CM_EXCEPT(InternalErrorException, "Invalid shader parameter type: " + toString(desc.Type) + " for parameter " + paramName);
+			}
 		}
 	}
 

+ 0 - 8
CamelotGLRenderer/CamelotGLRenderer.vcxproj

@@ -147,7 +147,6 @@
     </Link>
   </ItemDefinitionGroup>
   <ItemGroup>
-    <ClInclude Include="Include\CmGLATIFSInit.h" />
     <ClInclude Include="Include\CmGLContext.h" />
     <ClInclude Include="Include\CmGLDefaultHardwareBufferManager.h" />
     <ClInclude Include="Include\CmGLDepthStencilBuffer.h" />
@@ -174,9 +173,6 @@
     <ClInclude Include="Include\CmWin32GLSupport.h" />
     <ClInclude Include="Include\CmWin32Prerequisites.h" />
     <ClInclude Include="Include\CmWin32Window.h" />
-    <ClInclude Include="Source\atifs\include\ATI_FS_GLGpuProgram.h" />
-    <ClInclude Include="Source\atifs\include\Compiler2Pass.h" />
-    <ClInclude Include="Source\atifs\include\ps_1_4.h" />
     <ClInclude Include="Source\GLSL\include\CmGLSLExtSupport.h" />
     <ClInclude Include="Source\GLSL\include\CmGLSLGpuProgram.h" />
     <ClInclude Include="Source\GLSL\include\CmGLSLLinkProgram.h" />
@@ -188,10 +184,6 @@
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="CmGLPlugin.cpp" />
-    <ClCompile Include="Source\atifs\src\ATI_FS_GLGpuProgram.cpp" />
-    <ClCompile Include="Source\atifs\src\Compiler2Pass.cpp" />
-    <ClCompile Include="Source\atifs\src\ps_1_4.cpp" />
-    <ClCompile Include="Source\CmGLATIFSInit.cpp" />
     <ClCompile Include="Source\CmGLContext.cpp" />
     <ClCompile Include="Source\CmGLDefaultHardwareBufferManager.cpp" />
     <ClCompile Include="Source\CmGLDepthStencilBuffer.cpp" />

+ 0 - 27
CamelotGLRenderer/CamelotGLRenderer.vcxproj.filters

@@ -13,9 +13,6 @@
       <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
       <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
     </Filter>
-    <Filter Include="ATIFS">
-      <UniqueIdentifier>{2c02e8a0-bcb2-415a-8740-10cb94cfbb80}</UniqueIdentifier>
-    </Filter>
     <Filter Include="GLSL">
       <UniqueIdentifier>{23f5e949-4542-49d4-86f9-d24656b5de08}</UniqueIdentifier>
     </Filter>
@@ -27,9 +24,6 @@
     </Filter>
   </ItemGroup>
   <ItemGroup>
-    <ClInclude Include="Include\CmGLATIFSInit.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
     <ClInclude Include="Include\CmGLContext.h">
       <Filter>Header Files</Filter>
     </ClInclude>
@@ -96,15 +90,6 @@
     <ClInclude Include="Include\CmWin32Window.h">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="Source\atifs\include\ATI_FS_GLGpuProgram.h">
-      <Filter>ATIFS</Filter>
-    </ClInclude>
-    <ClInclude Include="Source\atifs\include\Compiler2Pass.h">
-      <Filter>ATIFS</Filter>
-    </ClInclude>
-    <ClInclude Include="Source\atifs\include\ps_1_4.h">
-      <Filter>ATIFS</Filter>
-    </ClInclude>
     <ClInclude Include="Source\GLSL\include\CmGLSLExtSupport.h">
       <Filter>GLSL</Filter>
     </ClInclude>
@@ -143,15 +128,6 @@
     </ClInclude>
   </ItemGroup>
   <ItemGroup>
-    <ClCompile Include="Source\atifs\src\ATI_FS_GLGpuProgram.cpp">
-      <Filter>ATIFS</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\atifs\src\Compiler2Pass.cpp">
-      <Filter>ATIFS</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\atifs\src\ps_1_4.cpp">
-      <Filter>ATIFS</Filter>
-    </ClCompile>
     <ClCompile Include="Source\GLSL\src\CmGLSLExtSupport.cpp">
       <Filter>GLSL</Filter>
     </ClCompile>
@@ -176,9 +152,6 @@
     <ClCompile Include="Source\win32\CmWin32Context.cpp">
       <Filter>Win32</Filter>
     </ClCompile>
-    <ClCompile Include="Source\CmGLATIFSInit.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
     <ClCompile Include="Source\CmGLContext.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>

+ 0 - 41
CamelotGLRenderer/Include/CmGLATIFSInit.h

@@ -1,41 +0,0 @@
-/*
-	ATI fragment shader Extension header file.
-	setup by NFZ
-	extracted from ATI 8500 SDK
-
-** GL_ATI_fragment_shader
-**
-** Support:
-**   Rage 128 * based  : Not Supported
-**   Radeon   * based  : Not Supported
-**   R200     * based  : Supported
-**   R200 : 8500, 9000, 9100, 9200
-**   also works on R300 but pointless since ARBFP1.0 supported
-*/
-
-
-#ifndef _GL_ATI_FRAGMENT_SHADER_H_
-#define _GL_ATI_FRAGMENT_SHADER_H_
-
-#include "CmGLSupport.h"
-
-// ATI_fragment_program functions
-extern PFNGLGENFRAGMENTSHADERSATIPROC        glGenFragmentShadersATI_ptr;
-extern PFNGLBINDFRAGMENTSHADERATIPROC        glBindFragmentShaderATI_ptr;
-extern PFNGLDELETEFRAGMENTSHADERATIPROC      glDeleteFragmentShaderATI_ptr;
-extern PFNGLBEGINFRAGMENTSHADERATIPROC       glBeginFragmentShaderATI_ptr;
-extern PFNGLENDFRAGMENTSHADERATIPROC         glEndFragmentShaderATI_ptr;
-extern PFNGLPASSTEXCOORDATIPROC              glPassTexCoordATI_ptr;
-extern PFNGLSAMPLEMAPATIPROC                 glSampleMapATI_ptr;
-extern PFNGLCOLORFRAGMENTOP1ATIPROC          glColorFragmentOp1ATI_ptr;
-extern PFNGLCOLORFRAGMENTOP2ATIPROC          glColorFragmentOp2ATI_ptr;
-extern PFNGLCOLORFRAGMENTOP3ATIPROC          glColorFragmentOp3ATI_ptr;
-extern PFNGLALPHAFRAGMENTOP1ATIPROC          glAlphaFragmentOp1ATI_ptr;
-extern PFNGLALPHAFRAGMENTOP2ATIPROC          glAlphaFragmentOp2ATI_ptr;
-extern PFNGLALPHAFRAGMENTOP3ATIPROC          glAlphaFragmentOp3ATI_ptr;
-extern PFNGLSETFRAGMENTSHADERCONSTANTATIPROC glSetFragmentShaderConstantATI_ptr;
-
-bool InitATIFragmentShaderExtensions(CamelotEngine::GLSupport& glSupport);
-
-#endif	//_GL_ATI_FRAGMENT_SHADER_H_
-

+ 2 - 34
CamelotGLRenderer/Include/CmGLGpuProgram.h

@@ -50,7 +50,7 @@ namespace CamelotEngine {
 		virtual void bindProgramParameters(GpuProgramParametersSharedPtr params, UINT16 mask) {}
 
         /// Get the assigned GL program id
-        const GLuint getProgramID(void) const
+        const UINT32 getProgramID(void) const
         { return mProgramID; }
 
 		/** Get the attribute index for a given semantic. 
@@ -75,41 +75,9 @@ namespace CamelotEngine {
         /// @copydoc Resource::unloadImpl
         void unloadImpl(void) {}
 
-        GLuint mProgramID;
+        UINT32 mProgramID;
         GLenum mProgramType;
     };
-
-    /** Specialisation of the GL low-level program for ARB programs. */
-    class CM_RSGL_EXPORT GLArbGpuProgram : public GLGpuProgram
-    {
-    public:
-        virtual ~GLArbGpuProgram();
-
-        /// Execute the binding functions for this program
-        void bindProgram(void);
-        /// Execute the unbinding functions for this program
-        void unbindProgram(void);
-        /// Execute the param binding functions for this program
-		void bindProgramParameters(GpuProgramParametersSharedPtr params, UINT16 mask);
-
-        /// Get the GL type for the program
-        const GLuint getProgramType(void) const
-        { return mProgramType; }
-
-    protected:
-		friend GpuProgram* createGLArbGpuProgram(const String& source, const String& entryPoint, const String& language, GpuProgramType gptype, GpuProgramProfile profile);
-
-		GLArbGpuProgram(const String& source, const String& entryPoint, const String& language, 
-			GpuProgramType gptype, GpuProgramProfile profile, bool isAdjacencyInfoRequired = false);
-
-        void loadFromSource(void);
-        /// @copydoc Resource::unloadImpl
-        void unloadImpl(void);
-
-    };
-
-
-
 }; // namespace CamelotEngine
 
 #endif // __GLGpuProgram_H__

+ 5 - 0
CamelotGLRenderer/Include/CmGLRenderSystem.h

@@ -120,6 +120,11 @@ namespace CamelotEngine {
 		 * @copydoc RenderSystem::bindGpuProgramParameters()
 		 */
 		void bindGpuProgramParameters(GpuProgramType gptype, GpuProgramParametersSharedPtr params, UINT16 mask);
+		
+		/**
+		 * @copydoc RenderSystem::bindGpuParams()
+		 */
+		void bindGpuParams(GpuProgramType gptype, GpuParamsPtr params);
 
 		/**
 		 * @copydoc RenderSystem::beginFrame()

+ 0 - 104
CamelotGLRenderer/Source/CmGLATIFSInit.cpp

@@ -1,104 +0,0 @@
-/*
-	ATI fragment shader Extension program file.
-	setup by NFZ
-	extracted from ATI 8500 SDK
-
-** GL_ATI_fragment_shader
-**
-** Support:
-**   Rage 128 * based  : Not Supported
-**   Radeon   * based  : Not Supported
-**   R200     * based  : Supported
-**   R200 : 8500, 9000, 9100, 9200
-**   also works on R300 but pointless since ARBFP1.0 supported
-*/
-
-#include "CmGLATIFSInit.h"
-#include "CmGLPrerequisites.h"
-
-// ATI_fragment_program functions
-PFNGLGENFRAGMENTSHADERSATIPROC        glGenFragmentShadersATI_ptr=NULL;
-PFNGLBINDFRAGMENTSHADERATIPROC        glBindFragmentShaderATI_ptr=NULL;
-PFNGLDELETEFRAGMENTSHADERATIPROC      glDeleteFragmentShaderATI_ptr=NULL;
-PFNGLBEGINFRAGMENTSHADERATIPROC       glBeginFragmentShaderATI_ptr=NULL;
-PFNGLENDFRAGMENTSHADERATIPROC         glEndFragmentShaderATI_ptr=NULL;
-PFNGLPASSTEXCOORDATIPROC              glPassTexCoordATI_ptr=NULL;
-PFNGLSAMPLEMAPATIPROC                 glSampleMapATI_ptr=NULL;
-PFNGLCOLORFRAGMENTOP1ATIPROC          glColorFragmentOp1ATI_ptr=NULL;
-PFNGLCOLORFRAGMENTOP2ATIPROC          glColorFragmentOp2ATI_ptr=NULL;
-PFNGLCOLORFRAGMENTOP3ATIPROC          glColorFragmentOp3ATI_ptr=NULL;
-PFNGLALPHAFRAGMENTOP1ATIPROC          glAlphaFragmentOp1ATI_ptr=NULL;
-PFNGLALPHAFRAGMENTOP2ATIPROC          glAlphaFragmentOp2ATI_ptr=NULL;
-PFNGLALPHAFRAGMENTOP3ATIPROC          glAlphaFragmentOp3ATI_ptr=NULL;
-PFNGLSETFRAGMENTSHADERCONSTANTATIPROC glSetFragmentShaderConstantATI_ptr=NULL;
-
-bool InitATIFragmentShaderExtensions(CamelotEngine::GLSupport& glSupport)
-{
-    static bool init = false;
-    //char *extList;
-
-    if(init) return init;
-
-	
-	/* confirm that the version of OpenGL supports ATI fragment shader */
-	/* done in GLRenderSystem
-    extList = (char *)glGetString(GL_EXTENSIONS);
-
-    if (strstr(extList, "GL_ATI_fragment_shader") == NULL)  {
-		//MessageBox(NULL, "GL_ATI_fragment_shader extension not supported", "GL Extension error", MB_OK);
-		// ** should raise exception
-		init = false;
-		return false;
-    }
-
-	*/
-
-
-	glGenFragmentShadersATI_ptr    = (PFNGLGENFRAGMENTSHADERSATIPROC) glSupport.getProcAddress("glGenFragmentShadersATI");
-	glBindFragmentShaderATI_ptr    = (PFNGLBINDFRAGMENTSHADERATIPROC) glSupport.getProcAddress("glBindFragmentShaderATI");
-	glDeleteFragmentShaderATI_ptr  = (PFNGLDELETEFRAGMENTSHADERATIPROC) glSupport.getProcAddress("glDeleteFragmentShaderATI");
-	glBeginFragmentShaderATI_ptr   = (PFNGLBEGINFRAGMENTSHADERATIPROC) glSupport.getProcAddress("glBeginFragmentShaderATI");
-	glEndFragmentShaderATI_ptr     = (PFNGLENDFRAGMENTSHADERATIPROC) glSupport.getProcAddress("glEndFragmentShaderATI");
-	glPassTexCoordATI_ptr          = (PFNGLPASSTEXCOORDATIPROC) glSupport.getProcAddress("glPassTexCoordATI");
-	glSampleMapATI_ptr             = (PFNGLSAMPLEMAPATIPROC) glSupport.getProcAddress("glSampleMapATI");
-	glColorFragmentOp1ATI_ptr      = (PFNGLCOLORFRAGMENTOP1ATIPROC) glSupport.getProcAddress("glColorFragmentOp1ATI");
-	glColorFragmentOp2ATI_ptr      = (PFNGLCOLORFRAGMENTOP2ATIPROC) glSupport.getProcAddress("glColorFragmentOp2ATI");
-	glColorFragmentOp3ATI_ptr      = (PFNGLCOLORFRAGMENTOP3ATIPROC) glSupport.getProcAddress("glColorFragmentOp3ATI");
-	glAlphaFragmentOp1ATI_ptr      = (PFNGLALPHAFRAGMENTOP1ATIPROC) glSupport.getProcAddress("glAlphaFragmentOp1ATI");
-	glAlphaFragmentOp2ATI_ptr      = (PFNGLALPHAFRAGMENTOP2ATIPROC) glSupport.getProcAddress("glAlphaFragmentOp2ATI");
-	glAlphaFragmentOp3ATI_ptr      = (PFNGLALPHAFRAGMENTOP3ATIPROC) glSupport.getProcAddress("glAlphaFragmentOp3ATI");
-	glSetFragmentShaderConstantATI_ptr = (PFNGLSETFRAGMENTSHADERCONSTANTATIPROC) glSupport.getProcAddress("glSetFragmentShaderConstantATI");
-
-	if (glGenFragmentShadersATI_ptr == NULL) return false;
-
-	if (glBindFragmentShaderATI_ptr == NULL) return false;
-
-	if (glDeleteFragmentShaderATI_ptr == NULL) return false;
-
-	if (glBeginFragmentShaderATI_ptr == NULL) return false;
-
-	if (glEndFragmentShaderATI_ptr == NULL) return false;
-
-	if (glPassTexCoordATI_ptr == NULL) return false;
-
-	if (glColorFragmentOp1ATI_ptr == NULL) return false;
-
-	if (glColorFragmentOp2ATI_ptr == NULL) return false;
-
-	if (glColorFragmentOp3ATI_ptr == NULL) return false;
-
-	if (glAlphaFragmentOp1ATI_ptr == NULL) return false;
-
-	if (glAlphaFragmentOp2ATI_ptr == NULL) return false;
-
-	if (glAlphaFragmentOp2ATI_ptr == NULL) return false;
-
-	if (glAlphaFragmentOp3ATI_ptr == NULL) return false;
-
-	if (glSetFragmentShaderConstantATI_ptr == NULL) return false;
-
-    init = true;
-
-	return true;
-}
-

+ 71 - 168
CamelotGLRenderer/Source/CmGLGpuProgram.cpp

@@ -29,191 +29,94 @@ THE SOFTWARE.
 #include "CmGLGpuProgram.h"
 #include "CmException.h"
 
-using namespace CamelotEngine;
-
-GLenum getGLShaderType(GpuProgramType programType)
+namespace CamelotEngine
 {
-	switch (programType)
+	GLGpuProgram::GLGpuProgram(const String& source, const String& entryPoint, const String& language, 
+							   GpuProgramType gptype, GpuProgramProfile profile, bool isAdjacencyInfoRequired) 
+		: GpuProgram(source, entryPoint, language, gptype, profile, isAdjacencyInfoRequired)
 	{
-		case GPT_VERTEX_PROGRAM:
-		default:
-			return GL_VERTEX_PROGRAM_ARB;
-		case GPT_GEOMETRY_PROGRAM:
-			return GL_GEOMETRY_PROGRAM_NV;
-		case GPT_FRAGMENT_PROGRAM:
-			return GL_FRAGMENT_PROGRAM_ARB;
-	}
-}
 
-GLGpuProgram::GLGpuProgram(const String& source, const String& entryPoint, const String& language, 
-						   GpuProgramType gptype, GpuProgramProfile profile, bool isAdjacencyInfoRequired) 
-    : GpuProgram(source, entryPoint, language, gptype, profile, isAdjacencyInfoRequired)
-{
-    //if (createParamDictionary("GLGpuProgram"))
-    //{
-    //    setupBaseParamDictionary();
-    //}
-}
-
-GLGpuProgram::~GLGpuProgram()
-{
-    // have to call this here reather than in Resource destructor
-    // since calling virtual methods in base destructors causes crash
-    unload_internal(); 
-}
-
-GLuint GLGpuProgram::getAttributeIndex(VertexElementSemantic semantic, CamelotEngine::UINT32 index)
-{
-	return getFixedAttributeIndex(semantic, index);
-}
-
-GLuint GLGpuProgram::getFixedAttributeIndex(VertexElementSemantic semantic, CamelotEngine::UINT32 index)
-{
-	// Some drivers (e.g. OS X on nvidia) incorrectly determine the attribute binding automatically
-	// and end up aliasing existing built-ins. So avoid! Fixed builtins are: 
+	}
 
-	//  a  builtin				custom attrib name
-	// ----------------------------------------------
-	//	0  gl_Vertex			vertex
-	//  1  n/a					blendWeights		
-	//	2  gl_Normal			normal
-	//	3  gl_Color				colour
-	//	4  gl_SecondaryColor	secondary_colour
-	//	5  gl_FogCoord			fog_coord
-	//  7  n/a					blendIndices
-	//	8  gl_MultiTexCoord0	uv0
-	//	9  gl_MultiTexCoord1	uv1
-	//	10 gl_MultiTexCoord2	uv2
-	//	11 gl_MultiTexCoord3	uv3
-	//	12 gl_MultiTexCoord4	uv4
-	//	13 gl_MultiTexCoord5	uv5
-	//	14 gl_MultiTexCoord6	uv6, tangent
-	//	15 gl_MultiTexCoord7	uv7, binormal
-	switch(semantic)
+	GLGpuProgram::~GLGpuProgram()
 	{
-	case VES_POSITION:
-		return 0;
-	case VES_BLEND_WEIGHTS:
-		return 1;
-	case VES_NORMAL:
-		return 2;
-	case VES_DIFFUSE:
-		return 3;
-	case VES_SPECULAR:
-		return 4;
-	case VES_BLEND_INDICES:
-		return 7;
-	case VES_TEXTURE_COORDINATES:
-		return 8 + index;
-	case VES_TANGENT:
-		return 14;
-	case VES_BITANGENT:
-		return 15;
-	default:
-		assert(false && "Missing attribute!");
-		return 0;
-	};
+		// have to call this here reather than in Resource destructor
+		// since calling virtual methods in base destructors causes crash
+		unload_internal(); 
+	}
 
-}
+	GLuint GLGpuProgram::getAttributeIndex(VertexElementSemantic semantic, CamelotEngine::UINT32 index)
+	{
+		return getFixedAttributeIndex(semantic, index);
+	}
 
-bool GLGpuProgram::isAttributeValid(VertexElementSemantic semantic, CamelotEngine::UINT32 index)
-{
-	// default implementation
-	switch(semantic)
+	GLuint GLGpuProgram::getFixedAttributeIndex(VertexElementSemantic semantic, CamelotEngine::UINT32 index)
 	{
+		// Some drivers (e.g. OS X on nvidia) incorrectly determine the attribute binding automatically
+		// and end up aliasing existing built-ins. So avoid! Fixed builtins are: 
+
+		//  a  builtin				custom attrib name
+		// ----------------------------------------------
+		//	0  gl_Vertex			vertex
+		//  1  n/a					blendWeights		
+		//	2  gl_Normal			normal
+		//	3  gl_Color				colour
+		//	4  gl_SecondaryColor	secondary_colour
+		//	5  gl_FogCoord			fog_coord
+		//  7  n/a					blendIndices
+		//	8  gl_MultiTexCoord0	uv0
+		//	9  gl_MultiTexCoord1	uv1
+		//	10 gl_MultiTexCoord2	uv2
+		//	11 gl_MultiTexCoord3	uv3
+		//	12 gl_MultiTexCoord4	uv4
+		//	13 gl_MultiTexCoord5	uv5
+		//	14 gl_MultiTexCoord6	uv6, tangent
+		//	15 gl_MultiTexCoord7	uv7, binormal
+		switch(semantic)
+		{
 		case VES_POSITION:
+			return 0;
+		case VES_BLEND_WEIGHTS:
+			return 1;
 		case VES_NORMAL:
+			return 2;
 		case VES_DIFFUSE:
+			return 3;
 		case VES_SPECULAR:
-		case VES_TEXTURE_COORDINATES:
-			return false;
-		case VES_BLEND_WEIGHTS:
+			return 4;
 		case VES_BLEND_INDICES:
-		case VES_BITANGENT:
+			return 7;
+		case VES_TEXTURE_COORDINATES:
+			return 8 + index;
 		case VES_TANGENT:
-			return true; // with default binding
-	}
-
-    return false;
-}
-
-GLArbGpuProgram::GLArbGpuProgram(const String& source, const String& entryPoint, const String& language, 
-								 GpuProgramType gptype, GpuProgramProfile profile, bool isAdjacencyInfoRequired) 
-	: GLGpuProgram(source, entryPoint, language, gptype, profile, isAdjacencyInfoRequired)
-{
-    glGenProgramsARB(1, &mProgramID);
-	mProgramType = getGLShaderType(gptype);
-}
-
-GLArbGpuProgram::~GLArbGpuProgram()
-{
-    // have to call this here reather than in Resource destructor
-    // since calling virtual methods in base destructors causes crash
-    unload_internal(); 
-}
-
-void GLArbGpuProgram::bindProgram(void)
-{
-    glEnable(mProgramType);
-    glBindProgramARB(mProgramType, mProgramID);
-}
-
-void GLArbGpuProgram::unbindProgram(void)
-{
-    glBindProgramARB(mProgramType, 0);
-    glDisable(mProgramType);
-}
+			return 14;
+		case VES_BITANGENT:
+			return 15;
+		default:
+			assert(false && "Missing attribute!");
+			return 0;
+		};
 
-void GLArbGpuProgram::bindProgramParameters(GpuProgramParametersSharedPtr params, CamelotEngine::UINT16 mask)
-{
-    GLenum type = getGLShaderType(mType);
-    
-	// only supports float constants
-	GpuLogicalBufferStructPtr floatStruct = params->getFloatLogicalBufferStruct();
+	}
 
-	for (GpuLogicalIndexUseMap::const_iterator i = floatStruct->map.begin();
-		i != floatStruct->map.end(); ++i)
+	bool GLGpuProgram::isAttributeValid(VertexElementSemantic semantic, CamelotEngine::UINT32 index)
 	{
-		if (i->second.variability & mask)
+		// default implementation
+		switch(semantic)
 		{
-			UINT32 logicalIndex = i->first;
-			const float* pFloat = params->getFloatPointer(i->second.physicalIndex);
-			// Iterate over the params, set in 4-float chunks (low-level)
-			for (UINT32 j = 0; j < i->second.currentSize; j+=4)
-			{
-				glProgramLocalParameter4fvARB(type, logicalIndex, pFloat);
-				pFloat += 4;
-				++logicalIndex;
-			}
+			case VES_POSITION:
+			case VES_NORMAL:
+			case VES_DIFFUSE:
+			case VES_SPECULAR:
+			case VES_TEXTURE_COORDINATES:
+				return false;
+			case VES_BLEND_WEIGHTS:
+			case VES_BLEND_INDICES:
+			case VES_BITANGENT:
+			case VES_TANGENT:
+				return true; // with default binding
 		}
-	}
-}
-
-void GLArbGpuProgram::unloadImpl(void)
-{
-    glDeleteProgramsARB(1, &mProgramID);
-}
-
-void GLArbGpuProgram::loadFromSource(void)
-{
-    if (GL_INVALID_OPERATION == glGetError()) {
-		// TODO LOG PORT LOG - Log this somewhere
-        //LogManager::getSingleton().logMessage("Invalid Operation before loading program "+mName);
-
-    }
-    glBindProgramARB(mProgramType, mProgramID);
-    glProgramStringARB(mProgramType, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)mSource.length(), mSource.c_str());
-
-    if (GL_INVALID_OPERATION == glGetError())
-    {
-        GLint errPos;
-        glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errPos);
-		String errPosStr = toString(errPos);
-        char* errStr = (char*)glGetString(GL_PROGRAM_ERROR_STRING_ARB);
-        // XXX New exception code?
-		CM_EXCEPT(InternalErrorException, 
-            "Cannot load GL vertex program.  Line " + errPosStr + ":\n" + errStr);
-    }
-    glBindProgramARB(mProgramType, 0);
-}
 
+		return false;
+	}
+}

+ 7 - 103
CamelotGLRenderer/Source/CmGLRenderSystem.cpp

@@ -36,7 +36,6 @@ THE SOFTWARE.s
 #include "CmGLDefaultHardwareBufferManager.h"
 #include "CmGLUtil.h"
 #include "CmGLGpuProgram.h"
-#include "ATI_FS_GLGpuProgram.h"
 #include "CmGLGpuProgramManager.h"
 #include "CmException.h"
 #include "CmGLSLExtSupport.h"
@@ -62,23 +61,8 @@ THE SOFTWARE.s
 GLenum glewContextInit (CamelotEngine::GLSupport *glSupport);
 #endif
 
-namespace CamelotEngine {
-
-	// Callback function used when registering GLGpuPrograms
-	GpuProgram* createGLArbGpuProgram(const String& source, const String& entryPoint, const String& language, GpuProgramType gptype, GpuProgramProfile profile)
-	{
-		GLArbGpuProgram* ret = new GLArbGpuProgram(source, entryPoint, language, gptype, profile);
-
-		return ret;
-	}
-
-	GpuProgram* createGL_ATI_FS_GpuProgram(const String& source, const String& entryPoint, const String& language, GpuProgramType gptype, GpuProgramProfile profile)
-	{
-		ATI_FS_GLGpuProgram* ret = new ATI_FS_GLGpuProgram(source, entryPoint, language, gptype, profile);
-
-		return ret;
-	}
-
+namespace CamelotEngine 
+{
 	/************************************************************************/
 	/* 								PUBLIC INTERFACE                   		*/
 	/************************************************************************/
@@ -340,6 +324,11 @@ namespace CamelotEngine {
 		}
 	}
 	//-----------------------------------------------------------------------------
+	void GLRenderSystem::bindGpuParams(GpuProgramType gptype, GpuParamsPtr params)
+	{
+		// TODO - Not implemented
+	}
+	//-----------------------------------------------------------------------------
 	void GLRenderSystem::setTexture(UINT16 stage, bool enabled, const TexturePtr &texPtr)
 	{
 		THROW_IF_NOT_RENDER_THREAD;
@@ -1836,91 +1825,6 @@ namespace CamelotEngine {
 
 		// GPU Program Manager setup
 		GpuProgramManager::startUp(new GLGpuProgramManager());
-		GLGpuProgramManager* gpuProgramManager = static_cast<GLGpuProgramManager*>(GpuProgramManager::instancePtr());
-
-		if(caps->hasCapability(RSC_VERTEX_PROGRAM))
-		{
-			if(caps->isShaderProfileSupported("arbvp1"))
-			{
-				gpuProgramManager->registerProgramFactory("arbvp1", createGLArbGpuProgram);
-			}
-
-			if(caps->isShaderProfileSupported("vp30"))
-			{
-				gpuProgramManager->registerProgramFactory("vp30", createGLArbGpuProgram);
-			}
-
-			if(caps->isShaderProfileSupported("vp40"))
-			{
-				gpuProgramManager->registerProgramFactory("vp40", createGLArbGpuProgram);
-			}
-
-			if(caps->isShaderProfileSupported("gp4vp"))
-			{
-				gpuProgramManager->registerProgramFactory("gp4vp", createGLArbGpuProgram);
-			}
-
-			if(caps->isShaderProfileSupported("gpu_vp"))
-			{
-				gpuProgramManager->registerProgramFactory("gpu_vp", createGLArbGpuProgram);
-			}
-		}
-
-		if(caps->hasCapability(RSC_GEOMETRY_PROGRAM))
-		{
-			//TODO : Should these be createGLArbGpuProgram or createGLGpuNVparseProgram?
-			if(caps->isShaderProfileSupported("nvgp4"))
-			{
-				gpuProgramManager->registerProgramFactory("nvgp4", createGLArbGpuProgram);
-			}
-			if(caps->isShaderProfileSupported("gp4gp"))
-			{
-				gpuProgramManager->registerProgramFactory("gp4gp", createGLArbGpuProgram);
-			}
-			if(caps->isShaderProfileSupported("gpu_gp"))
-			{
-				gpuProgramManager->registerProgramFactory("gpu_gp", createGLArbGpuProgram);
-			}
-		}
-
-		if(caps->hasCapability(RSC_FRAGMENT_PROGRAM))
-		{
-			if(caps->isShaderProfileSupported("ps_1_4"))
-			{
-				gpuProgramManager->registerProgramFactory("ps_1_4", createGL_ATI_FS_GpuProgram);
-			}
-
-			if(caps->isShaderProfileSupported("ps_1_3"))
-			{
-				gpuProgramManager->registerProgramFactory("ps_1_3", createGL_ATI_FS_GpuProgram);
-			}
-
-			if(caps->isShaderProfileSupported("ps_1_2"))
-			{
-				gpuProgramManager->registerProgramFactory("ps_1_2", createGL_ATI_FS_GpuProgram);
-			}
-
-			if(caps->isShaderProfileSupported("ps_1_1"))
-			{
-				gpuProgramManager->registerProgramFactory("ps_1_1", createGL_ATI_FS_GpuProgram);
-			}
-
-			if(caps->isShaderProfileSupported("arbfp1"))
-			{
-				gpuProgramManager->registerProgramFactory("arbfp1", createGLArbGpuProgram);
-			}
-
-			if(caps->isShaderProfileSupported("fp40"))
-			{
-				gpuProgramManager->registerProgramFactory("fp40", createGLArbGpuProgram);
-			}
-
-			if(caps->isShaderProfileSupported("fp30"))
-			{
-				gpuProgramManager->registerProgramFactory("fp30", createGLArbGpuProgram);
-			}
-
-		}
 
 		if(caps->isShaderProfileSupported("glsl"))
 		{

+ 16 - 4
CamelotGLRenderer/Source/GLSL/include/CmGLSLExtSupport.h

@@ -38,6 +38,11 @@ THE SOFTWARE.
 //
 namespace CamelotEngine
 {
+	enum GLSLObjectType
+	{
+		GLSLOT_SHADER,
+		GLSLOT_PROGRAM
+	};
 
 	// forward declarations
 	class GLSLProgram;
@@ -52,13 +57,20 @@ namespace CamelotEngine
 	@param forceInfoLog if true then message from GL info log is obtained
 	@param forceException if true then exception is generated if a GL error found
 	*/
-    void checkForGLSLError(const String& ogreMethod, const String& errorTextPrefix, const GLhandleARB obj, const bool forceInfoLog = false, const bool forceException = false);
+    void checkForGLSLError(const String& ogreMethod, const String& errorTextPrefix, const GLuint obj, GLSLObjectType objectType, 
+		const bool forceInfoLog = false, const bool forceException = false);
 
-	/** if there is a message in GL info log then post it in the Ogre Log
+	/** if there is a message in GL info log then post it in the engine Log
 	@param msg the info log message string is appended to this string
-	@param obj the GL object that is used to retrieve the info log
+	@param obj the GL shader object that is used to retrieve the info log
 	*/
-	String logObjectInfo(const String& msg, const GLhandleARB obj);
+	String logShaderInfo(const String& msg, const GLuint obj);
+
+	/** if there is a message in GL info log then post it in the engine Log
+	@param msg the info log message string is appended to this string
+	@param obj the GL program object that is used to retrieve the info log
+	*/
+	String logProgramInfo(const String& msg, const GLuint obj);
 
 
 } // namespace CamelotEngine

+ 7 - 8
CamelotGLRenderer/Source/GLSL/include/CmGLSLGpuProgram.h

@@ -52,12 +52,15 @@ namespace CamelotEngine {
 		GLSLProgram* mGLSLProgram;
 
 		/// keep track of the number of vertex shaders created
-		static GLuint mVertexShaderCount;
+		static UINT32 mVertexShaderCount;
 		/// keep track of the number of fragment shaders created
-		static GLuint mFragmentShaderCount;
+		static UINT32 mFragmentShaderCount;
 		/// keep track of the number of geometry shaders created
-		static GLuint mGeometryShaderCount;
-
+		static UINT32 mGeometryShaderCount;
+		/// keep track of the number of hull shaders created
+		static UINT32 mHullShaderCount;
+		/// keep track of the number of domain shaders created
+		static UINT32 mDomainShaderCount;
 	public:
 		~GLSLGpuProgram();
 		GLSLGpuProgram(GLSLProgram* parent, const String& source, const String& entryPoint, const String& language, 
@@ -70,10 +73,6 @@ namespace CamelotEngine {
 		/// Execute the param binding functions for this program
 		void bindProgramParameters(GpuProgramParametersSharedPtr params, UINT16 mask);
 
-		/// Get the assigned GL program id
-		const GLuint getProgramID(void) const
-		{ return mProgramID; }
-
 		/// get the GLSLProgram for the shader object
 		GLSLProgram* getGLSLProgram(void) const { return mGLSLProgram; }
 

+ 7 - 3
CamelotGLRenderer/Source/GLSL/include/CmGLSLLinkProgram.h

@@ -63,6 +63,10 @@ namespace CamelotEngine {
 		GLSLGpuProgram* mGeometryProgram;
 		/// Linked fragment program
 		GLSLGpuProgram* mFragmentProgram;
+		/// Linked domain program
+		GLSLGpuProgram* mDomainProgram;
+		/// Linked hull program
+		GLSLGpuProgram* mHullProgram;
 
 		/// flag to indicate that uniform references have already been built
 		bool		mUniformRefsBuilt;
@@ -71,8 +75,6 @@ namespace CamelotEngine {
 		/// flag indicating that the program object has been successfully linked
 		GLint		mLinked;
 
-		/// build uniform references from active named uniforms
-		void buildGLUniformReferences(void);
 		/// extract attributes
 		void extractAttributes(void);
 
@@ -93,13 +95,15 @@ namespace CamelotEngine {
 
 	public:
 		/// constructor should only be used by GLSLLinkProgramManager
-		GLSLLinkProgram(GLSLGpuProgram* vertexProgram, GLSLGpuProgram* geometryProgram, GLSLGpuProgram* fragmentProgram);
+		GLSLLinkProgram(GLSLGpuProgram* vertexProgram, GLSLGpuProgram* geometryProgram, GLSLGpuProgram* fragmentProgram,
+			GLSLGpuProgram* hullProgram, GLSLGpuProgram* domainProgram);
 		~GLSLLinkProgram(void);
 
 		/** Makes a program object active by making sure it is linked and then putting it in use.
 
 		*/
 		void activate(void);
+
 		/** updates program object uniforms using data from GpuProgramParamters.
 		normally called by GLSLGpuProgram::bindParameters() just before rendering occurs.
 		*/

+ 42 - 52
CamelotGLRenderer/Source/GLSL/include/CmGLSLLinkProgramManager.h

@@ -37,24 +37,40 @@ THE SOFTWARE.
 namespace CamelotEngine {
 
 
-	/** Ogre assumes that there are seperate vertex and fragment programs to deal with but
-		GLSL has one program object that represents the active vertex and fragment shader objects
-		during a rendering state.  GLSL Vertex and fragment 
-		shader objects are compiled seperately and then attached to a program object and then the
-		program object is linked.  Since Ogre can only handle one vertex program and one fragment
-		program being active in a pass, the GLSL Link Program Manager does the same.  The GLSL Link
-		program manager acts as a state machine and activates a program object based on the active
-		vertex and fragment program.  Previously created program objects are stored along with a unique
-		key in a hash_map for quick retrieval the next time the program object is required.
-
+	/** Camelot assumes that there are seperate shader programs to deal with but
+		GLSL has one program object that represents the active shader objects
+		during a rendering state.  GLSL shader objects are compiled seperately and then attached to a 
+		program object and then theprogram object is linked.  Since Ogre can only handle one vertex 
+		program and one fragmentprogram being active in a pass, the GLSL Link Program Manager does the same.  
+		The GLSL Link program manager acts as a state machine and activates a program object based on the active
+		shader program.  
 	*/
 
 	class CM_RSGL_EXPORT GLSLLinkProgramManager : public Module<GLSLLinkProgramManager>
 	{
-
 	private:
+		struct LinkProgramKey
+		{
+			UINT32 vertexProgKey;
+			UINT32 fragmentProgKey;
+			UINT32 geometryProgKey;
+			UINT32 hullProgKey;
+			UINT32 domainProgKey;
+		};
+
+		class LinkProgramKeyHashFunction 
+		{
+		public:
+			::std::size_t operator()(const LinkProgramKey &key) const;
+		};
+
+		class LinkProgramKeyEqual 
+		{
+		public:
+			bool operator()(const LinkProgramKey &a, const LinkProgramKey &b) const;
+		};
 	
-		typedef map<UINT64, GLSLLinkProgram*>::type LinkProgramMap;
+		typedef std::unordered_map<LinkProgramKey, GLSLLinkProgram*, LinkProgramKeyHashFunction, LinkProgramKeyEqual> LinkProgramMap;
 		typedef LinkProgramMap::iterator LinkProgramIterator;
 
 		/// container holding previously created program objects 
@@ -64,24 +80,15 @@ namespace CamelotEngine {
 		GLSLGpuProgram* mActiveVertexGpuProgram;
 		GLSLGpuProgram* mActiveGeometryGpuProgram;
 		GLSLGpuProgram* mActiveFragmentGpuProgram;
+		GLSLGpuProgram* mActiveHullGpuProgram;
+		GLSLGpuProgram* mActiveDomainGpuProgram;
 		GLSLLinkProgram* mActiveLinkProgram;
 
-		typedef map<String, GLenum>::type StringToEnumMap;
-		StringToEnumMap mTypeEnumMap;
-
-		/// Use type to complete other information
-		void completeDefInfo(GLenum gltype, GpuConstantDefinition& defToUpdate);
-		/// Find where the data for a specific uniform should come from, populate
-		bool completeParamSource(const String& paramName,
-			const GpuConstantDefinitionMap* vertexConstantDefs, 
-			const GpuConstantDefinitionMap* geometryConstantDefs,
-			const GpuConstantDefinitionMap* fragmentConstantDefs,
-			GLUniformReference& refToUpdate);
+		void determineParamInfo(GpuParamMemberDesc& desc, const String& paramName, GLuint programHandle, GLuint uniformIndex);
 
 	public:
 
 		GLSLLinkProgramManager(void);
-
 		~GLSLLinkProgramManager(void);
 
 		/**
@@ -92,47 +99,30 @@ namespace CamelotEngine {
 
 		/** Set the active fragment shader for the next rendering state.
 			The active program object will be cleared.
-			Normally called from the GLSLGpuProgram::bindProgram and unbindProgram methods
 		*/
 		void setActiveFragmentShader(GLSLGpuProgram* fragmentGpuProgram);
+
 		/** Set the active geometry shader for the next rendering state.
 			The active program object will be cleared.
-			Normally called from the GLSLGpuProgram::bindProgram and unbindProgram methods
 		*/
 		void setActiveGeometryShader(GLSLGpuProgram* geometryGpuProgram);
+
 		/** Set the active vertex shader for the next rendering state.
 			The active program object will be cleared.
-			Normally called from the GLSLGpuProgram::bindProgram and unbindProgram methods
 		*/
 		void setActiveVertexShader(GLSLGpuProgram* vertexGpuProgram);
 
-		/** Populate a list of uniforms based on a program object.
-		@param programObject Handle to the program object to query
-		@param vertexConstantDefs Definition of the constants extracted from the
-			vertex program, used to match up physical buffer indexes with program
-			uniforms. May be null if there is no vertex program.
-		@param geometryConstantDefs Definition of the constants extracted from the
-			geometry program, used to match up physical buffer indexes with program
-			uniforms. May be null if there is no geometry program.
-		@param fragmentConstantDefs Definition of the constants extracted from the
-			fragment program, used to match up physical buffer indexes with program
-			uniforms. May be null if there is no fragment program.
-		@param list The list to populate (will not be cleared before adding, clear
-		it yourself before calling this if that's what you want).
+		/** Set the active hull shader for the next rendering state.
+			The active program object will be cleared.
 		*/
-		void extractUniforms(GLhandleARB programObject, 
-			const GpuConstantDefinitionMap* vertexConstantDefs, 
-			const GpuConstantDefinitionMap* geometryConstantDefs,
-			const GpuConstantDefinitionMap* fragmentConstantDefs,
-			GLUniformReferenceList& list);
-		/** Populate a list of uniforms based on GLSL source.
-		@param src Reference to the source code
-		@param list The defs to populate (will not be cleared before adding, clear
-		it yourself before calling this if that's what you want).
-		@param filename The file name this came from, for logging errors.
+		void setActiveHullShader(GLSLGpuProgram* hullGpuProgram);
+
+		/** Set the active domain shader for the next rendering state.
+			The active program object will be cleared.
 		*/
-		void extractConstantDefs(const String& src, GpuNamedConstants& constantDefs, 
-			const String& filename);
+		void setActiveDomainShader(GLSLGpuProgram* domainGpuProgram);
+
+		void extractGpuParams(GLSLLinkProgram* linkProgram, GpuParamDesc& returnParamDesc);
 	};
 
 }

+ 0 - 16
CamelotGLRenderer/Source/GLSL/include/CmGLSLProgram.h

@@ -59,16 +59,6 @@ namespace CamelotEngine {
 		~GLSLProgram();
 
 		const GLhandleARB getGLHandle() const { return mGLHandle; }
-		void attachToProgramObject( const GLhandleARB programObject );
-		void detachFromProgramObject( const GLhandleARB programObject );
-		String getAttachedShaderNames() const { return mAttachedShaderNames; }
-
-		/// Overridden
-		bool getPassTransformStates(void) const;
-		bool getPassSurfaceAndLightStates(void) const;
-
-        /** Attach another GLSL Shader to this one. */
-        void attachChildShader(const String& name);
 
 		/** Sets the preprocessor defines use to compile the program. */
 		void setPreprocessorDefines(const String& defines) { mPreprocessorDefines = defines; }
@@ -139,14 +129,8 @@ namespace CamelotEngine {
 		RenderOperation::OperationType mOutputOperationType;
 		/// The maximum amount of vertices that this (geometry) program can output
 		int mMaxOutputVertices;
-		/// attached Shader names
-		String mAttachedShaderNames;
 		/// Preprocessor options
 		String mPreprocessorDefines;
-		/// container of attached programs
-		typedef vector< GLSLProgram* >::type GLSLProgramContainer;
-		typedef GLSLProgramContainer::iterator GLSLProgramContainerIterator;
-		GLSLProgramContainer mAttachedGLSLPrograms;
 
 		/************************************************************************/
 		/* 								SERIALIZATION                      		*/

+ 40 - 12
CamelotGLRenderer/Source/GLSL/src/CmGLSLExtSupport.cpp

@@ -28,12 +28,12 @@ THE SOFTWARE.
 
 #include "CmGLSLExtSupport.h"
 #include "CmGLSupport.h"
+#include "CmDebug.h"
 
 namespace CamelotEngine
 {
-
-    //-----------------------------------------------------------------------------
-    void checkForGLSLError(const String& ogreMethod, const String& errorTextPrefix, const GLhandleARB obj, const bool forceInfoLog, const bool forceException)
+    void checkForGLSLError(const String& ogreMethod, const String& errorTextPrefix, const GLuint obj, 
+		GLSLObjectType objectType, const bool forceInfoLog, const bool forceException)
     {
 		GLenum glErr;
 		bool errorsFound = false;
@@ -57,17 +57,23 @@ namespace CamelotEngine
 		if (errorsFound || forceInfoLog)
 		{
 			// if shader or program object then get the log message and send to the log manager
-			msg += logObjectInfo( msg, obj );
+			if(objectType == GLSLOT_SHADER)
+				msg += logShaderInfo(msg, obj);
+			else if(objectType == GLSLOT_PROGRAM)
+				msg += logProgramInfo(msg, obj);
 
             if (forceException) 
 			{
 				CM_EXCEPT(InternalErrorException, msg);
 			}
+			else
+			{
+				LOGWRN(msg);
+			}
 		}
     }
 
-    //-----------------------------------------------------------------------------
-	String logObjectInfo(const String& msg, const GLhandleARB obj)
+	String logShaderInfo(const String& msg, const GLuint obj)
 	{
 		String logMessage = msg;
 
@@ -75,26 +81,48 @@ namespace CamelotEngine
 		{
 			GLint infologLength = 0;
 
-			glGetObjectParameterivARB(obj, GL_OBJECT_INFO_LOG_LENGTH_ARB, &infologLength);
+			glGetShaderiv(obj, GL_INFO_LOG_LENGTH, &infologLength);
 
 			if (infologLength > 0)
 			{
 				GLint charsWritten  = 0;
 
-				GLcharARB * infoLog = new GLcharARB[infologLength];
+				GLchar* infoLog = new GLchar[infologLength];
 
-				glGetInfoLogARB(obj, infologLength, &charsWritten, infoLog);
+				glGetShaderInfoLog(obj, infologLength, &charsWritten, infoLog);
 				logMessage += String(infoLog);
-				// TODO LOG PORT - Log this somewhere
-				//LogManager::getSingleton().logMessage(logMessage);
 
 				delete [] infoLog;
 			}
 		}
 
 		return logMessage;
-
 	}
 
+	String logProgramInfo(const String& msg, const GLuint obj)
+	{
+		String logMessage = msg;
+
+		if (obj > 0)
+		{
+			GLint infologLength = 0;
+
+			glGetProgramiv(obj, GL_INFO_LOG_LENGTH, &infologLength);
+
+			if (infologLength > 0)
+			{
+				GLint charsWritten  = 0;
+
+				GLchar* infoLog = new GLchar[infologLength];
+
+				glGetProgramInfoLog(obj, infologLength, &charsWritten, infoLog);
+				logMessage += String(infoLog);
+
+				delete [] infoLog;
+			}
+		}
+
+		return logMessage;
+	}
 
 } // namespace CamelotEngine

+ 48 - 27
CamelotGLRenderer/Source/GLSL/src/CmGLSLGpuProgram.cpp

@@ -35,9 +35,11 @@ THE SOFTWARE.
 
 namespace CamelotEngine {
 
-	GLuint GLSLGpuProgram::mVertexShaderCount = 0;
-	GLuint GLSLGpuProgram::mFragmentShaderCount = 0;
-	GLuint GLSLGpuProgram::mGeometryShaderCount = 0;
+	UINT32 GLSLGpuProgram::mVertexShaderCount = 0;
+	UINT32 GLSLGpuProgram::mFragmentShaderCount = 0;
+	UINT32 GLSLGpuProgram::mGeometryShaderCount = 0;
+	UINT32 GLSLGpuProgram::mDomainShaderCount = 0;
+	UINT32 GLSLGpuProgram::mHullShaderCount = 0;
     //-----------------------------------------------------------------------------
 	GLSLGpuProgram::GLSLGpuProgram(GLSLProgram* parent, const String& source, const String& entryPoint, const String& language, 
 		GpuProgramType gptype, GpuProgramProfile profile) : 
@@ -46,17 +48,25 @@ namespace CamelotEngine {
         mType = parent->getType();
         mSyntaxCode = "glsl";
 
-		if (parent->getType() == GPT_VERTEX_PROGRAM)
+		switch(parent->getType())
 		{
+		case GPT_VERTEX_PROGRAM:
 			mProgramID = ++mVertexShaderCount;
-		}
-		else if (parent->getType() == GPT_FRAGMENT_PROGRAM)
-		{
+			break;
+		case GPT_FRAGMENT_PROGRAM:
 			mProgramID = ++mFragmentShaderCount;
-		}
-		else
-		{
+			break;
+		case GPT_GEOMETRY_PROGRAM:
 			mProgramID = ++mGeometryShaderCount;
+			break;
+		case GPT_DOMAIN_PROGRAM:
+			mProgramID = ++mDomainShaderCount;
+			break;
+		case GPT_HULL_PROGRAM:
+			mProgramID = ++mHullShaderCount;
+			break;
+		default:
+			CM_EXCEPT(InternalErrorException, "Invalid gpu program type: " + toString(parent->getType()));
 		}
     }
     //-----------------------------------------------------------------------
@@ -92,14 +102,21 @@ namespace CamelotEngine {
 		switch (mType)
 		{
 		case GPT_VERTEX_PROGRAM:
-			GLSLLinkProgramManager::instance().setActiveVertexShader( this );
+			GLSLLinkProgramManager::instance().setActiveVertexShader(this);
 			break;
 		case GPT_FRAGMENT_PROGRAM:
-			GLSLLinkProgramManager::instance().setActiveFragmentShader( this );
+			GLSLLinkProgramManager::instance().setActiveFragmentShader(this);
 			break;
 		case GPT_GEOMETRY_PROGRAM:
-			GLSLLinkProgramManager::instance().setActiveGeometryShader( this );
+			GLSLLinkProgramManager::instance().setActiveGeometryShader(this);
+			break;
+		case GPT_DOMAIN_PROGRAM:
+			GLSLLinkProgramManager::instance().setActiveDomainShader(this);
 			break;
+		case GPT_HULL_PROGRAM:
+			GLSLLinkProgramManager::instance().setActiveHullShader(this);
+		default:
+			CM_EXCEPT(InternalErrorException, "Invalid gpu program type: " + toString(mType));
 		}
 	}
 
@@ -107,19 +124,26 @@ namespace CamelotEngine {
 	void GLSLGpuProgram::unbindProgram(void)
 	{
 		// tell the Link Program Manager what shader is to become inactive
-		if (mType == GPT_VERTEX_PROGRAM)
-		{
-			GLSLLinkProgramManager::instance().setActiveVertexShader( NULL );
-		}
-		else if (mType == GPT_GEOMETRY_PROGRAM)
-		{
-			GLSLLinkProgramManager::instance().setActiveGeometryShader( NULL );
-		}
-		else // its a fragment shader
+		switch(mType)
 		{
-			GLSLLinkProgramManager::instance().setActiveFragmentShader( NULL );
+		case GPT_VERTEX_PROGRAM:
+			GLSLLinkProgramManager::instance().setActiveVertexShader(nullptr);
+			break;
+		case GPT_FRAGMENT_PROGRAM:
+			GLSLLinkProgramManager::instance().setActiveFragmentShader(nullptr);
+			break;
+		case GPT_GEOMETRY_PROGRAM:
+			GLSLLinkProgramManager::instance().setActiveGeometryShader(nullptr);
+			break;
+		case GPT_DOMAIN_PROGRAM:
+			GLSLLinkProgramManager::instance().setActiveDomainShader(nullptr);
+			break;
+		case GPT_HULL_PROGRAM:
+			GLSLLinkProgramManager::instance().setActiveHullShader(nullptr);
+			break;
+		default:
+			CM_EXCEPT(InternalErrorException, "Invalid gpu program type: " + toString(mType));
 		}
-
 	}
 
 	//-----------------------------------------------------------------------------
@@ -164,8 +188,5 @@ namespace CamelotEngine {
 			return GLGpuProgram::isAttributeValid(semantic, index);
 		}
 	}
-
-
-
 }
 

+ 50 - 59
CamelotGLRenderer/Source/GLSL/src/CmGLSLLinkProgram.cpp

@@ -105,43 +105,64 @@ namespace CamelotEngine {
 		}
 	}
 	//-----------------------------------------------------------------------
-	GLSLLinkProgram::GLSLLinkProgram(GLSLGpuProgram* vertexProgram, GLSLGpuProgram* geometryProgram, GLSLGpuProgram* fragmentProgram)
+	GLSLLinkProgram::GLSLLinkProgram(GLSLGpuProgram* vertexProgram, GLSLGpuProgram* geometryProgram, GLSLGpuProgram* fragmentProgram,
+		GLSLGpuProgram* hullProgram, GLSLGpuProgram* domainProgram)
         : mVertexProgram(vertexProgram)
 		, mGeometryProgram(geometryProgram)
 		, mFragmentProgram(fragmentProgram)
+		, mHullProgram(hullProgram)
+		, mDomainProgram(domainProgram)
 		, mUniformRefsBuilt(false)
         , mLinked(false)
 
 	{
-			//checkForGLSLError( "GLSLLinkProgram::GLSLLinkProgram", "Error prior to Creating GLSL Program Object", 0);
-		    glGetError(); //Clean up the error. Otherwise will flood log.
-		    mGLHandle = glCreateProgramObjectARB();
-			checkForGLSLError( "GLSLLinkProgram::GLSLLinkProgram", "Error Creating GLSL Program Object", 0 );
+		checkForGLSLError("GLSLLinkProgram::GLSLLinkProgram", "Error prior to Creating GLSL Program Object", 0, GLSLOT_PROGRAM);
+		glGetError(); //Clean up the error. Otherwise will flood log.
+		mGLHandle = glCreateProgram();
+		checkForGLSLError("GLSLLinkProgram::GLSLLinkProgram", "Error Creating GLSL Program Object", 0, GLSLOT_PROGRAM);
+
+		// tell shaders to attach themselves to the LinkProgram
+		// let the shaders do the attaching since they may have several children to attach
+		if (mVertexProgram)
+		{
+			glAttachShader(mGLHandle, mVertexProgram->getGLSLProgram()->getGLHandle());
+			checkForGLSLError("GLSLProgram::attachToProgramObject",
+				"Error attaching shader object to GLSL Program Object", mGLHandle, GLSLOT_PROGRAM);
+		}
 
+		if (mGeometryProgram)
+		{
+			glAttachShader(mGLHandle, mGeometryProgram->getGLSLProgram()->getGLHandle());
+			checkForGLSLError("GLSLProgram::attachToProgramObject",
+				"Error attaching shader object to GLSL Program Object", mGLHandle, GLSLOT_PROGRAM);
+		}
 
-			// tell shaders to attach themselves to the LinkProgram
-			// let the shaders do the attaching since they may have several children to attach
-			if (mVertexProgram)
-			{
-				mVertexProgram->getGLSLProgram()->attachToProgramObject(mGLHandle);
-			}
-			if (mGeometryProgram)
-			{
-				mGeometryProgram->getGLSLProgram()->attachToProgramObject(mGLHandle);
-				//Don't set adjacency flag. We handle it internally and expose "false"
-			}
-			if (mFragmentProgram)
-			{
-				mFragmentProgram->getGLSLProgram()->attachToProgramObject(mGLHandle);
-			}
+		if (mFragmentProgram)
+		{
+			glAttachShader(mGLHandle, mFragmentProgram->getGLSLProgram()->getGLHandle());
+			checkForGLSLError("GLSLProgram::attachToProgramObject",
+				"Error attaching shader object to GLSL Program Object", mGLHandle, GLSLOT_PROGRAM);
+		}
+
+		if (mDomainProgram)
+		{
+			glAttachShader(mGLHandle, mDomainProgram->getGLSLProgram()->getGLHandle());
+			checkForGLSLError("GLSLProgram::attachToProgramObject",
+				"Error attaching shader object to GLSL Program Object", mGLHandle, GLSLOT_PROGRAM);
+		}
 
+		if (mHullProgram)
+		{
+			glAttachShader(mGLHandle, mHullProgram->getGLSLProgram()->getGLHandle());
+			checkForGLSLError("GLSLProgram::attachToProgramObject",
+				"Error attaching shader object to GLSL Program Object", mGLHandle, GLSLOT_PROGRAM);
+		}
 	}
 
 	//-----------------------------------------------------------------------
 	GLSLLinkProgram::~GLSLLinkProgram(void)
 	{
-		glDeleteObjectARB(mGLHandle);
-
+		glDeleteProgram(mGLHandle);
 	}
 
 	//-----------------------------------------------------------------------
@@ -218,32 +239,30 @@ namespace CamelotEngine {
 			glGetObjectParameterivARB( mGLHandle, GL_OBJECT_LINK_STATUS_ARB, &mLinked );
 
 			if(!mLinked)
-				logObjectInfo( String("GLSL link FAILED : "), mGLHandle );
+				logProgramInfo( String("GLSL link FAILED : "), mGLHandle );
 
 			// force logging and raise exception if not linked
 			checkForGLSLError( "GLSLLinkProgram::Activate",
-				"Error linking GLSL Program Object : ", mGLHandle, !mLinked, !mLinked );
+				"Error linking GLSL Program Object : ", mGLHandle, GLSLOT_PROGRAM, !mLinked, !mLinked );
+
 			if(mLinked)
 			{
-				logObjectInfo( String("GLSL link result : "), mGLHandle );
-				buildGLUniformReferences();
+				logProgramInfo( String("GLSL link result : "), mGLHandle );
 				extractAttributes();
 			}
-
 		}
 
 		if (mLinked)
 		{
 			checkForGLSLError( "GLSLLinkProgram::Activate",
-				"Error prior to using GLSL Program Object : ", mGLHandle, false, false);
+				"Error prior to using GLSL Program Object : ", mGLHandle, GLSLOT_PROGRAM, false, false);
 
 		    glUseProgramObjectARB( mGLHandle );
 
 			checkForGLSLError( "GLSLLinkProgram::Activate",
-				"Error using GLSL Program Object : ", mGLHandle, false, false);
+				"Error using GLSL Program Object : ", mGLHandle, GLSLOT_PROGRAM, false, false);
 		}
 	}
-
 	//-----------------------------------------------------------------------
 	void GLSLLinkProgram::extractAttributes(void)
 	{
@@ -270,34 +289,6 @@ namespace CamelotEngine {
 	{
 		return mValidAttributes.find(getAttributeIndex(semantic, index)) != mValidAttributes.end();
 	}
-	//-----------------------------------------------------------------------
-	void GLSLLinkProgram::buildGLUniformReferences(void)
-	{
-		if (!mUniformRefsBuilt)
-		{
-			const GpuConstantDefinitionMap* vertParams = 0;
-			const GpuConstantDefinitionMap* fragParams = 0;
-			const GpuConstantDefinitionMap* geomParams = 0;
-			if (mVertexProgram)
-			{
-				vertParams = &(mVertexProgram->getGLSLProgram()->getConstantDefinitions_internal().map);
-			}
-			if (mGeometryProgram)
-			{
-				geomParams = &(mGeometryProgram->getGLSLProgram()->getConstantDefinitions_internal().map);
-			}
-			if (mFragmentProgram)
-			{
-				fragParams = &(mFragmentProgram->getGLSLProgram()->getConstantDefinitions_internal().map);
-			}
-
-			GLSLLinkProgramManager::instance().extractUniforms(
-				mGLHandle, vertParams, geomParams, fragParams, mGLUniformReferences);
-
-			mUniformRefsBuilt = true;
-		}
-	}
-
 	//-----------------------------------------------------------------------
 	void GLSLLinkProgram::updateUniforms(GpuProgramParametersSharedPtr params, 
 		UINT16 mask, GpuProgramType fromProgType)
@@ -423,7 +414,7 @@ namespace CamelotEngine {
 
 					} // end switch
 	#if CM_DEBUG_MODE
-					checkForGLSLError( "GLSLLinkProgram::updateUniforms", "Error updating uniform", 0 );
+					checkForGLSLError( "GLSLLinkProgram::updateUniforms", "Error updating uniform", 0, GLSLOT_PROGRAM);
 	#endif
 				} // variability & mask
 			} // fromProgType == currentUniform->mSourceProgType

+ 279 - 378
CamelotGLRenderer/Source/GLSL/src/CmGLSLLinkProgramManager.cpp

@@ -29,41 +29,40 @@ THE SOFTWARE.
 #include "CmGLSLLinkProgramManager.h"
 #include "CmGLSLGpuProgram.h"
 #include "CmGLSLProgram.h"
+#include "CmGpuParamDesc.h"
 
-namespace CamelotEngine {
+namespace CamelotEngine 
+{
+	template <class T>
+	inline void hash_combine(std::size_t& seed, const T& v)
+	{
+		std::hash<T> hasher;
+		seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
+	}
+
+	::std::size_t GLSLLinkProgramManager::LinkProgramKeyHashFunction::operator()(const GLSLLinkProgramManager::LinkProgramKey &key) const
+	{
+		std::size_t seed = 0;
+		hash_combine(seed, key.vertexProgKey);
+		hash_combine(seed, key.fragmentProgKey);
+		hash_combine(seed, key.geometryProgKey);
+		hash_combine(seed, key.hullProgKey);
+		hash_combine(seed, key.domainProgKey);
+
+		return seed;
+	}
+
+	bool GLSLLinkProgramManager::LinkProgramKeyEqual::operator()(const GLSLLinkProgramManager::LinkProgramKey &a, const GLSLLinkProgramManager::LinkProgramKey &b) const
+	{
+		return a.vertexProgKey == b.vertexProgKey && a.fragmentProgKey == b.fragmentProgKey && a.geometryProgKey == b.geometryProgKey &&
+			a.hullProgKey == b.hullProgKey && a.domainProgKey == b.domainProgKey;
+	}
 
 	//-----------------------------------------------------------------------
-	GLSLLinkProgramManager::GLSLLinkProgramManager(void) : mActiveVertexGpuProgram(NULL),
-		mActiveGeometryGpuProgram(NULL), mActiveFragmentGpuProgram(NULL), mActiveLinkProgram(NULL)
+	GLSLLinkProgramManager::GLSLLinkProgramManager(void) : mActiveVertexGpuProgram(nullptr),
+		mActiveGeometryGpuProgram(nullptr), mActiveFragmentGpuProgram(nullptr), mActiveHullGpuProgram(nullptr),
+		mActiveDomainGpuProgram(nullptr), mActiveLinkProgram(nullptr)
 	{
-		// Fill in the relationship between type names and enums
-		mTypeEnumMap.insert(StringToEnumMap::value_type("float", GL_FLOAT));
-		mTypeEnumMap.insert(StringToEnumMap::value_type("vec2", GL_FLOAT_VEC2));
-		mTypeEnumMap.insert(StringToEnumMap::value_type("vec3", GL_FLOAT_VEC3));
-		mTypeEnumMap.insert(StringToEnumMap::value_type("vec4", GL_FLOAT_VEC4));
-		mTypeEnumMap.insert(StringToEnumMap::value_type("sampler1D", GL_SAMPLER_1D));
-		mTypeEnumMap.insert(StringToEnumMap::value_type("sampler2D", GL_SAMPLER_2D));
-		mTypeEnumMap.insert(StringToEnumMap::value_type("sampler3D", GL_SAMPLER_3D));
-		mTypeEnumMap.insert(StringToEnumMap::value_type("samplerCube", GL_SAMPLER_CUBE));
-		mTypeEnumMap.insert(StringToEnumMap::value_type("sampler1DShadow", GL_SAMPLER_1D_SHADOW));
-		mTypeEnumMap.insert(StringToEnumMap::value_type("sampler2DShadow", GL_SAMPLER_2D_SHADOW));
-		mTypeEnumMap.insert(StringToEnumMap::value_type("int", GL_INT));
-		mTypeEnumMap.insert(StringToEnumMap::value_type("ivec2", GL_INT_VEC2));
-		mTypeEnumMap.insert(StringToEnumMap::value_type("ivec3", GL_INT_VEC3));
-		mTypeEnumMap.insert(StringToEnumMap::value_type("ivec4", GL_INT_VEC4));
-		mTypeEnumMap.insert(StringToEnumMap::value_type("mat2", GL_FLOAT_MAT2));
-		mTypeEnumMap.insert(StringToEnumMap::value_type("mat3", GL_FLOAT_MAT3));
-		mTypeEnumMap.insert(StringToEnumMap::value_type("mat4", GL_FLOAT_MAT4));
-		// GL 2.1
-		mTypeEnumMap.insert(StringToEnumMap::value_type("mat2x2", GL_FLOAT_MAT2));
-		mTypeEnumMap.insert(StringToEnumMap::value_type("mat3x3", GL_FLOAT_MAT3));
-		mTypeEnumMap.insert(StringToEnumMap::value_type("mat4x4", GL_FLOAT_MAT4));
-		mTypeEnumMap.insert(StringToEnumMap::value_type("mat2x3", GL_FLOAT_MAT2x3));
-		mTypeEnumMap.insert(StringToEnumMap::value_type("mat3x2", GL_FLOAT_MAT3x2));
-		mTypeEnumMap.insert(StringToEnumMap::value_type("mat3x4", GL_FLOAT_MAT3x4));
-		mTypeEnumMap.insert(StringToEnumMap::value_type("mat4x3", GL_FLOAT_MAT4x3));
-		mTypeEnumMap.insert(StringToEnumMap::value_type("mat2x4", GL_FLOAT_MAT2x4));
-		mTypeEnumMap.insert(StringToEnumMap::value_type("mat4x2", GL_FLOAT_MAT4x2));
 
 	}
 
@@ -76,7 +75,6 @@ namespace CamelotEngine {
 		{
 			delete currentProgram->second;
 		}
-
 	}
 
 	//-----------------------------------------------------------------------
@@ -86,46 +84,32 @@ namespace CamelotEngine {
 		if (mActiveLinkProgram)
 			return mActiveLinkProgram;
 
-		// no active link program so find one or make a new one
-		// is there an active key?
-		UINT64 activeKey = 0;
-
-		if (mActiveVertexGpuProgram)
-		{
-			activeKey = static_cast<UINT64>(mActiveVertexGpuProgram->getProgramID()) << 32;
-		}
-		if (mActiveGeometryGpuProgram)
+		LinkProgramKey key;
+		key.vertexProgKey = mActiveVertexGpuProgram != nullptr ? mActiveVertexGpuProgram->getProgramID() : 0;
+		key.fragmentProgKey = mActiveFragmentGpuProgram != nullptr ? mActiveFragmentGpuProgram->getProgramID() : 0;
+		key.geometryProgKey = mActiveGeometryGpuProgram != nullptr ? mActiveGeometryGpuProgram->getProgramID() : 0;
+		key.hullProgKey = mActiveHullGpuProgram != nullptr ? mActiveHullGpuProgram->getProgramID() : 0;
+		key.domainProgKey = mActiveDomainGpuProgram != nullptr ? mActiveDomainGpuProgram->getProgramID() : 0;
+
+		// find the key in the hash map
+		LinkProgramIterator programFound = mLinkPrograms.find(key);
+		// program object not found for key so need to create it
+		if (programFound == mLinkPrograms.end())
 		{
-			activeKey += static_cast<UINT64>(mActiveGeometryGpuProgram->getProgramID()) << 16;
+			mActiveLinkProgram = new GLSLLinkProgram(mActiveVertexGpuProgram, mActiveGeometryGpuProgram, mActiveFragmentGpuProgram, mActiveHullGpuProgram, mActiveDomainGpuProgram);
+			mLinkPrograms[key] = mActiveLinkProgram;
 		}
-		if (mActiveFragmentGpuProgram)
+		else
 		{
-			activeKey += static_cast<UINT64>(mActiveFragmentGpuProgram->getProgramID());
+			// found a link program in map container so make it active
+			mActiveLinkProgram = programFound->second;
 		}
 
-		// only return a link program object if a vertex, geometry or fragment program exist
-		if (activeKey > 0)
-		{
-			// find the key in the hash map
-			LinkProgramIterator programFound = mLinkPrograms.find(activeKey);
-			// program object not found for key so need to create it
-			if (programFound == mLinkPrograms.end())
-			{
-				mActiveLinkProgram = new GLSLLinkProgram(mActiveVertexGpuProgram, mActiveGeometryGpuProgram,mActiveFragmentGpuProgram);
-				mLinkPrograms[activeKey] = mActiveLinkProgram;
-			}
-			else
-			{
-				// found a link program in map container so make it active
-				mActiveLinkProgram = programFound->second;
-			}
-
-		}
 		// make the program object active
-		if (mActiveLinkProgram) mActiveLinkProgram->activate();
+		if (mActiveLinkProgram) 
+			mActiveLinkProgram->activate();
 
 		return mActiveLinkProgram;
-
 	}
 
 	//-----------------------------------------------------------------------
@@ -135,7 +119,7 @@ namespace CamelotEngine {
 		{
 			mActiveFragmentGpuProgram = fragmentGpuProgram;
 			// ActiveLinkProgram is no longer valid
-			mActiveLinkProgram = NULL;
+			mActiveLinkProgram = nullptr;
 			// change back to fixed pipeline
 			glUseProgramObjectARB(0);
 		}
@@ -148,7 +132,7 @@ namespace CamelotEngine {
 		{
 			mActiveVertexGpuProgram = vertexGpuProgram;
 			// ActiveLinkProgram is no longer valid
-			mActiveLinkProgram = NULL;
+			mActiveLinkProgram = nullptr;
 			// change back to fixed pipeline
 			glUseProgramObjectARB(0);
 		}
@@ -160,361 +144,278 @@ namespace CamelotEngine {
 		{
 			mActiveGeometryGpuProgram = geometryGpuProgram;
 			// ActiveLinkProgram is no longer valid
-			mActiveLinkProgram = NULL;
+			mActiveLinkProgram = nullptr;
 			// change back to fixed pipeline
 			glUseProgramObjectARB(0);
 		}
 	}
-	//---------------------------------------------------------------------
-	void GLSLLinkProgramManager::completeDefInfo(GLenum gltype, 
-		GpuConstantDefinition& defToUpdate)
+	//-----------------------------------------------------------------------
+	void GLSLLinkProgramManager::setActiveHullShader(GLSLGpuProgram* hullGpuProgram)
 	{
-		// decode uniform size and type
-		// Note GLSL never packs rows into float4's(from an API perspective anyway)
-		// therefore all values are tight in the buffer
-		switch (gltype)
+		if (hullGpuProgram != mActiveHullGpuProgram)
 		{
-		case GL_FLOAT:
-			defToUpdate.constType = GCT_FLOAT1;
-			break;
-		case GL_FLOAT_VEC2:
-			defToUpdate.constType = GCT_FLOAT2;
-			break;
-
-		case GL_FLOAT_VEC3:
-			defToUpdate.constType = GCT_FLOAT3;
-			break;
-
-		case GL_FLOAT_VEC4:
-			defToUpdate.constType = GCT_FLOAT4;
-			break;
-		case GL_SAMPLER_1D:
-			// need to record samplers for GLSL
-			defToUpdate.constType = GCT_SAMPLER1D;
-			break;
-		case GL_SAMPLER_2D:
-		case GL_SAMPLER_2D_RECT_ARB:
-			defToUpdate.constType = GCT_SAMPLER2D;
-			break;
-		case GL_SAMPLER_3D:
-			defToUpdate.constType = GCT_SAMPLER3D;
-			break;
-		case GL_SAMPLER_CUBE:
-			defToUpdate.constType = GCT_SAMPLERCUBE;
-			break;
-		case GL_SAMPLER_1D_SHADOW:
-			defToUpdate.constType = GCT_SAMPLER1DSHADOW;
-			break;
-		case GL_SAMPLER_2D_SHADOW:
-		case GL_SAMPLER_2D_RECT_SHADOW_ARB:
-			defToUpdate.constType = GCT_SAMPLER2DSHADOW;
-			break;
-		case GL_INT:
-			defToUpdate.constType = GCT_INT1;
-			break;
-		case GL_INT_VEC2:
-			defToUpdate.constType = GCT_INT2;
-			break;
-		case GL_INT_VEC3:
-			defToUpdate.constType = GCT_INT3;
-			break;
-		case GL_INT_VEC4:
-			defToUpdate.constType = GCT_INT4;
-			break;
-		case GL_FLOAT_MAT2:
-			defToUpdate.constType = GCT_MATRIX_2X2;
-			break;
-		case GL_FLOAT_MAT3:
-			defToUpdate.constType = GCT_MATRIX_3X3;
-			break;
-		case GL_FLOAT_MAT4:
-			defToUpdate.constType = GCT_MATRIX_4X4;
-			break;
-		case GL_FLOAT_MAT2x3:
-			defToUpdate.constType = GCT_MATRIX_2X3;
-			break;
-		case GL_FLOAT_MAT3x2:
-			defToUpdate.constType = GCT_MATRIX_3X2;
-			break;
-		case GL_FLOAT_MAT2x4:
-			defToUpdate.constType = GCT_MATRIX_2X4;
-			break;
-		case GL_FLOAT_MAT4x2:
-			defToUpdate.constType = GCT_MATRIX_4X2;
-			break;
-		case GL_FLOAT_MAT3x4:
-			defToUpdate.constType = GCT_MATRIX_3X4;
-			break;
-		case GL_FLOAT_MAT4x3:
-			defToUpdate.constType = GCT_MATRIX_4X3;
-			break;
-		default:
-			defToUpdate.constType = GCT_UNKNOWN;
-			break;
-
+			mActiveHullGpuProgram = hullGpuProgram;
+			// ActiveLinkProgram is no longer valid
+			mActiveLinkProgram = nullptr;
+			// change back to fixed pipeline
+			glUseProgramObjectARB(0);
 		}
-
-		// GL doesn't pad
-		defToUpdate.elementSize = GpuConstantDefinition::getElementSize(defToUpdate.constType, false);
-
-
 	}
-	//---------------------------------------------------------------------
-	bool GLSLLinkProgramManager::completeParamSource(
-		const String& paramName,
-		const GpuConstantDefinitionMap* vertexConstantDefs, 
-		const GpuConstantDefinitionMap* geometryConstantDefs,
-		const GpuConstantDefinitionMap* fragmentConstantDefs,
-		GLUniformReference& refToUpdate)
+	//-----------------------------------------------------------------------
+	void GLSLLinkProgramManager::setActiveDomainShader(GLSLGpuProgram* domainGpuProgram)
 	{
-		if (vertexConstantDefs)
-		{
-			GpuConstantDefinitionMap::const_iterator parami = 
-				vertexConstantDefs->find(paramName);
-			if (parami != vertexConstantDefs->end())
-			{
-				refToUpdate.mSourceProgType = GPT_VERTEX_PROGRAM;
-				refToUpdate.mConstantDef = &(parami->second);
-				return true;
-			}
-
-		}
-		if (geometryConstantDefs)
+		if (domainGpuProgram != mActiveDomainGpuProgram)
 		{
-			GpuConstantDefinitionMap::const_iterator parami = 
-				geometryConstantDefs->find(paramName);
-			if (parami != geometryConstantDefs->end())
-			{
-				refToUpdate.mSourceProgType = GPT_GEOMETRY_PROGRAM;
-				refToUpdate.mConstantDef = &(parami->second);
-				return true;
-			}
-
-		}
-		if (fragmentConstantDefs)
-		{
-			GpuConstantDefinitionMap::const_iterator parami = 
-				fragmentConstantDefs->find(paramName);
-			if (parami != fragmentConstantDefs->end())
-			{
-				refToUpdate.mSourceProgType = GPT_FRAGMENT_PROGRAM;
-				refToUpdate.mConstantDef = &(parami->second);
-				return true;
-			}
+			mActiveDomainGpuProgram = domainGpuProgram;
+			// ActiveLinkProgram is no longer valid
+			mActiveLinkProgram = nullptr;
+			// change back to fixed pipeline
+			glUseProgramObjectARB(0);
 		}
-		return false;
-
-
 	}
 	//---------------------------------------------------------------------
-	void GLSLLinkProgramManager::extractUniforms(GLhandleARB programObject, 
-		const GpuConstantDefinitionMap* vertexConstantDefs, 
-		const GpuConstantDefinitionMap* geometryConstantDefs,
-		const GpuConstantDefinitionMap* fragmentConstantDefs,
-		GLUniformReferenceList& list)
+	void GLSLLinkProgramManager::extractGpuParams(GLSLLinkProgram* linkProgram, GpuParamDesc& returnParamDesc)
 	{
+		assert(linkProgram != nullptr);
+
 		// scan through the active uniforms and add them to the reference list
 		GLint uniformCount = 0;
+		GLuint glProgram = linkProgram->getGLHandle();
+
+		GLint maxBufferSize = 0;
+		glGetProgramiv(glProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxBufferSize);
 
-		#define BUFFERSIZE 200
-		char   uniformName[BUFFERSIZE] = "";
-		//GLint location;
-		GLUniformReference newGLUniformReference;
+		GLint maxBlockNameBufferSize = 0;
+		glGetProgramiv(glProgram, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &maxBlockNameBufferSize);
+
+		if(maxBlockNameBufferSize > maxBufferSize)
+			maxBufferSize = maxBlockNameBufferSize;
+
+		GLchar* uniformName = new GLchar[maxBufferSize];
+
+		GpuParamBlockDesc globalBlockDesc;
+		globalBlockDesc.slot = 0;
+		globalBlockDesc.name = "CM_INTERNAL_Globals";
+		globalBlockDesc.blockSize = 0;
+
+		returnParamDesc.paramBlocks[globalBlockDesc.name] = globalBlockDesc;
+
+		GLint uniformBlockCount = 0;
+		glGetProgramiv(glProgram, GL_ACTIVE_UNIFORM_BLOCKS, &uniformBlockCount);
+
+		map<UINT32, String>::type blockSlotToName;
+		for (GLuint index = 0; index < (GLuint)uniformBlockCount; index++)
+		{
+			GLsizei unusedSize = 0;
+			glGetActiveUniformBlockName(glProgram, index, maxBufferSize, &unusedSize, uniformName);
+
+			GpuParamBlockDesc newBlockDesc;
+			newBlockDesc.slot = index + 1;
+			newBlockDesc.name = uniformName;
+			newBlockDesc.blockSize = 0;
+
+			returnParamDesc.paramBlocks[newBlockDesc.name] = newBlockDesc;
+			blockSlotToName.insert(std::make_pair(newBlockDesc.slot, newBlockDesc.name));
+		}
 
 		// get the number of active uniforms
-		glGetObjectParameterivARB(programObject, GL_OBJECT_ACTIVE_UNIFORMS_ARB,
-			&uniformCount);
+		glGetProgramiv(glProgram, GL_ACTIVE_UNIFORMS, &uniformCount);
 
 		// Loop over each of the active uniforms, and add them to the reference container
 		// only do this for user defined uniforms, ignore built in gl state uniforms
-		for (int index = 0; index < uniformCount; index++)
+		for (GLuint index = 0; index < (GLuint)uniformCount; index++)
 		{
-			GLint arraySize = 0;
-			GLenum glType;
-			glGetActiveUniformARB(programObject, index, BUFFERSIZE, NULL, 
-				&arraySize, &glType, uniformName);
-			// don't add built in uniforms
-			newGLUniformReference.mLocation = glGetUniformLocationARB(programObject, uniformName);
-			if (newGLUniformReference.mLocation >= 0)
+			GLsizei arraySize = 0;
+			glGetActiveUniformName(glProgram, index, maxBufferSize, &arraySize, uniformName);
+
+			String paramName = String(uniformName);
+
+			// If the uniform name has a "[" in it then its an array element uniform.
+			String::size_type arrayStart = paramName.find("[");
+			if (arrayStart != String::npos)
 			{
-				// user defined uniform found, add it to the reference list
-				String paramName = String( uniformName );
+				// if not the first array element then skip it and continue to the next uniform
+				if (paramName.compare(arrayStart, paramName.size() - 1, "[0]") != 0)
+					CM_EXCEPT(NotImplementedException, "No support for array parameters yet.");
 
-				// currant ATI drivers (Catalyst 7.2 and earlier) and older NVidia drivers will include all array elements as uniforms but we only want the root array name and location
-				// Also note that ATI Catalyst 6.8 to 7.2 there is a bug with glUniform that does not allow you to update a uniform array past the first uniform array element
-				// ie you can't start updating an array starting at element 1, must always be element 0.
+				paramName = paramName.substr(0, arrayStart);
+			}
 
-				// if the uniform name has a "[" in it then its an array element uniform.
-				String::size_type arrayStart = paramName.find("[");
-				if (arrayStart != String::npos)
-				{
-					// if not the first array element then skip it and continue to the next uniform
-					if (paramName.compare(arrayStart, paramName.size() - 1, "[0]") != 0) continue;
-					paramName = paramName.substr(0, arrayStart);
-				}
+			GLint uniformType;
+			glGetActiveUniformsiv(glProgram, 1, &index, GL_UNIFORM_TYPE, &uniformType);
 
-				// find out which params object this comes from
-				bool foundSource = completeParamSource(paramName,
-						vertexConstantDefs,	geometryConstantDefs, fragmentConstantDefs, newGLUniformReference);
+			bool isSampler = false;
+			switch(uniformType)
+			{
+			case GL_SAMPLER_1D:
+			case GL_SAMPLER_2D:
+			case GL_SAMPLER_3D:
+			case GL_SAMPLER_CUBE:
+				isSampler = true;
+			}
 
-				// only add this parameter if we found the source
-				if (foundSource)
-				{
-					assert(size_t (arraySize) == newGLUniformReference.mConstantDef->arraySize
-							&& "GL doesn't agree with our array size!");
-					list.push_back(newGLUniformReference);
-				}
+			if(isSampler)
+			{
+				GpuParamSpecialDesc samplerParam;
+				samplerParam.name = paramName;
+				samplerParam.slot = glGetUniformLocation(glProgram, uniformName);
 
-				// Don't bother adding individual array params, they will be
-				// picked up in the 'parent' parameter can copied all at once
-				// anyway, individual indexes are only needed for lookup from
-				// user params
-			} // end if
-		} // end for
+				GpuParamSpecialDesc textureParam;
+				textureParam.name = paramName;
+				textureParam.slot = samplerParam.slot;
 
-	}
-	//---------------------------------------------------------------------
-	void GLSLLinkProgramManager::extractConstantDefs(const String& src,
-		GpuNamedConstants& defs, const String& filename)
-	{
-		// Parse the output string and collect all uniforms
-		// NOTE this relies on the source already having been preprocessed
-		// which is done in GLSLProgram::loadFromSource
-		String line;
-		String::size_type currPos = src.find("uniform");
-		while (currPos != String::npos)
-		{
-			GpuConstantDefinition def;
-			String paramName;
+				switch(uniformType)
+				{
+				case GL_SAMPLER_1D:
+					samplerParam.type = GST_SAMPLER1D;
+					textureParam.type = GST_TEXTURE1D;
+					break;
+				case GL_SAMPLER_2D:
+					samplerParam.type = GST_SAMPLER2D;
+					textureParam.type = GST_TEXTURE2D;
+					break;
+				case GL_SAMPLER_3D:
+					samplerParam.type = GST_SAMPLER3D;
+					textureParam.type = GST_TEXTURE3D;
+					break;
+				case GL_SAMPLER_CUBE:
+					samplerParam.type = GST_SAMPLERCUBE;
+					textureParam.type = GST_TEXTURECUBE;
+					break;
+				}
 
-			// Now check for using the word 'uniform' in a larger string & ignore
-			bool inLargerString = false;
-			if (currPos != 0)
-			{
-				char prev = src.at(currPos - 1);
-				if (prev != ' ' && prev != '\t' && prev != '\r' && prev != '\n'
-					&& prev != ';')
-					inLargerString = true;
+				returnParamDesc.samplers.insert(std::make_pair(paramName, samplerParam));
+				returnParamDesc.textures.insert(std::make_pair(paramName, textureParam));
 			}
-			if (!inLargerString && currPos + 7 < src.size())
+			else
 			{
-				char next = src.at(currPos + 7);
-				if (next != ' ' && next != '\t' && next != '\r' && next != '\n')
-					inLargerString = true;
-			}
+				GpuParamMemberDesc gpuParam;
+				gpuParam.name = paramName;
+				
+				GLint blockIndex;
+				glGetActiveUniformsiv(glProgram, 1, &index, GL_UNIFORM_BLOCK_INDEX, &blockIndex);
 
-			// skip 'uniform'
-			currPos += 7;
+				determineParamInfo(gpuParam, paramName, glProgram, index);
 
-			if (!inLargerString)
-			{
-				// find terminating semicolon
-				String::size_type endPos = src.find(";", currPos);
-				if (endPos == String::npos)
+				if(blockIndex != -1)
 				{
-					// problem, missing semicolon, abort
-					break;
+					GLint blockOffset;
+					glGetActiveUniformsiv(glProgram, 1, &index, GL_UNIFORM_OFFSET, &blockOffset);
+					gpuParam.gpuMemOffset = blockOffset;
+
+					GLint arrayStride;
+					glGetActiveUniformsiv(glProgram, 1, &index, GL_UNIFORM_ARRAY_STRIDE, &arrayStride);
+					gpuParam.elementSize = arrayStride;
+
+					gpuParam.paramBlockSlot = blockIndex + 1; // 0 is reserved for globals
+
+					String& blockName = blockSlotToName[gpuParam.paramBlockSlot];
+					GpuParamBlockDesc& curBlockDesc = returnParamDesc.paramBlocks[blockName];
+
+					gpuParam.cpuMemOffset = curBlockDesc.blockSize;
+					curBlockDesc.blockSize += gpuParam.elementSize * gpuParam.arraySize;
 				}
-				line = src.substr(currPos, endPos - currPos);
-
-				// Remove spaces before opening square braces, otherwise
-				// the following split() can split the line at inappropiate
-				// places (e.g. "vec3 something [3]" won't work).
-				for (String::size_type sqp = line.find (" ["); sqp != String::npos;
-					 sqp = line.find (" ["))
-					line.erase (sqp, 1);
-				// Split into tokens
-				std::vector<CamelotEngine::String> parts = StringUtil::split(line, ", \t\r\n");
-
-				for (std::vector<CamelotEngine::String>::iterator i = parts.begin(); i != parts.end(); ++i)
+				else
 				{
-					// Is this a type?
-					StringToEnumMap::iterator typei = mTypeEnumMap.find(*i);
-					if (typei != mTypeEnumMap.end())
-					{
-						completeDefInfo(typei->second, def);
-					}
-					else
-					{
-						// if this is not a type, and not empty, it should be a name
-						StringUtil::trim(*i);
-						if (i->empty()) continue;
-
-						String::size_type arrayStart = i->find("[", 0);
-						if (arrayStart != String::npos)
-						{
-							// potential name (if butted up to array)
-							String name = i->substr(0, arrayStart);
-							StringUtil::trim(name);
-							if (!name.empty())
-								paramName = name;
-
-							String::size_type arrayEnd = i->find("]", arrayStart);
-							String arrayDimTerm = i->substr(arrayStart + 1, arrayEnd - arrayStart - 1);
-							StringUtil::trim(arrayDimTerm);
-							// the array term might be a simple number or it might be
-							// an expression (e.g. 24*3) or refer to a constant expression
-							// we'd have to evaluate the expression which could get nasty
-							// TODO
-							def.arraySize = parseInt(arrayDimTerm);
-
-						}
-						else
-						{
-							paramName = *i;
-							def.arraySize = 1;
-						}
-
-						// Name should be after the type, so complete def and add
-						// We do this now so that comma-separated params will do
-						// this part once for each name mentioned 
-						if (def.constType == GCT_UNKNOWN)
-						{
-							// TODO LOG PORT - Log this somewhere?
-							//LogManager::getSingleton().logMessage(
-							//	"Problem parsing the following GLSL Uniform: '"
-							//	+ line + "' in file " + filename);
-							// next uniform
-							break;
-						}
-
-						if(def.isSampler())
-						{
-							def.physicalIndex = defs.samplerCount;
-							defs.samplerCount++;
-							defs.textureCount++;
-						}
-						else
-						{
-							// Complete def and add
-							// increment physical buffer location
-							def.logicalIndex = 0; // not valid in GLSL
-							if (def.isFloat())
-							{
-								def.physicalIndex = defs.floatBufferSize;
-								defs.floatBufferSize += def.arraySize * def.elementSize;
-							}
-							else
-							{
-								def.physicalIndex = defs.intBufferSize;
-								defs.intBufferSize += def.arraySize * def.elementSize;
-							}
-						}
-						defs.map.insert(GpuConstantDefinitionMap::value_type(paramName, def));
-
-						// Generate array accessors
-						defs.generateConstantDefinitionArrayEntries(paramName, def);
-					}
+					gpuParam.gpuMemOffset = glGetUniformLocationARB(glProgram, uniformName);
+					gpuParam.paramBlockSlot = 0;
+					gpuParam.cpuMemOffset = globalBlockDesc.blockSize;
 
+					globalBlockDesc.blockSize += gpuParam.elementSize * gpuParam.arraySize;
 				}
 
-			} // not commented or a larger symbol
+				returnParamDesc.params.insert(std::make_pair(gpuParam.name, gpuParam));
+			}
+		}
+
+		delete[] uniformName;
+	}
+	//---------------------------------------------------------------------
+	void GLSLLinkProgramManager::determineParamInfo(GpuParamMemberDesc& desc, const String& paramName, GLuint programHandle, GLuint uniformIndex)
+	{
+		GLint arraySize;
+		glGetActiveUniformsiv(programHandle, 1, &uniformIndex, GL_UNIFORM_SIZE, &arraySize);
+		desc.arraySize = arraySize;
 
-			// Find next one
-			currPos = src.find("uniform", currPos);
+		GLint uniformType;
+		glGetActiveUniformsiv(programHandle, 1, &uniformIndex, GL_UNIFORM_TYPE, &uniformType);
 
+		switch (uniformType)
+		{
+		case GL_BOOL:
+			desc.type = GMT_BOOL;
+			desc.elementSize = 1;
+			break;
+		case GL_FLOAT:
+			desc.type = GMT_FLOAT1;
+			desc.elementSize = 1;
+			break;
+		case GL_FLOAT_VEC2:
+			desc.type = GMT_FLOAT2;
+			desc.elementSize = 2;
+			break;
+		case GL_FLOAT_VEC3:
+			desc.type = GMT_FLOAT3;
+			desc.elementSize = 3;
+			break;
+		case GL_FLOAT_VEC4:
+			desc.type = GMT_FLOAT4;
+			desc.elementSize = 4;
+			break;
+		case GL_INT:
+			desc.type = GMT_INT1;
+			desc.elementSize = 1;
+			break;
+		case GL_INT_VEC2:
+			desc.type = GMT_INT2;
+			desc.elementSize = 2;
+			break;
+		case GL_INT_VEC3:
+			desc.type = GMT_INT3;
+			desc.elementSize = 3;
+			break;
+		case GL_INT_VEC4:
+			desc.type = GMT_INT4;
+			desc.elementSize = 4;
+			break;
+		case GL_FLOAT_MAT2:
+			desc.type = GMT_MATRIX_2X2;
+			desc.elementSize = 4;
+			break;
+		case GL_FLOAT_MAT3:
+			desc.type = GMT_MATRIX_3X3;
+			desc.elementSize = 9;
+			break;
+		case GL_FLOAT_MAT4:
+			desc.type = GMT_MATRIX_4X4;
+			desc.elementSize = 16;
+			break;
+		case GL_FLOAT_MAT2x3:
+			desc.type = GMT_MATRIX_2X3;
+			desc.elementSize = 6;
+			break;
+		case GL_FLOAT_MAT3x2:
+			desc.type = GMT_MATRIX_3X2;
+			desc.elementSize = 6;
+			break;
+		case GL_FLOAT_MAT2x4:
+			desc.type = GMT_MATRIX_2X4;
+			desc.elementSize = 8;
+			break;
+		case GL_FLOAT_MAT4x2:
+			desc.type = GMT_MATRIX_4X2;
+			desc.elementSize = 8;
+			break;
+		case GL_FLOAT_MAT3x4:
+			desc.type = GMT_MATRIX_3X4;
+			desc.elementSize = 12;
+			break;
+		case GL_FLOAT_MAT4x3:
+			desc.type = GMT_MATRIX_4X3;
+			desc.elementSize = 12;
+			break;
+		default:
+			CM_EXCEPT(InternalErrorException, "Invalid shader parameter type: " + toString(uniformType) + " for parameter " + paramName);
 		}
-		
 	}
-
 }

+ 33 - 191
CamelotGLRenderer/Source/GLSL/src/CmGLSLProgram.cpp

@@ -41,6 +41,16 @@ THE SOFTWARE.
 #include "CmGLSLProgramRTTI.h"
 
 namespace CamelotEngine {
+
+	class GLSLParamParser
+	{
+	public:
+		GLSLParamParser()
+		{
+
+		}
+	};
+
     //---------------------------------------------------------------------------
     GLSLProgram::~GLSLProgram()
     {
@@ -63,25 +73,32 @@ namespace CamelotEngine {
 		// only create a shader object if glsl is supported
 		if (isSupported())
 		{
-			checkForGLSLError( "GLSLProgram::loadFromSource", "GL Errors before creating shader object", 0 );
+			checkForGLSLError( "GLSLProgram::loadFromSource", "GL Errors before creating shader object", 0, GLSLOT_SHADER);
 			// create shader object
 
 			GLenum shaderType = 0x0000;
 			switch (mType)
 			{
 			case GPT_VERTEX_PROGRAM:
-				shaderType = GL_VERTEX_SHADER_ARB;
+				shaderType = GL_VERTEX_SHADER;
 				break;
 			case GPT_FRAGMENT_PROGRAM:
-				shaderType = GL_FRAGMENT_SHADER_ARB;
+				shaderType = GL_FRAGMENT_SHADER;
 				break;
 			case GPT_GEOMETRY_PROGRAM:
-				shaderType = GL_GEOMETRY_SHADER_EXT;
+				shaderType = GL_GEOMETRY_SHADER;
+				break;
+			case GPT_HULL_PROGRAM:
+				shaderType = GL_TESS_CONTROL_SHADER;
+				break;
+			case GPT_DOMAIN_PROGRAM:
+				shaderType = GL_TESS_EVALUATION_SHADER;
 				break;
 			}
-			mGLHandle = glCreateShaderObjectARB(shaderType);
 
-			checkForGLSLError( "GLSLProgram::loadFromSource", "Error creating GLSL shader object", 0 );
+			mGLHandle = glCreateShader(shaderType);
+
+			checkForGLSLError( "GLSLProgram::loadFromSource", "Error creating GLSL shader object", 0, GLSLOT_SHADER);
 		}
 
 		// Preprocess the GLSL shader in order to get a clean source
@@ -156,9 +173,9 @@ namespace CamelotEngine {
 		if (!mSource.empty())
 		{
 			const char *source = mSource.c_str();
-			glShaderSourceARB(mGLHandle, 1, &source, NULL);
+			glShaderSource(mGLHandle, 1, &source, nullptr);
 			// check for load errors
-			checkForGLSLError( "GLSLProgram::loadFromSource", "Cannot load GLSL high-level shader source : ", 0 );
+			checkForGLSLError( "GLSLProgram::loadFromSource", "Cannot load GLSL high-level shader source : ", 0, GLSLOT_SHADER);
 		}
 
 		compile();
@@ -170,25 +187,24 @@ namespace CamelotEngine {
 	bool GLSLProgram::compile(const bool checkErrors)
 	{
         if (checkErrors)
-        {
-            logObjectInfo("GLSL compiling: ", mGLHandle);
-        }
+            logShaderInfo("GLSL compiling: ", mGLHandle);
+
+		glCompileShader(mGLHandle);
 
-		glCompileShaderARB(mGLHandle);
 		// check for compile errors
-		glGetObjectParameterivARB(mGLHandle, GL_OBJECT_COMPILE_STATUS_ARB, &mCompiled);
+		glGetShaderiv(mGLHandle, GL_COMPILE_STATUS, &mCompiled);
+
 		// force exception if not compiled
 		if (checkErrors)
 		{
-			checkForGLSLError( "GLSLProgram::compile", "Cannot compile GLSL high-level shader : ", mGLHandle, !mCompiled, !mCompiled );
+			checkForGLSLError("GLSLProgram::compile", "Cannot compile GLSL high-level shader : ", mGLHandle, GLSLOT_SHADER, !mCompiled, !mCompiled);
 			
 			if (mCompiled)
 			{
-				logObjectInfo("GLSL compiled : ", mGLHandle);
+				logShaderInfo("GLSL compiled : ", mGLHandle);
 			}
 		}
 		return (mCompiled == 1);
-
 	}
 	//---------------------------------------------------------------------------
 	void GLSLProgram::unload_internal()
@@ -199,128 +215,10 @@ namespace CamelotEngine {
 		mAssemblerProgram = nullptr;
 
 		if (isSupported())
-		{
-			glDeleteObjectARB(mGLHandle);
-		}
+			glDeleteShader(mGLHandle);
 
 		HighLevelGpuProgram::unload_internal();
 	}
-	//-----------------------------------------------------------------------
-	void GLSLProgram::populateParameterNames(GpuProgramParametersSharedPtr params)
-	{
-		getConstantDefinitions_internal();
-		params->_setNamedConstants(mConstantDefs);
-		// Don't set logical / physical maps here, as we can't access parameters by logical index in GLHL.
-	}
-	//-----------------------------------------------------------------------
-	void GLSLProgram::buildConstantDefinitions() const
-	{
-		// We need an accurate list of all the uniforms in the shader, but we
-		// can't get at them until we link all the shaders into a program object.
-
-
-		// Therefore instead, parse the source code manually and extract the uniforms
-		createParameterMappingStructures(true);
-		GLSLLinkProgramManager::instance().extractConstantDefs(
-			mSource, *mConstantDefs.get(), "");
-
-		// Also parse any attached sources
-		for (GLSLProgramContainer::const_iterator i = mAttachedGLSLPrograms.begin();
-			i != mAttachedGLSLPrograms.end(); ++i)
-		{
-			GLSLProgram* childShader = *i;
-
-			GLSLLinkProgramManager::instance().extractConstantDefs(
-				childShader->getSource(), *mConstantDefs.get(), "");
-
-		}
-	}
-	//---------------------------------------------------------------------
-	bool GLSLProgram::getPassSurfaceAndLightStates(void) const
-	{
-		// scenemanager should pass on light & material state to the rendersystem
-		return true;
-	}
-	//---------------------------------------------------------------------
-	bool GLSLProgram::getPassTransformStates(void) const
-	{
-		// scenemanager should pass on transform state to the rendersystem
-		return true;
-	}
-
-	//-----------------------------------------------------------------------
-    void GLSLProgram::attachChildShader(const String& name)
-	{
-		// is the name valid and already loaded?
-		// check with the high level program manager to see if it was loaded
-		// TODO PORT - I'm not sure what is this for but I don't support it
-		//HighLevelGpuProgramPtr hlProgram = HighLevelGpuProgramManager::getSingleton().getByName(name);
-		//if (!hlProgram.isNull())
-		//{
-		//	if (hlProgram->getSyntaxCode() == "glsl")
-		//	{
-		//		// make sure attached program source gets loaded and compiled
-		//		// don't need a low level implementation for attached shader objects
-		//		// loadHighLevelImpl will only load the source and compile once
-		//		// so don't worry about calling it several times
-		//		GLSLProgram* childShader = static_cast<GLSLProgram*>(hlProgram.getPointer());
-		//		// load the source and attach the child shader only if supported
-		//		if (isSupported())
-		//		{
-		//			childShader->loadHighLevelImpl();
-		//			// add to the container
-		//			mAttachedGLSLPrograms.push_back( childShader );
-		//			mAttachedShaderNames += name + " ";
-		//		}
-		//	}
-		//}
-	}
-
-	//-----------------------------------------------------------------------
-	void GLSLProgram::attachToProgramObject( const GLhandleARB programObject )
-	{
-		// attach child objects
-		GLSLProgramContainerIterator childprogramcurrent = mAttachedGLSLPrograms.begin();
-		GLSLProgramContainerIterator childprogramend = mAttachedGLSLPrograms.end();
-
- 		while (childprogramcurrent != childprogramend)
-		{
-
-			GLSLProgram* childShader = *childprogramcurrent;
-			// bug in ATI GLSL linker : modules without main function must be recompiled each time 
-			// they are linked to a different program object
-			// don't check for compile errors since there won't be any
-			// *** minor inconvenience until ATI fixes there driver
-			childShader->compile(false);
-
-			childShader->attachToProgramObject( programObject );
-
-			++childprogramcurrent;
-		}
-		glAttachObjectARB( programObject, mGLHandle );
-		checkForGLSLError( "GLSLProgram::attachToProgramObject",
-			"Error attaching shader object to GLSL Program Object", programObject );
-
-	}
-	//-----------------------------------------------------------------------
-	void GLSLProgram::detachFromProgramObject( const GLhandleARB programObject )
-	{
-		glDetachObjectARB(programObject, mGLHandle);
-		checkForGLSLError( "GLSLProgram::detachFromProgramObject",
-			"Error detaching shader object from GLSL Program Object", programObject );
-		// attach child objects
-		GLSLProgramContainerIterator childprogramcurrent = mAttachedGLSLPrograms.begin();
-		GLSLProgramContainerIterator childprogramend = mAttachedGLSLPrograms.end();
-
-		while (childprogramcurrent != childprogramend)
-		{
-			GLSLProgram* childShader = *childprogramcurrent;
-			childShader->detachFromProgramObject( programObject );
-			++childprogramcurrent;
-		}
-
-	}
-
     //-----------------------------------------------------------------------
     const String& GLSLProgram::getLanguage(void) const
     {
@@ -341,60 +239,4 @@ namespace CamelotEngine {
 	{
 		return GLSLProgram::getRTTIStatic();
 	}
-
-	//-----------------------------------------------------------------------
-	RenderOperation::OperationType parseOperationType(const String& val)
-	{
-		if (val == "point_list")
-		{
-			return RenderOperation::OT_POINT_LIST;
-		}
-		else if (val == "line_list")
-		{
-			return RenderOperation::OT_LINE_LIST;
-		}
-		else if (val == "line_strip")
-		{
-			return RenderOperation::OT_LINE_STRIP;
-		}
-		else if (val == "triangle_strip")
-		{
-			return RenderOperation::OT_TRIANGLE_STRIP;
-		}
-		else if (val == "triangle_fan")
-		{
-			return RenderOperation::OT_TRIANGLE_FAN;
-		}
-		else 
-		{
-			//Triangle list is the default fallback. Keep it this way?
-			return RenderOperation::OT_TRIANGLE_LIST;
-		}
-	}
-	//-----------------------------------------------------------------------
-	String operationTypeToString(RenderOperation::OperationType val)
-	{
-		switch (val)
-		{
-		case RenderOperation::OT_POINT_LIST:
-			return "point_list";
-			break;
-		case RenderOperation::OT_LINE_LIST:
-			return "line_list";
-			break;
-		case RenderOperation::OT_LINE_STRIP:
-			return "line_strip";
-			break;
-		case RenderOperation::OT_TRIANGLE_STRIP:
-			return "triangle_strip";
-			break;
-		case RenderOperation::OT_TRIANGLE_FAN:
-			return "triangle_fan";
-			break;
-		case RenderOperation::OT_TRIANGLE_LIST:
-		default:
-			return "triangle_list";
-			break;
-		}
-	}
 }

+ 0 - 71
CamelotGLRenderer/Source/atifs/include/ATI_FS_GLGpuProgram.h

@@ -1,71 +0,0 @@
-/*
------------------------------------------------------------------------------
-This source file is part of OGRE
-(Object-oriented Graphics Rendering Engine)
-For the latest info, see http://www.ogre3d.org/
-
-Copyright (c) 2000-2011 Torus Knot Software Ltd
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
------------------------------------------------------------------------------
-*/
-
-#ifndef __ATI_FS_GLGpuProgram_H__
-#define __ATI_FS_GLGpuProgram_H__
-
-#include "CmGLPrerequisites.h"
-#include "CmGLGpuProgram.h"
-
-namespace CamelotEngine {
-
-	/** Specialisation of the GL low-level program for ATI Fragment Shader programs. */
-	class CM_RSGL_EXPORT ATI_FS_GLGpuProgram : public GLGpuProgram
-	{
-	public:
-		virtual ~ATI_FS_GLGpuProgram();
-
-
-		/// Execute the binding functions for this program
-		void bindProgram(void);
-		/// Execute the unbinding functions for this program
-		void unbindProgram(void);
-		/// Execute the param binding functions for this program
-		void bindProgramParameters(GpuProgramParametersSharedPtr params, UINT16 mask);
-
-		/// Get the assigned GL program id
-		const GLuint getProgramID(void) const
-		{ return mProgramID; }
-
-	protected:
-		friend GpuProgram* createGL_ATI_FS_GpuProgram(const String& source, const String& entryPoint, const String& language, GpuProgramType gptype, GpuProgramProfile profile);
-
-		ATI_FS_GLGpuProgram(const String& source, const String& entryPoint, const String& language, 
-			GpuProgramType gptype, GpuProgramProfile profile, bool isAdjacencyInfoRequired = false);
-
-		/// @copydoc Resource::unload
-		void unloadImpl(void);
-		void loadFromSource(void);
-
-	}; // class ATI_FS_GLGpuProgram
-
-
-
-}; // namespace CamelotEngine
-
-#endif // __ATI_FS_GLGpuProgram_H__

+ 0 - 280
CamelotGLRenderer/Source/atifs/include/Compiler2Pass.h

@@ -1,280 +0,0 @@
-/*
------------------------------------------------------------------------------
-This source file is part of OGRE
-(Object-oriented Graphics Rendering Engine)
-For the latest info, see http://www.ogre3d.org/
-
-Copyright (c) 2000-2011 Torus Knot Software Ltd
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
------------------------------------------------------------------------------
-*/
-
-
-#ifndef COMPILER2PASS_H
-#define COMPILER2PASS_H
-
-#include <vector>
-
-#ifdef _WIN32
-#define WIN32_LEAN_AND_MEAN
-#if !defined(NOMINMAX) && defined(_MSC_VER)
-#	define NOMINMAX // required to stop windows.h messing up std::min
-#endif
-#include <windows.h>
-#endif
-
-// FIX ME - should not be hard coded
-#define BAD_TOKEN 999
-
-typedef unsigned int UINT32;
-
-
-
-/** Compiler2Pass is a generic compiler/assembler
-@remarks
-	provides a tokenizer in pass 1 and relies on the subclass to provide the virtual method for pass 2
-
-	PASS 1 - tokenize source: this is a simple brute force lexical scanner/analyzer that also parses
-			 the formed token for proper semantics and context in one pass
-			 it uses Look Ahead Left-Right (LALR) ruling based on Backus - Naur From notation for semantic
-			 checking and also performs	context checking allowing for language dialects
-
-	PASS 2 - generate application specific instructions ie native instructions
-
-@par
-	this class must be subclassed with the subclass providing implementation for Pass 2.  The subclass
-	is responsible for setting up the token libraries along with defining the language syntax.
-
-*/
-class Compiler2Pass {
-
-protected:
-
-	// BNF operation types
-	enum OperationType {otRULE, otAND, otOR, otOPTIONAL, otREPEAT, otEND};
-
-	/** structure used to build rule paths
-
-	*/
-	struct TokenRule {
-		OperationType mOperation;
-		UINT32 mTokenID;
-		const char* mSymbol;
-		UINT32 mErrorID;
-
-	};
-
-	/** structure used to build Symbol Type library */
-	struct SymbolDef {
-	  UINT32 mID;					// Token ID which is the index into the Token Type library
-	  UINT32 mPass2Data;			// data used by pass 2 to build native instructions
-
-	  UINT32 mContextKey;			// context key to fit the Active Context
-	  UINT32 mContextPatternSet;	// new pattern to set for Active Context bits
-	  UINT32 mContextPatternClear;// Contexts bits to clear Active Context bits
-
-	  int mDefTextID;			// index into text table for default name : set at runtime
-	  UINT32 mRuleID;				// index into Rule database for non-terminal toke rulepath
-								// if RuleID is zero the token is terminal
-
-	};
-
-
-	/** structure for Token instructions */
-	struct TokenInst {
-	  UINT32 mNTTRuleID;			// Non-Terminal Token Rule ID that generated Token
-	  UINT32 mID;					// Token ID
-	  int mLine;				// line number in source code where Token was found
-	  size_t mPos;					// Character position in source where Token was found
-
-	};
-
-	typedef std::vector<TokenInst> TokenInstContainer;
-	//typedef TokenInstContainer::iterator TokenInstIterator;
-
-	/// container for Tokens extracted from source
-	TokenInstContainer mTokenInstructions;
-
-	/// pointer to the source to be compiled
-	const char* mSource;
-	int mEndOfSource;
-
-	/// pointers to Text and Token Type libraries setup by subclass
-	SymbolDef* mSymbolTypeLib;
-
-	/// pointer to root rule path - has to be set by subclass constructor
-	TokenRule* mRootRulePath;
-
-	/// number of entries in Text and Token Type libraries
-	int mRulePathLibCnt;
-	int mSymbolTypeLibCnt;
-
-	/// mVauleID needs to be initialized by the subclass before compiling occurs
-	/// it defines the token ID used in the symbol type library
-	UINT32 mValueID;
-
-
-	/// storage container for constants defined in source
-	std::vector<float> mConstants;
-
-	/// Active Contexts pattern used in pass 1 to determine which tokens are valid for a certain context
-	UINT32 mActiveContexts;
-
-	/** check token semantics between ID1 and ID2 using left/right semantic data in Token Type library
-	@param ID1 token ID on the left
-	@param ID2 token ID on the right
-	@return
-		true if both will bind to each other
-		false if either fails the semantic bind test
-
-	*/
-	//bool checkTokenSemantics(UINT32 ID1, UINT32 ID2);
-
-	/** perform pass 1 of compile process
-		scans source for symbols that can be tokenized and then
-		performs general semantic and context verification on each symbol before it is tokenized.
-		A tokenized instruction list is built to be used by Pass 2.
-
-	*/
-	bool doPass1();
-
-	/** pure virtual method that must be set up by subclass to perform Pass 2 of compile process
-	@remark
-		Pass 2 is for the subclass to take the token instructions generated in Pass 1 and
-		build the application specific instructions along with verifying
-		symantic and context rules that could not be checked in Pass 1
-
-	*/
-	virtual bool doPass2() = 0;
-
-	void findEOL();
-
-	/** get the text symbol for this token
-	@remark
-		mainly used for debugging and in test routines
-	@param sid is the token ID
-	@return a pointer to the string text
-	*/
-	const char* getTypeDefText(const UINT32 sid);
-
-	/** check to see if the text at the present position in the source is a numerical constant
-	@param fvalue is a reference that will receive the float value that is in the source
-	@param charsize reference to receive number of characters that make of the value in the source
-	@return
-		true if characters form a valid float representation
-		false if a number value could not be extracted
-	*/
-	bool isFloatValue(float & fvalue, size_t & charsize);
-
-	/** check to see if the text is in the symbol text library
-	@param symbol points to begining of text where a symbol token might exist
-	@param symbolsize reference that will receive the size value of the symbol found
-	@return
-		true if a matching token could be found in the token type library
-		false if could not be tokenized
-	*/
-	bool isSymbol(const char* symbol, size_t & symbolsize);
-
-
-	/// position to the next possible valid sysmbol
-	bool positionToNextSymbol();
-
-
-	/** process input source text using rulepath to determine allowed tokens
-	@remarks
-		the method is reentrant and recursive
-		if a non-terminal token is encountered in the current rule path then the method is
-		called using the new rule path referenced by the non-terminal token
-		Tokens can have the following operation states which effects the flow path of the rule
-			RULE: defines a rule path for the non-terminal token
-			AND: the token is required for the rule to pass
-			OR: if the previous tokens failed then try these ones
-			OPTIONAL: the token is optional and does not cause the rule to fail if the token is not found
-			REPEAT: the token is required but there can be more than one in a sequence
-			END: end of the rule path - the method returns the succuss of the rule
-
-	@param rulepathIDX index into to array of Token Rules that define a rule path to be processed
-	@return
-		true if rule passed - all required tokens found
-		false if one or more tokens required to complete the rule were not found
-	*/
-	bool processRulePath( UINT32 rulepathIDX);
-
-
-	// setup ActiveContexts - should be called by subclass to setup initial language contexts
-	void setActiveContexts(const UINT32 contexts){ mActiveContexts = contexts; }
-
-
-	/// comment specifiers are hard coded
-	void skipComments();
-
-	/// find end of line marker and move past it
-	void skipEOL();
-
-	/// skip all the white space which includes spaces and tabs
-	void skipWhiteSpace();
-
-
-	/** check if current position in source has the symbol text equivalent to the TokenID
-	@param rulepathIDX index into rule path database of token to validate
-	@param activeRuleID index of non-terminal rule that generated the token
-	@return
-		true if token was found
-		false if token symbol text does not match the source text
-		if token is non-terminal then processRulePath is called
-	*/
-	bool ValidateToken(const UINT32 rulepathIDX, const UINT32 activeRuleID);
-
-
-public:
-	// ** these probably should not be public
-	int mCurrentLine;
-	size_t mCharPos;
-
-
-	/// constructor
-	Compiler2Pass();
-    virtual ~Compiler2Pass() {}
-	/** compile the source - performs 2 passes
-		first pass is to tokinize, check semantics and context
-		second pass is performed by subclass and converts tokens to application specific instructions
-	@remark
-		Pass 2 only gets executed if Pass 1 has no errors
-	@param source a pointer to the source text to be compiled
-	@return
-		true if Pass 1 and Pass 2 are successfull
-		false if any errors occur in Pass 1 or Pass 2
-	*/
-	bool compile(const char* source);
-
-	/** Initialize the type library with matching symbol text found in symbol text library
-		find a default text for all Symbol Types in library
-
-		scan through all the rules and initialize TypeLib with index to text and index to rules for non-terminal tokens
-
-		must be called by subclass after libraries and rule database setup
-	*/
-
-	void InitSymbolTypeLib();
-
-};
-
-#endif
-

+ 0 - 367
CamelotGLRenderer/Source/atifs/include/ps_1_4.h

@@ -1,367 +0,0 @@
-/*
------------------------------------------------------------------------------
-This source file is part of OGRE
-(Object-oriented Graphics Rendering Engine)
-For the latest info, see http://www.ogre3d.org/
-
-Copyright (c) 2000-2011 Torus Knot Software Ltd
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
------------------------------------------------------------------------------
-*/
-
-
-/**
-	A number of invaluable references were used to put together this ps.1.x compiler for ATI_fragment_shader execution
-
-	References:
-		1. MSDN: DirectX 8.1 Reference
-		2. Wolfgang F. Engel "Fundamentals of Pixel Shaders - Introduction to Shader Programming Part III" on gamedev.net
-		3. Martin Ecker - XEngine
-		4. Shawn Kirst - ps14toATIfs
-		5. Jason L. Mitchell "float-Time 3D Graphics With Pixel Shaders" 
-		6. Jason L. Mitchell "1.4 Pixel Shaders"
-		7. Jason L. Mitchell and Evan Hart "Hardware Shading with EXT_vertex_shader and ATI_fragment_shader"
-		6. ATI 8500 SDK
-		7. GL_ATI_fragment_shader extension reference
-
-*/
-//---------------------------------------------------------------------------
-#ifndef ps_1_4H
-#define ps_1_4H
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "CmGLPrerequisites.h"
-#include "Compiler2Pass.h"
-
-
-//---------------------------------------------------------------------------
-// macro to get the size of a static array
-#undef ARRAYSIZE
-#define ARRAYSIZE(array) (sizeof(array)/sizeof(array[0]))
-
-#define ALPHA_BIT 0x08
-#define RGB_BITS 0x07
-
-// Context key patterns
-#define ckp_PS_BASE 0x1
-#define ckp_PS_1_1  0x2
-#define ckp_PS_1_2  0x4
-#define ckp_PS_1_3  0x8
-#define ckp_PS_1_4  0x10
-
-#define ckp_PS_1_4_BASE (ckp_PS_BASE + ckp_PS_1_4)
-
-
-
-
-/** Subclasses Compiler2Pass to provide a ps_1_x compiler that takes DirectX pixel shader assembly
-	and converts it to a form that can be used by ATI_fragment_shader OpenGL API
-@remarks
-	all ps_1_1, ps_1_2, ps_1_3, ps_1_4 assembly instructions are recognized but not all are passed
-	on to ATI_fragment_shader.	ATI_fragment_shader does not have an equivelant directive for
-	texkill or texdepth instructions.
-
-	The user must provide the GL binding interfaces.
-
-	A Test method is provided to verify the basic operation of the compiler which outputs the test
-	results to a file.
-
-
-*/
-class PS_1_4 : public Compiler2Pass{
-private:
-	enum RWAflags {rwa_NONE = 0, rwa_READ = 1, rwa_WRITE = 2};
-
-	enum MachineInstID {mi_COLOROP1, mi_COLOROP2, mi_COLOROP3, mi_ALPHAOP1, mi_ALPHAOP2,
-						mi_ALPHAOP3, mi_SETCONSTANTS, mi_PASSTEXCOORD, mi_SAMPLEMAP, mi_TEX,
-						mi_TEXCOORD, mi_TEXREG2RGB, mi_NOP
-	};
-
-	struct  TokenInstType{
-	  char* Name;
-	  GLuint ID;
-
-	};
-
-	struct RegisterUsage {
-		bool Phase1Write;
-		bool Phase2Write;
-	};
-
-	// Token ID enumeration
-	enum SymbolID {
-		// Terminal Tokens section
-
-		// DirectX pixel shader source formats 
-		sid_PS_1_4, sid_PS_1_1, sid_PS_1_2, sid_PS_1_3,
-					
-		// PS_BASE
-		sid_C0, sid_C1, sid_C2, sid_C3, sid_C4, sid_C5, sid_C6, sid_C7,
-		sid_V0, sid_V1,
-		sid_ADD, sid_SUB, sid_MUL, sid_MAD, sid_LRP, sid_MOV, sid_CMP, sid_CND,
-		sid_DP3, sid_DP4, sid_DEF,
-		sid_R, sid_RA, sid_G, sid_GA, sid_B, sid_BA, sid_A, sid_RGBA, sid_RGB,
-		sid_RG, sid_RGA, sid_RB, sid_RBA, sid_GB, sid_GBA,
-		sid_RRRR, sid_GGGG, sid_BBBB, sid_AAAA,
-		sid_X2, sid_X4, sid_D2, sid_SAT,
-		sid_BIAS, sid_INVERT, sid_NEGATE, sid_BX2,
-		sid_COMMA, sid_VALUE,
-
-		//PS_1_4 sid
-		sid_R0, sid_R1, sid_R2, sid_R3, sid_R4, sid_R5,
-		sid_T0, sid_T1, sid_T2, sid_T3, sid_T4, sid_T5,
-		sid_DP2ADD,
-		sid_X8, sid_D8, sid_D4,
-		sid_TEXCRD, sid_TEXLD,
-		sid_STR, sid_STQ,
-		sid_STRDR, sid_STQDQ,
-		sid_BEM,
-		sid_PHASE,
-
-		//PS_1_1 sid
-		sid_1R0, sid_1R1, sid_1T0, sid_1T1, sid_1T2, sid_1T3,
-		sid_TEX, sid_TEXCOORD, sid_TEXM3X2PAD,
-		sid_TEXM3X2TEX, sid_TEXM3X3PAD, sid_TEXM3X3TEX, sid_TEXM3X3SPEC, sid_TEXM3X3VSPEC,
-		sid_TEXREG2AR, sid_TEXREG2GB,
-		
-		//PS_1_2 side
-		sid_TEXREG2RGB, sid_TEXDP3, sid_TEXDP3TEX,
-
-		// common
-		sid_SKIP, sid_PLUS,
-
-		// non-terminal tokens section
-		sid_PROGRAM, sid_PROGRAMTYPE, sid_DECLCONSTS, sid_DEFCONST,
-		sid_CONSTANT, sid_COLOR,
-		sid_TEXSWIZZLE, sid_UNARYOP,
-		sid_NUMVAL, sid_SEPERATOR, sid_ALUOPS, sid_TEXMASK, sid_TEXOP_PS1_1_3,
-		sid_TEXOP_PS1_4,
-		sid_ALU_STATEMENT, sid_DSTMODSAT, sid_UNARYOP_ARGS, sid_REG_PS1_4,
-		sid_TEX_PS1_4, sid_REG_PS1_1_3, sid_TEX_PS1_1_3, sid_DSTINFO,
-		sid_SRCINFO, sid_BINARYOP_ARGS, sid_TERNARYOP_ARGS, sid_TEMPREG,
-		sid_DSTMASK, sid_PRESRCMOD, sid_SRCNAME, sid_SRCREP, sid_POSTSRCMOD,
-		sid_DSTMOD, sid_DSTSAT, sid_BINARYOP,  sid_TERNARYOP,
-		sid_TEXOPS_PHASE1, sid_COISSUE, sid_PHASEMARKER, sid_TEXOPS_PHASE2, 
-		sid_TEXREG_PS1_4, sid_TEXOPS_PS1_4, sid_TEXOPS_PS1_1_3, sid_TEXCISCOP_PS1_1_3,
-
-
-		// last token
-		sid_INVALID = BAD_TOKEN // must be last in enumeration
-	};
-
-	/// structure used to keep track of arguments and instruction parameters
-	struct OpParram {
-	  GLuint Arg;		// type of argument
-	  bool Filled;		// has it been filled yet
-	  GLuint MaskRep;	// Mask/Replicator flags
-	  GLuint Mod;		// argument modifier
-	};
-
-	typedef std::vector<UINT32> MachineInstContainer;
-	//typedef MachineInstContainer::iterator MachineInstIterator;
-
-
-	// there are 2 phases with 2 subphases each
-	enum PhaseType {ptPHASE1TEX, ptPHASE1ALU, ptPHASE2TEX, ptPHASE2ALU };
-
-	struct RegModOffset {
-		UINT32 MacroOffset;
-		UINT32 RegisterBase;
-		UINT32 OpParramsIndex;
-	};
-
-	struct MacroRegModify {
-		TokenInst *		Macro;
-		UINT32			MacroSize;
-		RegModOffset *	RegMods;
-		UINT32			RegModSize;
-
-	};
-
-	#define R_BASE  (sid_R0 - GL_REG_0_ATI)
-	#define C_BASE  (sid_C0 - GL_CON_0_ATI)
-	#define T_BASE  (sid_1T0 - GL_REG_0_ATI)
-
-	// static library database for tokens and BNF rules
-	static SymbolDef PS_1_4_SymbolTypeLib[];
-	static TokenRule PS_1_x_RulePath[];
-	static bool LibInitialized;
-
-	// Static Macro database for ps.1.1 ps.1.2 ps.1.3 instructions
-
-	static TokenInst texreg2ar[];
-	static RegModOffset texreg2xx_RegMods[];
-	static MacroRegModify texreg2ar_MacroMods;
-
-	static TokenInst texreg2gb[];
-	static MacroRegModify texreg2gb_MacroMods;
-
-	static TokenInst texdp3[];
-	static RegModOffset texdp3_RegMods[];
-	static MacroRegModify texdp3_MacroMods;
-
-	static TokenInst texdp3tex[];
-	static RegModOffset texdp3tex_RegMods[];
-	static MacroRegModify texdp3tex_MacroMods;
-
-	static TokenInst texm3x2pad[];
-	static RegModOffset texm3xxpad_RegMods[];
-	static MacroRegModify texm3x2pad_MacroMods;
-
-	static TokenInst texm3x2tex[];
-	static RegModOffset texm3xxtex_RegMods[];
-	static MacroRegModify texm3x2tex_MacroMods;
-
-	static TokenInst texm3x3pad[];
-	static MacroRegModify texm3x3pad_MacroMods;
-
-	static TokenInst texm3x3tex[];
-	static MacroRegModify texm3x3tex_MacroMods;
-
-	static TokenInst texm3x3spec[];
-	static RegModOffset texm3x3spec_RegMods[];
-	static MacroRegModify texm3x3spec_MacroMods;
-
-	static TokenInst texm3x3vspec[];
-	static RegModOffset texm3x3vspec_RegMods[];
-	static MacroRegModify texm3x3vspec_MacroMods;
-
-
-	MachineInstContainer mPhase1TEX_mi; /// machine instructions for phase one texture section
-	MachineInstContainer mPhase1ALU_mi; /// machine instructions for phase one ALU section
-	MachineInstContainer mPhase2TEX_mi; /// machine instructions for phase two texture section
-	MachineInstContainer mPhase2ALU_mi; /// machine instructions for phase two ALU section
-
-	MachineInstContainer* mActivePhaseMachineInstructions;
-	// vars used during pass 2
-	MachineInstID mOpType;
-	UINT32 mOpInst;
-	bool mDo_Alpha;
-	PhaseType mInstructionPhase;
-	int mArgCnt;
-	int mConstantsPos;
-
-	#define MAXOPPARRAMS 5 // max number of parrams bound to an instruction
-	
-	OpParram mOpParrams[MAXOPPARRAMS];
-
-	/// keeps track of which registers are written to in each phase
-	/// if a register is read from but has not been written to in phase 2
-	/// then if it was written to in phase 1 perform a register pass function
-	/// at the begining of phase2 so that the register has something worthwhile in it
-	/// NB: check ALU and TEX section of phase 1 and phase 2
-	/// there are 6 temp registers r0 to r5 to keep track off
-	/// checks are performed in pass 2 when building machine instructions
-	RegisterUsage Phase_RegisterUsage[6];
-
-	bool mMacroOn; // if true then put all ALU instructions in phase 1
-
-	UINT32 mTexm3x3padCount; // keep track of how many texm3x3pad instructions are used so know which mask to use
-
-	size_t mLastInstructionPos; // keep track of last phase 2 ALU instruction to check for R0 setting
-	size_t mSecondLastInstructionPos;
-
-	// keep track if phase marker found: determines which phase the ALU instructions go into
-	bool mPhaseMarkerFound; 
-
-#ifdef _DEBUG
-	FILE* fp;
-	// full compiler test with output results going to a text file
-	void testCompile(char* testname, char* teststr, SymbolID* testresult,
-		UINT32 testresultsize, GLuint* MachinInstResults = NULL, UINT32 MachinInstResultsSize = 0);
-#endif // _DEBUG
-
-
-	/** attempt to build a machine instruction using current tokens
-		determines what phase machine insturction should be in and if an Alpha Op is required
-		calls expandMachineInstruction() to expand the token into machine instructions
-	*/
-	bool BuildMachineInst();
-	
-	void clearMachineInstState();
-
-	bool setOpParram(const SymbolDef* symboldef);
-
-	/** optimizes machine instructions depending on pixel shader context
-		only applies to ps.1.1 ps.1.2 and ps.1.3 since they use CISC instructions
-		that must be transformed into RISC instructions
-	*/
-	void optimize();
-
-	// the method is expected to be recursive to allow for inline expansion of instructions if required
-	bool Pass2scan(const TokenInst * Tokens, const size_t size);
-
-	// supply virtual functions for Compiler2Pass
-	/// Pass 1 is completed so now take tokens generated and build machine instructions
-	bool doPass2();
-
-	/** Build a machine instruction from token and ready it for expansion
-		will expand CISC tokens using macro database
-
-	*/
-	bool bindMachineInstInPassToFragmentShader(const MachineInstContainer & PassMachineInstructions);
-
-	/** Expand CISC tokens into PS1_4 token equivalents
-
-	*/
-	bool expandMacro(const MacroRegModify & MacroMod);
-
-	/** Expand Machine instruction into operation type and arguments and put into proper machine
-		instruction container
-		also expands scaler alpha machine instructions if required
-
-	*/
-	bool expandMachineInstruction();
-
-	// mainly used by tests - too slow for use in binding
-	size_t getMachineInst(size_t Idx);
-
-	size_t getMachineInstCount();
-
-	void addMachineInst(PhaseType phase, const UINT32 inst);
-
-	void clearAllMachineInst();
-
-	void updateRegisterWriteState(const PhaseType phase);
-
-	bool isRegisterReadValid(const PhaseType phase, const int param);
-
-public:
-
-	/// constructor
-	PS_1_4();
-
-	/// binds machine instructions generated in Pass 2 to the ATI GL fragment shader
-	bool bindAllMachineInstToFragmentShader();
-
-#ifdef _DEBUG
-	/// perform compiler tests - only available in _DEBUG mode
-	void test();
-	void testbinder();
-
-#endif
-};
-
-
-#endif
-

+ 0 - 137
CamelotGLRenderer/Source/atifs/src/ATI_FS_GLGpuProgram.cpp

@@ -1,137 +0,0 @@
-/*
------------------------------------------------------------------------------
-This source file is part of OGRE
-(Object-oriented Graphics Rendering Engine)
-For the latest info, see http://www.ogre3d.org/
-
-Copyright (c) 2000-2011 Torus Knot Software Ltd
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
------------------------------------------------------------------------------
-*/
-
-#include "ps_1_4.h"
-#include "CmException.h"
-#include "CmRenderSystem.h"
-#include "CmRenderSystemCapabilities.h"
-#include "ATI_FS_GLGpuProgram.h"
-
-using namespace CamelotEngine;
-
-
-ATI_FS_GLGpuProgram::ATI_FS_GLGpuProgram(const String& source, const String& entryPoint, const String& language, 
-										 GpuProgramType gptype, GpuProgramProfile profile, bool isAdjacencyInfoRequired) 
-										 :GLGpuProgram(source, entryPoint, language, gptype, profile, isAdjacencyInfoRequired)
-{
-	mProgramType = GL_FRAGMENT_SHADER_ATI;
-    mProgramID = glGenFragmentShadersATI(1);
-}
-
-ATI_FS_GLGpuProgram::~ATI_FS_GLGpuProgram()
-{
-    // have to call this here reather than in Resource destructor
-    // since calling virtual methods in base destructors causes crash
-    unload_internal(); 
-}
-
-void ATI_FS_GLGpuProgram::bindProgram(void)
-{
-	glEnable(mProgramType);
-	glBindFragmentShaderATI(mProgramID);
-}
-
-void ATI_FS_GLGpuProgram::unbindProgram(void)
-{
-	glDisable(mProgramType);
-}
-
-
-void ATI_FS_GLGpuProgram::bindProgramParameters(GpuProgramParametersSharedPtr params, CamelotEngine::UINT16 mask)
-{
-	// only supports float constants
-	GpuLogicalBufferStructPtr floatStruct = params->getFloatLogicalBufferStruct();
-
-	for (GpuLogicalIndexUseMap::const_iterator i = floatStruct->map.begin();
-		i != floatStruct->map.end(); ++i)
-	{
-		if (i->second.variability & mask)
-		{
-			UINT32 logicalIndex = i->first;
-			const float* pFloat = params->getFloatPointer(i->second.physicalIndex);
-			// Iterate over the params, set in 4-float chunks (low-level)
-			for (UINT32 j = 0; j < i->second.currentSize; j+=4)
-			{
-				glSetFragmentShaderConstantATI(GL_CON_0_ATI + logicalIndex, pFloat);
-				pFloat += 4;
-				++logicalIndex;
-			}
-		}
-	}
-
-}
-
-void ATI_FS_GLGpuProgram::unloadImpl(void)
-{
-	glDeleteFragmentShaderATI(mProgramID);
-}
-
-
-void ATI_FS_GLGpuProgram::loadFromSource(void)
-{
-
-    PS_1_4 PS1_4Assembler;
-	// attempt to compile the source
-#ifdef _DEBUG
-	PS1_4Assembler.test(); // run compiler tests in debug mode
-#endif
-
-    bool Error = !PS1_4Assembler.compile(mSource.c_str());
-
-    if(!Error) { 
-		glBindFragmentShaderATI(mProgramID);
-		glBeginFragmentShaderATI();
-			// compile was successfull so send the machine instructions thru GL to GPU
-			Error = !PS1_4Assembler.bindAllMachineInstToFragmentShader();
-        glEndFragmentShaderATI();
-
-		// check GL for GPU machine instruction bind erros
-		if (Error)
-		{
-			CM_EXCEPT(InternalErrorException, 
-				"Cannot Bind ATI fragment shader :"); 
-		}
-
-    }
-    else
-	{
-		// an error occured when compiling the ps_1_4 source code
-		char buff[50];
-        sprintf_s(buff, 50, "error on line %d in pixel shader source\n", PS1_4Assembler.mCurrentLine);
-
-		// TODO LOG PORT - Log this somewhere
-		//LogManager::getSingleton().logMessage("Warning: atifs compiler reported the following errors:");
-		//LogManager::getSingleton().logMessage(buff + mName);
-
-		CM_EXCEPT(InternalErrorException, 
-			String("Cannot Compile ATI fragment shader : \n\n") + buff);// + 
-    }
-
-
-}
-

+ 0 - 379
CamelotGLRenderer/Source/atifs/src/Compiler2Pass.cpp

@@ -1,379 +0,0 @@
-/*
------------------------------------------------------------------------------
-This source file is part of OGRE
-(Object-oriented Graphics Rendering Engine)
-For the latest info, see http://www.ogre3d.org/
-
-Copyright (c) 2000-2011 Torus Knot Software Ltd
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
------------------------------------------------------------------------------
-*/
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "Compiler2Pass.h"
-
-Compiler2Pass::Compiler2Pass()
-{
-	// reserve some memory space in the containers being used
-	mTokenInstructions.reserve(100);
-	mConstants.reserve(80);
-	// default contexts allows all contexts
-	// subclass should change it to fit the language being compiled
-	mActiveContexts = 0xffffffff;
-
-}
-
-
-
-void Compiler2Pass::InitSymbolTypeLib()
-{
-	UINT32 token_ID;
-	// find a default text for all Symbol Types in library
-
-	// scan through all the rules and initialize TypeLib with index to text and index to rules for non-terminal tokens
-	for(int i = 0; i < mRulePathLibCnt; i++) {
-		token_ID = mRootRulePath[i].mTokenID;
-		// make sure SymbolTypeLib holds valid token
-		assert(mSymbolTypeLib[token_ID].mID == token_ID);
-		switch(mRootRulePath[i].mOperation) {
-			case otRULE:
-				// if operation is a rule then update typelib
-				mSymbolTypeLib[token_ID].mRuleID = i;
-
-			case otAND:
-			case otOR:
-			case otOPTIONAL:
-				// update text index in typelib
-				if (mRootRulePath[i].mSymbol != NULL) mSymbolTypeLib[token_ID].mDefTextID = i;
-				break;
-            case otREPEAT:
-            case otEND:
-                break;
-		}
-	}
-
-}
-
-
-bool Compiler2Pass::compile(const char* source)
-{
-	bool Passed = false;
-
-	mSource = source;
-	// start compiling if there is a rule base to work with
-	if(mRootRulePath != NULL) {
-		 Passed = doPass1();
-
-		if(Passed) {
-			Passed = doPass2();
-		}
-	}
-	return Passed;
-}
-
-
-bool Compiler2Pass::doPass1()
-{
-	// scan through Source string and build a token list using TokenInstructions
-	// this is a simple brute force lexical scanner/analyzer that also parses the formed
-	// token for proper semantics and context in one pass
-
-	mCurrentLine = 1;
-	mCharPos = 0;
-	// reset position in Constants container
-	mConstants.clear();
-	mEndOfSource = (int)strlen(mSource);
-
-	// start with a clean slate
-	mTokenInstructions.clear();
-	// tokenize and check semantics untill an error occurs or end of source is reached
-	// assume RootRulePath has pointer to rules so start at index + 1 for first rule path
-	// first rule token would be a rule definition so skip over it
-	bool passed = processRulePath(0);
-	// if a symbol in source still exists then the end of source was not reached and there was a problem some where
-	if (positionToNextSymbol()) passed = false;
-	return passed;
-
-}
-
-
-bool Compiler2Pass::processRulePath( UINT32 rulepathIDX)
-{
-	// rule path determines what tokens and therefore what symbols are acceptable from the source
-	// it is assumed that the tokens with the longest similar symbols are arranged first so
-	// if a match is found it is accepted and no further searching is done
-
-	// record position of last token in container
-	// to be used as the rollback position if a valid token is not found
-	UINT32 TokenContainerOldSize = (UINT32)mTokenInstructions.size();
-	size_t OldCharPos = mCharPos;
-	int OldLinePos = mCurrentLine;
-	UINT32 OldConstantsSize = (UINT32)mConstants.size();
-
-	// keep track of what non-terminal token activated the rule
-	UINT32 ActiveNTTRule = mRootRulePath[rulepathIDX].mTokenID;
-	// start rule path at next position for definition
-	rulepathIDX++;
-
-	// assume the rule will pass
-	bool Passed = true;
-	bool EndFound = false;
-
-	// keep following rulepath until the end is reached
-	while (EndFound == false) {
-		switch (mRootRulePath[rulepathIDX].mOperation) {
-
-			case otAND:
-				// only validate if the previous rule passed
-				if(Passed) Passed = ValidateToken(rulepathIDX, ActiveNTTRule); 
-				break;
-
-			case otOR:
-				// only validate if the previous rule failed
-				if ( Passed == false ) {
-					// clear previous tokens from entry and try again
-					mTokenInstructions.resize(TokenContainerOldSize);
-					Passed = ValidateToken(rulepathIDX, ActiveNTTRule);
-				}
-				else { // path passed up to this point therefore finished so pretend end marker found
-					EndFound = true;
-				}
-				break;
-
-			case otOPTIONAL:
-				// if previous passed then try this rule but it does not effect succes of rule since its optional
-				if(Passed) ValidateToken(rulepathIDX, ActiveNTTRule); 
-				break;
-
-			case otREPEAT:
-				// repeat until no tokens of this type found 
-				// at least one must be found
-				if(Passed) {
-					int TokensPassed = 0;
-					// keep calling until failure
-					while ((Passed = ValidateToken(rulepathIDX, ActiveNTTRule))) {
-						// increment count for previous passed token
-						TokensPassed++;
-					}
-					// defaults to Passed = fail
-					// if at least one token found then return passed = true
-					if (TokensPassed > 0) Passed = true;
-				}
-				break;
-
-			case otEND:
-				// end of rule found so time to return
-				EndFound = true;
-				if(Passed == false) {
-					// the rule did not validate so get rid of tokens decoded
-					// roll back the token container end position to what it was when rule started
-					// this will get rid of all tokens that had been pushed on the container while
-					// trying to validating this rule
-					mTokenInstructions.resize(TokenContainerOldSize);
-					mConstants.resize(OldConstantsSize);
-					mCharPos = OldCharPos;
-					mCurrentLine = OldLinePos;
-				}
-				break;
-
-			default:
-				// an exception should be raised since the code should never get here
-				Passed = false;
-				EndFound = true;
-				break;
-
-		}
-
-
-		// move on to the next rule in the path
-		rulepathIDX++;
-	}
-
-	return Passed;
-
-}
-
-
-bool Compiler2Pass::ValidateToken(const UINT32 rulepathIDX, const UINT32 activeRuleID)
-{
-	size_t tokenlength = 0;
-	// assume the test is going to fail
-	bool Passed = false;
-	UINT32 TokenID = mRootRulePath[rulepathIDX].mTokenID;
-	// only validate token if context is correct
-	if (mSymbolTypeLib[TokenID].mContextKey & mActiveContexts) {
-	
-		// if terminal token then compare text of symbol with what is in source
-		if ( mSymbolTypeLib[TokenID].mRuleID == 0){
-
-			if (positionToNextSymbol()) {
-				// if Token is supposed to be a number then check if its a numerical constant
-				if (TokenID == mValueID) {
-					float constantvalue;
-					if((Passed = isFloatValue(constantvalue, tokenlength))) {
-						mConstants.push_back(constantvalue);
-					}
-					
-				}
-				// compare token symbol text with source text
-				else Passed = isSymbol(mRootRulePath[rulepathIDX].mSymbol, tokenlength);
-					
-				if(Passed) {
-					TokenInst newtoken;
-					// push token onto end of container
-					newtoken.mID = TokenID;
-					newtoken.mNTTRuleID = activeRuleID;
-					newtoken.mLine = mCurrentLine;
-					newtoken.mPos = mCharPos;
-
-					mTokenInstructions.push_back(newtoken);
-					// update source position
-					mCharPos += tokenlength;
-
-					// allow token instruction to change the ActiveContexts
-					// use token contexts pattern to clear ActiveContexts pattern bits
-					mActiveContexts &= ~mSymbolTypeLib[TokenID].mContextPatternClear;
-					// use token contexts pattern to set ActiveContexts pattern bits
-					mActiveContexts |= mSymbolTypeLib[TokenID].mContextPatternSet;
-				}
-			}
-
-		}
-		// else a non terminal token was found
-		else {
-
-			// execute rule for non-terminal
-			// get rule_ID for index into  rulepath to be called
-			Passed = processRulePath(mSymbolTypeLib[TokenID].mRuleID);
-		}
-	}
-
-
-	return Passed;
-
-}
-
-
-const char* Compiler2Pass::getTypeDefText(const UINT32 sid)
-{
-	return mRootRulePath[mSymbolTypeLib[sid].mDefTextID].mSymbol;
-}
-
-
-bool Compiler2Pass::isFloatValue(float& fvalue, size_t& charsize)
-{
-	// check to see if it is a numeric float value
-	bool valuefound = false;
-
-	const char* startptr = mSource + mCharPos;
-	char* endptr = NULL;
-
-	fvalue = (float)strtod(startptr, &endptr);
-	// if a valid float was found then endptr will have the pointer to the first invalid character
-	if(endptr) {
-		if(endptr>startptr) {
-			// a valid value was found so process it
-			charsize = endptr - startptr;
-			valuefound = true;
-		}
-	}
-
-	return valuefound;
-}
-
-
-bool Compiler2Pass::isSymbol(const char* symbol, size_t& symbolsize)
-{
-	// compare text at source+charpos with the symbol : limit testing to symbolsize
-	bool symbolfound = false;
-	symbolsize = strlen(symbol);
-	if(strncmp(mSource + mCharPos, symbol, symbolsize)==0) {
-		symbolfound = true;
-	}
-
-	return symbolfound;
-}
-
-
-bool Compiler2Pass::positionToNextSymbol()
-{
-	bool validsymbolfound = false;
-	bool endofsource = false;
-	while(!validsymbolfound && !endofsource) {
-		skipWhiteSpace();
-		skipEOL();
-		skipComments();
-		// have we reached the end of the string?
-		if (mCharPos == mEndOfSource) endofsource = true;
-		else {
-			// if ASCII > space then assume valid character is found
-			if (mSource[mCharPos] > ' ') validsymbolfound = true;
-		}
-	}// end of while
-
-	return validsymbolfound;
-}
-
-
-
-void Compiler2Pass::skipComments()
-{
-  // if current char and next are // then search for EOL
-	if(mCharPos < mEndOfSource) {
-		if( ((mSource[mCharPos] == '/') && (mSource[mCharPos + 1] == '/')) ||
-			(mSource[mCharPos] == ';') ||
-			(mSource[mCharPos] == '#') ) findEOL();
-	}
-}
-
-
-void Compiler2Pass::findEOL()
-{
-	// find eol charter and move to this position
-	const char* newpos = strchr(&mSource[mCharPos], '\n');
-	if(newpos) {
-		mCharPos += newpos - &mSource[mCharPos];
-	}
-	// couldn't find end of line so skip to the end
-	else mCharPos = mEndOfSource - 1;
-
-}
-
-
-void Compiler2Pass::skipEOL()
-{
-	if ((mSource[mCharPos] == '\n') || (mSource[mCharPos] == '\r')) {
-		mCurrentLine++;
-		mCharPos++;
-		if ((mSource[mCharPos] == '\n') || (mSource[mCharPos] == '\r')) {
-			mCharPos++;
-		}
-	}
-}
-
-
-void Compiler2Pass::skipWhiteSpace()
-{
-	// FIX - this method kinda slow
-	while((mSource[mCharPos] == ' ') || (mSource[mCharPos] == '\t')) mCharPos++; // find first non white space character
-}
-

+ 0 - 2149
CamelotGLRenderer/Source/atifs/src/ps_1_4.cpp

@@ -1,2149 +0,0 @@
-/*
------------------------------------------------------------------------------
-This source file is part of OGRE
-(Object-oriented Graphics Rendering Engine)
-For the latest info, see http://www.ogre3d.org/
-
-Copyright (c) 2000-2011 Torus Knot Software Ltd
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
------------------------------------------------------------------------------
-*/
-
- 
- //---------------------------------------------------------------------------
-#include "ps_1_4.h"
-
-//---------------------------------------------------------------------------
-
-/* ********************* START OF PS_1_4 CLASS STATIC DATA ********************************* */
-
-
-// library of built in symbol types
-
-bool PS_1_4::LibInitialized = false;
-
-#define SYMSTART {
-#define SYMDEF  ,0,0,0,0},{
-#define SYMEND  ,0,0,0,0}
-
-PS_1_4::SymbolDef PS_1_4::PS_1_4_SymbolTypeLib[] = {
-	// pixel shader versions supported
-	{ sid_PS_1_4, GL_NONE, ckp_PS_BASE, ckp_PS_1_4, 0, 0, 0 },
-	{ sid_PS_1_1, GL_NONE, ckp_PS_BASE, ckp_PS_1_1, 0, 0, 0 },
-	{ sid_PS_1_2, GL_NONE, ckp_PS_BASE, ckp_PS_1_2 + ckp_PS_1_1, 0, 0, 0 },
-	{ sid_PS_1_3, GL_NONE, ckp_PS_BASE, ckp_PS_1_3 + ckp_PS_1_2 + ckp_PS_1_1, 0, 0, 0 },
-
-	// PS_BASE
-
-	// constants
-	SYMSTART sid_C0, GL_CON_0_ATI, ckp_PS_BASE
-	SYMDEF sid_C1, GL_CON_1_ATI, ckp_PS_BASE
-	SYMDEF sid_C2, GL_CON_2_ATI, ckp_PS_BASE
-	SYMDEF sid_C3, GL_CON_3_ATI, ckp_PS_BASE
-	SYMDEF sid_C4, GL_CON_4_ATI, ckp_PS_BASE
-	SYMDEF sid_C5, GL_CON_5_ATI, ckp_PS_BASE
-	SYMDEF sid_C6, GL_CON_6_ATI, ckp_PS_BASE
-	SYMDEF sid_C7, GL_CON_7_ATI, ckp_PS_BASE
-
-	// colour
-	SYMDEF sid_V0, GL_PRIMARY_COLOR_ARB,  ckp_PS_BASE
-	SYMDEF sid_V1, GL_SECONDARY_INTERPOLATOR_ATI,  ckp_PS_BASE
-
-	// instruction ops
-	SYMDEF sid_ADD, GL_ADD_ATI, ckp_PS_BASE
-	SYMDEF sid_SUB, GL_SUB_ATI, ckp_PS_BASE
-	SYMDEF sid_MUL, GL_MUL_ATI, ckp_PS_BASE
-	SYMDEF sid_MAD, GL_MAD_ATI, ckp_PS_BASE
-	SYMDEF sid_LRP, GL_LERP_ATI, ckp_PS_BASE
-	SYMDEF sid_MOV, GL_MOV_ATI, ckp_PS_BASE
-	SYMDEF sid_CMP, GL_CND0_ATI, ckp_PS_BASE
-	SYMDEF sid_CND, GL_CND_ATI, ckp_PS_BASE
-	SYMDEF sid_DP3, GL_DOT3_ATI, ckp_PS_BASE
-	SYMDEF sid_DP4, GL_DOT4_ATI, ckp_PS_BASE
-
-	SYMDEF sid_DEF, GL_NONE, ckp_PS_BASE
-
-	// Masks
-	SYMDEF sid_R, GL_RED_BIT_ATI, ckp_PS_1_4
-	SYMDEF sid_RA, GL_RED_BIT_ATI | ALPHA_BIT, ckp_PS_1_4
-	SYMDEF sid_G, GL_GREEN_BIT_ATI, ckp_PS_1_4
-	SYMDEF sid_GA, GL_GREEN_BIT_ATI | ALPHA_BIT, ckp_PS_1_4
-	SYMDEF sid_B, GL_BLUE_BIT_ATI, ckp_PS_1_4
-	SYMDEF sid_BA, GL_BLUE_BIT_ATI | ALPHA_BIT, ckp_PS_1_4
-	SYMDEF sid_A, ALPHA_BIT, ckp_PS_BASE
-	SYMDEF sid_RGBA, RGB_BITS | ALPHA_BIT, ckp_PS_BASE
-	SYMDEF sid_RGB, RGB_BITS,  ckp_PS_BASE
-	SYMDEF sid_RG, GL_RED_BIT_ATI | GL_GREEN_BIT_ATI, ckp_PS_1_4
-	SYMDEF sid_RGA, GL_RED_BIT_ATI | GL_GREEN_BIT_ATI | ALPHA_BIT, ckp_PS_1_4
-	SYMDEF sid_RB, GL_RED_BIT_ATI | GL_BLUE_BIT_ATI, ckp_PS_1_4
-	SYMDEF sid_RBA, GL_RED_BIT_ATI | GL_BLUE_BIT_ATI | ALPHA_BIT, ckp_PS_1_4
-	SYMDEF sid_GB, GL_GREEN_BIT_ATI | GL_BLUE_BIT_ATI, ckp_PS_1_4
-	SYMDEF sid_GBA, GL_GREEN_BIT_ATI | GL_BLUE_BIT_ATI | ALPHA_BIT, ckp_PS_1_4
-
-	// Rep
-	SYMDEF sid_RRRR, GL_RED, ckp_PS_1_4
-	SYMDEF sid_GGGG, GL_GREEN, ckp_PS_1_4
-	SYMDEF sid_BBBB, GL_BLUE, ckp_PS_BASE
-	SYMDEF sid_AAAA, GL_ALPHA, ckp_PS_BASE
-
-
-	// modifiers
-	SYMDEF sid_X2, GL_2X_BIT_ATI, ckp_PS_BASE
-	SYMDEF sid_X4, GL_4X_BIT_ATI, ckp_PS_BASE
-	SYMDEF sid_D2, GL_HALF_BIT_ATI, ckp_PS_BASE
-	SYMDEF sid_SAT, GL_SATURATE_BIT_ATI, ckp_PS_BASE
-
-	// argument modifiers
-	SYMDEF sid_BIAS, GL_BIAS_BIT_ATI, ckp_PS_BASE
-	SYMDEF sid_INVERT, GL_COMP_BIT_ATI, ckp_PS_BASE
-	SYMDEF sid_NEGATE, GL_NEGATE_BIT_ATI, ckp_PS_BASE
-	SYMDEF sid_BX2, GL_2X_BIT_ATI | GL_BIAS_BIT_ATI, ckp_PS_BASE
-	
-	// seperator characters
-	SYMDEF sid_COMMA, GL_NONE, ckp_PS_BASE
-	SYMDEF sid_VALUE, GL_NONE, ckp_PS_BASE
-
-	// PS_1_4
-	// temp R/W registers
-	SYMDEF sid_R0, GL_REG_0_ATI, ckp_PS_1_4
-	SYMDEF sid_R1, GL_REG_1_ATI, ckp_PS_1_4
-	SYMDEF sid_R2, GL_REG_2_ATI, ckp_PS_1_4
-	SYMDEF sid_R3, GL_REG_3_ATI, ckp_PS_1_4
-	SYMDEF sid_R4, GL_REG_4_ATI, ckp_PS_1_4
-	SYMDEF sid_R5, GL_REG_5_ATI, ckp_PS_1_4
-
-	// textures
-	SYMDEF sid_T0, GL_TEXTURE0_ARB, ckp_PS_1_4
-	SYMDEF sid_T1, GL_TEXTURE1_ARB, ckp_PS_1_4
-	SYMDEF sid_T2, GL_TEXTURE2_ARB, ckp_PS_1_4
-	SYMDEF sid_T3, GL_TEXTURE3_ARB, ckp_PS_1_4
-	SYMDEF sid_T4, GL_TEXTURE4_ARB, ckp_PS_1_4
-	SYMDEF sid_T5, GL_TEXTURE5_ARB, ckp_PS_1_4
-	SYMDEF sid_DP2ADD, GL_DOT2_ADD_ATI, ckp_PS_1_4
-
-	// modifiers
-	SYMDEF sid_X8, GL_8X_BIT_ATI, ckp_PS_1_4
-	SYMDEF sid_D8, GL_EIGHTH_BIT_ATI, ckp_PS_1_4
-	SYMDEF sid_D4, GL_QUARTER_BIT_ATI, ckp_PS_1_4
-
-	// instructions
-	SYMDEF sid_TEXCRD, GL_NONE, ckp_PS_1_4
-	SYMDEF sid_TEXLD, GL_NONE, ckp_PS_1_4
-
-	// texture swizzlers
-
-	SYMDEF sid_STR, GL_SWIZZLE_STR_ATI - GL_SWIZZLE_STR_ATI, ckp_PS_1_4
-	SYMDEF sid_STQ, GL_SWIZZLE_STQ_ATI - GL_SWIZZLE_STR_ATI, ckp_PS_1_4
-	SYMDEF sid_STRDR, GL_SWIZZLE_STR_DR_ATI - GL_SWIZZLE_STR_ATI, ckp_PS_1_4
-	SYMDEF sid_STQDQ, GL_SWIZZLE_STQ_DQ_ATI - GL_SWIZZLE_STR_ATI, ckp_PS_1_4 
-
-	SYMDEF sid_BEM, GL_NONE, ckp_PS_1_4
-	SYMDEF sid_PHASE, GL_NONE, ckp_PS_1_4
-
-	// PS_1_1 
-	// temp R/W registers
-	// r0, r1 are mapped to r4, r5
-	// t0 to t3 are mapped to r0 to r3
-	SYMDEF sid_1R0, GL_REG_4_ATI, ckp_PS_1_1
-	SYMDEF sid_1R1, GL_REG_5_ATI, ckp_PS_1_1
-	SYMDEF sid_1T0, GL_REG_0_ATI, ckp_PS_1_1
-	SYMDEF sid_1T1, GL_REG_1_ATI, ckp_PS_1_1
-	SYMDEF sid_1T2, GL_REG_2_ATI, ckp_PS_1_1
-	SYMDEF sid_1T3, GL_REG_3_ATI, ckp_PS_1_1
-
-	// instructions common to PS_1_1, PS_1_2, PS_1_3
-	SYMDEF sid_TEX, GL_NONE, ckp_PS_1_1
-	SYMDEF sid_TEXCOORD, GL_NONE, ckp_PS_1_1
-	SYMDEF sid_TEXM3X2PAD, GL_NONE, ckp_PS_1_1
-	SYMDEF sid_TEXM3X2TEX, GL_NONE, ckp_PS_1_1
-	SYMDEF sid_TEXM3X3PAD, GL_NONE, ckp_PS_1_1
-	SYMDEF sid_TEXM3X3TEX, GL_NONE, ckp_PS_1_1
-	SYMDEF sid_TEXM3X3SPEC, GL_NONE, ckp_PS_1_1
-	SYMDEF sid_TEXM3X3VSPEC, GL_NONE, ckp_PS_1_1
-	SYMDEF sid_TEXREG2AR, GL_NONE, ckp_PS_1_2
-	SYMDEF sid_TEXREG2GB, GL_NONE, ckp_PS_1_2
-
-	// PS_1_2 & PS_1_3
-	SYMDEF sid_TEXREG2RGB, GL_NONE, ckp_PS_1_2
-	SYMDEF sid_TEXDP3, GL_NONE, ckp_PS_1_2
-	SYMDEF sid_TEXDP3TEX, GL_NONE, ckp_PS_1_2
-	
-
-	// Common
-	SYMDEF sid_SKIP, GL_NONE, ckp_PS_BASE
-	SYMDEF sid_PLUS, GL_NONE, ckp_PS_BASE
-
-	// Non-Terminal Tokens
-	SYMDEF sid_PROGRAM, GL_NONE, ckp_PS_BASE
-	SYMDEF sid_PROGRAMTYPE, GL_NONE, ckp_PS_BASE
-	SYMDEF sid_DECLCONSTS, GL_NONE, ckp_PS_BASE
-	SYMDEF sid_DEFCONST, GL_NONE, ckp_PS_BASE
-	SYMDEF sid_CONSTANT, GL_NONE, ckp_PS_BASE
-	SYMDEF sid_COLOR, GL_NONE, ckp_PS_BASE 
-	SYMDEF sid_TEXSWIZZLE, GL_NONE, ckp_PS_BASE
-	SYMDEF sid_UNARYOP, GL_NONE, ckp_PS_BASE
-	SYMDEF sid_NUMVAL, GL_NONE, ckp_PS_BASE
-	SYMDEF sid_SEPERATOR, GL_NONE, ckp_PS_BASE
-	SYMDEF sid_ALUOPS, GL_NONE, ckp_PS_BASE
-	SYMDEF sid_TEXMASK, GL_NONE, ckp_PS_BASE
-	SYMDEF sid_TEXOP_PS1_1_3, GL_NONE, ckp_PS_1_1 
-	SYMDEF sid_TEXOP_PS1_4, GL_NONE, ckp_PS_1_4
-	SYMDEF sid_ALU_STATEMENT, GL_NONE, ckp_PS_BASE
-	SYMDEF sid_DSTMODSAT, GL_NONE, ckp_PS_BASE
-	SYMDEF sid_UNARYOP_ARGS, GL_NONE, ckp_PS_BASE
-	SYMDEF sid_REG_PS1_4, GL_NONE, ckp_PS_1_4
-	SYMDEF sid_TEX_PS1_4, GL_NONE, ckp_PS_1_4
-	SYMDEF sid_REG_PS1_1_3, GL_NONE, ckp_PS_1_1
-	SYMDEF sid_TEX_PS1_1_3, GL_NONE, ckp_PS_1_1
-	SYMDEF sid_DSTINFO, GL_NONE, ckp_PS_BASE
-	SYMDEF sid_SRCINFO, GL_NONE, ckp_PS_BASE
-	SYMDEF sid_BINARYOP_ARGS, GL_NONE, ckp_PS_BASE
-	SYMDEF sid_TERNARYOP_ARGS, GL_NONE, ckp_PS_BASE
-	SYMDEF sid_TEMPREG, GL_NONE, ckp_PS_BASE
-	SYMDEF sid_DSTMASK, GL_NONE, ckp_PS_BASE
-	SYMDEF sid_PRESRCMOD, GL_NONE, ckp_PS_BASE
-	SYMDEF sid_SRCNAME, GL_NONE, ckp_PS_BASE
-	SYMDEF sid_SRCREP, GL_NONE, ckp_PS_BASE
-	SYMDEF sid_POSTSRCMOD, GL_NONE, ckp_PS_BASE
-	SYMDEF sid_DSTMOD, GL_NONE, ckp_PS_BASE
-	SYMDEF sid_DSTSAT, GL_NONE, ckp_PS_BASE
-	SYMDEF sid_BINARYOP, GL_NONE, ckp_PS_BASE
-	SYMDEF sid_TERNARYOP, GL_NONE, ckp_PS_BASE
-	SYMDEF sid_TEXOPS_PHASE1, GL_NONE, ckp_PS_BASE
-	SYMDEF sid_COISSUE, GL_NONE, ckp_PS_BASE
-	SYMDEF sid_PHASEMARKER, GL_NONE, ckp_PS_1_4
-	SYMDEF sid_TEXOPS_PHASE2, GL_NONE, ckp_PS_1_4
-	SYMDEF sid_TEXREG_PS1_4, GL_NONE, ckp_PS_1_4
-	SYMDEF sid_TEXOPS_PS1_4, GL_NONE, ckp_PS_1_4
-	SYMDEF sid_TEXOPS_PS1_1_3, GL_NONE, ckp_PS_1_1
-	SYMDEF sid_TEXCISCOP_PS1_1_3, GL_NONE, ckp_PS_1_1
-	SYMEND
-};
-
-
-// Rule Path Database for ps.1.x code based on extended Backus Naur Form notation
-
-// <>	- non-terminal token
-#define _rule_		{otRULE,		// ::=	- rule definition
-#define _is_		,0},{otAND,
-#define _and_		,0},{otAND,		//      - blank space is an implied "AND" meaning the token is required
-#define _or_		,0},{otOR,		// |	- or
-#define _optional_	,0},{otOPTIONAL,	// []	- optional
-#define _repeat_	,0},{otREPEAT,	// {}	- repeat until fail
-#define _end_		,0},{otEND,0,0,0},
-#define _nt_        ,0
-// " "  - terminal token string
-
-PS_1_4::TokenRule PS_1_4::PS_1_x_RulePath[] = {
-
-	_rule_ sid_PROGRAM, "Program"
-
-		_is_ sid_PROGRAMTYPE _nt_
-		_optional_ sid_DECLCONSTS _nt_
-		_optional_ sid_TEXOPS_PHASE1 _nt_
-		_optional_ sid_ALUOPS _nt_
-		_optional_ sid_PHASEMARKER _nt_
-		_optional_ sid_TEXOPS_PHASE2 _nt_
-		_optional_ sid_ALUOPS _nt_
-		_end_ 
-
-	_rule_ sid_PROGRAMTYPE, "<ProgramType>"
-
-		_is_ sid_PS_1_4, "ps.1.4"
-		_or_ sid_PS_1_1, "ps.1.1"
-		_or_ sid_PS_1_2, "ps.1.2"
-		_or_ sid_PS_1_3, "ps.1.3"
-		_end_
-
-	_rule_ sid_PHASEMARKER, "<PhaseMarker>"
-
-		_is_ sid_PHASE, "phase"
-		_end_
-
-	_rule_ sid_DECLCONSTS, "<DeclareConstants>"
-
-		_repeat_ sid_DEFCONST _nt_
-		_end_
-
-
-	_rule_ sid_TEXOPS_PHASE1, "<TexOps_Phase1>"
-
-		_is_ sid_TEXOPS_PS1_1_3 _nt_
-		_or_ sid_TEXOPS_PS1_4 _nt_
-		_end_
-
-	_rule_ sid_TEXOPS_PHASE2, "<TexOps_Phase2>"
-
-		_is_ sid_TEXOPS_PS1_4 _nt_
-		_end_
-
-	_rule_ sid_NUMVAL, "<NumVal>"
-
-		_is_ sid_VALUE, "Float Value"
-		_end_
-
-	_rule_ sid_TEXOPS_PS1_1_3, "<TexOps_PS1_1_3>"
-
-		_repeat_ sid_TEXOP_PS1_1_3 _nt_
-		_end_
-
-	_rule_ sid_TEXOPS_PS1_4, "<TexOps_PS1_4>"
-
-		_repeat_ sid_TEXOP_PS1_4 _nt_
-		_end_
-
-	_rule_ sid_TEXOP_PS1_1_3, "<TexOp_PS1_1_3>"
-
-		_is_  sid_TEXCISCOP_PS1_1_3 _nt_
-		_and_ sid_TEX_PS1_1_3 _nt_
-		_and_ sid_SEPERATOR _nt_
-		_and_ sid_TEX_PS1_1_3 _nt_
-
-		_or_  sid_TEXCOORD, "texcoord"
-		_and_ sid_TEX_PS1_1_3 _nt_
-
-		_or_  sid_TEX, "tex"
-		_and_ sid_TEX_PS1_1_3 _nt_
-
-
-
-		_end_
-
-	_rule_ sid_TEXOP_PS1_4, "<TexOp_PS1_4>"
-
-		_is_  sid_TEXCRD, "texcrd"
-		_and_ sid_REG_PS1_4 _nt_
-		_optional_ sid_TEXMASK _nt_
-		_and_ sid_SEPERATOR _nt_
-		_and_ sid_TEXREG_PS1_4 _nt_
-
-		_or_  sid_TEXLD, "texld"
-		_and_ sid_REG_PS1_4 _nt_
-		_optional_ sid_TEXMASK _nt_
-		_and_ sid_SEPERATOR _nt_
-		_and_ sid_TEXREG_PS1_4 _nt_
-		_end_
-
-	_rule_ sid_ALUOPS, "<ALUOps>"
-
-		_repeat_ sid_ALU_STATEMENT _nt_
-		_end_
-
-	_rule_ sid_ALU_STATEMENT, "<ALUStatement>"
-
-		_is_ sid_COISSUE _nt_
-		_and_ sid_UNARYOP _nt_
-		_optional_ sid_DSTMODSAT _nt_
-		_and_ sid_UNARYOP_ARGS _nt_ 
-
-		_or_ sid_COISSUE _nt_
-		_and_ sid_BINARYOP _nt_
-		_optional_ sid_DSTMODSAT _nt_
-		_and_ sid_BINARYOP_ARGS _nt_
-		
-		_or_ sid_COISSUE _nt_
-		_and_ sid_TERNARYOP _nt_
-		_optional_ sid_DSTMODSAT _nt_
-		_and_ sid_TERNARYOP_ARGS _nt_
-		_end_
-
-
-	_rule_ sid_TEXREG_PS1_4, "<TexReg_PS1_4>"
-
-		_is_ sid_TEX_PS1_4  _nt_
-		_optional_ sid_TEXSWIZZLE _nt_
-		_or_ sid_REG_PS1_4  _nt_
-		_optional_ sid_TEXSWIZZLE _nt_
-		_end_
-
-	_rule_ sid_UNARYOP_ARGS, "<UnaryOpArgs>"
-
-		_is_  sid_DSTINFO _nt_
-		_and_ sid_SRCINFO _nt_
-		_end_
-
-	_rule_ sid_BINARYOP_ARGS, "<BinaryOpArgs>"
-	
-		_is_  sid_DSTINFO _nt_
-		_and_ sid_SRCINFO _nt_
-		_and_ sid_SRCINFO _nt_
-		_end_
-
-	_rule_ sid_TERNARYOP_ARGS, "<TernaryOpArgs>"
-		
-		_is_  sid_DSTINFO _nt_
-		_and_ sid_SRCINFO _nt_
-		_and_ sid_SRCINFO _nt_
-		_and_ sid_SRCINFO _nt_
-		_end_
- 
-	_rule_ sid_DSTINFO, "<DstInfo>"
-
-		_is_ sid_TEMPREG _nt_
-		_optional_ sid_DSTMASK _nt_
-		_end_
-
-	_rule_ sid_SRCINFO, "<SrcInfo>"
-	
-		_is_ sid_SEPERATOR _nt_
-		_optional_ sid_PRESRCMOD _nt_
-		_and_ sid_SRCNAME _nt_
-		_optional_ sid_POSTSRCMOD _nt_
-		_optional_ sid_SRCREP _nt_
-		_end_
-
-	_rule_ sid_SRCNAME, "<SrcName>"
-	
-		_is_ sid_TEMPREG _nt_
-		_or_ sid_CONSTANT _nt_
-		_or_ sid_COLOR _nt_
-		_end_
-
-	_rule_ sid_DEFCONST, "<DefineConstant>"
-
-		_is_ sid_DEF, "def"
-		_and_ sid_CONSTANT _nt_
-		_and_ sid_SEPERATOR _nt_
-		_and_ sid_NUMVAL _nt_
-		_and_ sid_SEPERATOR _nt_
-		_and_ sid_NUMVAL _nt_
-		_and_ sid_SEPERATOR _nt_
-		_and_ sid_NUMVAL _nt_
-		_and_ sid_SEPERATOR _nt_
-		_and_ sid_NUMVAL _nt_
-		_end_
-
-	_rule_ sid_CONSTANT, "<Constant>"
-
-		_is_ sid_C0, "c0"
-		_or_ sid_C1, "c1"
-		_or_ sid_C2, "c2"
-		_or_ sid_C3, "c3"
-		_or_ sid_C4, "c4"
-		_or_ sid_C5, "c5"
-		_or_ sid_C6, "c6"
-		_or_ sid_C7, "c7"
-		_end_
-
-
-	_rule_ sid_TEXCISCOP_PS1_1_3, "<TexCISCOp_PS1_1_3>"
-
-		_is_ sid_TEXDP3TEX,		"texdp3tex"
-		_or_ sid_TEXDP3,		"texdp3"
-		_or_ sid_TEXM3X2PAD,	"texm3x2pad"
-		_or_ sid_TEXM3X2TEX,	"texm3x2tex"
-		_or_ sid_TEXM3X3PAD,	"texm3x3pad"
-		_or_ sid_TEXM3X3TEX,	"texm3x3tex"
-		_or_ sid_TEXM3X3SPEC,	"texm3x3spec"
-		_or_ sid_TEXM3X3VSPEC,	"texm3x3vspec"
-		_or_ sid_TEXREG2RGB,	"texreg2rgb"
-		_or_ sid_TEXREG2AR,		"texreg2ar"
-		_or_ sid_TEXREG2GB,		"texreg2gb"
-		_end_
-
-
-	_rule_ sid_TEXSWIZZLE, "<TexSwizzle>"
-
-		_is_ sid_STQDQ,	"_dw.xyw"
-		_or_ sid_STQDQ,	"_dw"
-		_or_ sid_STQDQ,	"_da.rga"
-		_or_ sid_STQDQ,	"_da"
-		_or_ sid_STRDR,	"_dz.xyz"
-		_or_ sid_STRDR,	"_dz"
-		_or_ sid_STRDR,	"_db.rgb"
-		_or_ sid_STRDR,	"_db"
-		_or_ sid_STR,	".xyz"
-		_or_ sid_STR,	".rgb"
-		_or_ sid_STQ,	".xyw"
-		_or_ sid_STQ,	".rga"
-		_end_ 
-
-	_rule_ sid_TEXMASK, "<TexMask>"
-
-		_is_ sid_RGB,	".rgb"
-		_or_ sid_RGB,	".xyz"
-		_or_ sid_RG,	".rg"
-		_or_ sid_RG,	".xy"
-		_end_
-
-	_rule_ sid_SEPERATOR, "<Seperator>"
-
-		_is_ sid_COMMA, ","
-		_end_
-
-	_rule_ sid_REG_PS1_4, "<Reg_PS1_4>"
-
-		_is_ sid_R0, "r0"
-		_or_ sid_R1, "r1"
-		_or_ sid_R2, "r2"
-		_or_ sid_R3, "r3"
-		_or_ sid_R4, "r4"
-		_or_ sid_R5, "r5"
-		_end_
-
-	_rule_ sid_TEX_PS1_4, "<Tex_PS1_4>"
-
-		_is_ sid_T0, "t0"
-		_or_ sid_T1, "t1"
-		_or_ sid_T2, "t2"
-		_or_ sid_T3, "t3"
-		_or_ sid_T4, "t4"
-		_or_ sid_T5, "t5"
-		_end_
-
-	_rule_ sid_REG_PS1_1_3, "<Reg_PS1_1_3>"
-
-		_is_ sid_1R0, "r0"
-		_or_ sid_1R1, "r1"
-		_end_
-
-	_rule_ sid_TEX_PS1_1_3, "<Tex_PS1_1_3>"
-
-		_is_ sid_1T0, "t0"
-		_or_ sid_1T1, "t1"
-		_or_ sid_1T2, "t2"
-		_or_ sid_1T3, "t3"
-		_end_
-
-	_rule_ sid_COLOR, "<Color>"
-
-		_is_ sid_V0, "v0"
-		_or_ sid_V1, "v1"
-		_end_
-
-
-	_rule_ sid_TEMPREG, "<TempReg>"
-
-		_is_ sid_REG_PS1_4 _nt_
-		_or_ sid_REG_PS1_1_3 _nt_
-		_or_ sid_TEX_PS1_1_3 _nt_
-		_end_
-
-	_rule_ sid_DSTMODSAT, "<DstModSat>"
-	
-		_optional_ sid_DSTMOD _nt_
-		_optional_ sid_DSTSAT _nt_
-		_end_
-
-	_rule_  sid_UNARYOP, "<UnaryOp>"
-
-		_is_ sid_MOV, "mov"
-		_end_
-
-	_rule_ sid_BINARYOP, "<BinaryOP>"
-	
-		_is_ sid_ADD, "add"
-		_or_ sid_MUL, "mul"
-		_or_ sid_SUB, "sub"
-		_or_ sid_DP3, "dp3"
-		_or_ sid_DP4, "dp4"
-		_or_ sid_BEM, "bem"
-		_end_
-
-	_rule_ sid_TERNARYOP, "<TernaryOp>"
-	
-		_is_ sid_MAD, "mad"
-		_or_ sid_LRP, "lrp"
-		_or_ sid_CND, "cnd"
-		_or_ sid_CMP, "cmp"
-		_end_
-
-	_rule_ sid_DSTMASK, "<DstMask>"
-
-		_is_ sid_RGBA,	".rgba"
-		_or_ sid_RGBA,	".xyzw"
-		_or_ sid_RGB,	".rgb"
-		_or_ sid_RGB,	".xyz"
-		_or_ sid_RGA,	".xyw"
-		_or_ sid_RGA,	".rga"
-		_or_ sid_RBA,	".rba"
-		_or_ sid_RBA,	".xzw"
-		_or_ sid_GBA,	".gba"
-		_or_ sid_GBA,	".yzw"
-		_or_ sid_RG,	".rg"
-		_or_ sid_RG,	".xy"
-		_or_ sid_RB,	".xz"
-		_or_ sid_RB,	".rb"
-		_or_ sid_RA,	".xw"
-		_or_ sid_RA,	".ra"
-		_or_ sid_GB,	".gb"
-		_or_ sid_GB,	".yz"
-		_or_ sid_GA,	".yw"
-		_or_ sid_GA,	".ga"
-		_or_ sid_BA,	".zw"
-		_or_ sid_BA,	".ba"
-		_or_ sid_R,		".r"
-		_or_ sid_R,		".x"
-		_or_ sid_G,		".g"
-		_or_ sid_G,		".y"
-		_or_ sid_B,		".b"
-		_or_ sid_B,		".z"
-		_or_ sid_A,		".a"
-		_or_ sid_A,		".w"
-		_end_
-
-	_rule_ sid_SRCREP, "<SrcRep>"
-	
-		_is_ sid_RRRR, ".r"
-		_or_ sid_RRRR, ".x"
-		_or_ sid_GGGG, ".g"
-		_or_ sid_GGGG, ".y"
-		_or_ sid_BBBB, ".b"
-		_or_ sid_BBBB, ".z"
-		_or_ sid_AAAA, ".a"
-		_or_ sid_AAAA, ".w"
-		_end_
-
-	_rule_ sid_PRESRCMOD, "<PreSrcMod>"
-
-		_is_ sid_INVERT, "1-"
-		_or_ sid_INVERT, "1 -"
-		_or_ sid_NEGATE, "-"
-		_end_
-
-	_rule_ sid_POSTSRCMOD, "<PostSrcMod>"
-
-		_is_ sid_BX2, "_bx2"
-		_or_ sid_X2, "_x2"
-		_or_ sid_BIAS, "_bias"
-		_end_
-
-	_rule_ sid_DSTMOD, "<DstMod>"
-
-		_is_ sid_X2, "_x2"
-		_or_ sid_X4, "_x4"
-		_or_ sid_D2, "_d2"
-		_or_ sid_X8, "_x8"
-		_or_ sid_D4, "_d4"
-		_or_ sid_D8, "_d8"
-		_end_
-
-	_rule_ sid_DSTSAT, "<DstSat>"
-
-		_is_ sid_SAT, "_sat"
-		_end_
-
-	_rule_ sid_COISSUE, "<CoIssue>"
-
-		_optional_ sid_PLUS, "+"
-		_end_
-
-};
-
-//***************************** MACROs for PS1_1 , PS1_2, PS1_3 CISC instructions **************************************
-
-// macro to make the macro text data easier to read
-#define _token_ ,0,0},{
-#define _token_end_ ,0,0}
-// macro token expansion for ps_1_2 instruction: texreg2ar
-PS_1_4::TokenInst PS_1_4::texreg2ar[] = {
-	// mov r(x).r, r(y).a
-	{		sid_UNARYOP,	sid_MOV
-	_token_ sid_REG_PS1_4,	sid_R1
-	_token_ sid_DSTMASK,	sid_R
-	_token_ sid_SEPERATOR,	sid_COMMA
-	_token_ sid_REG_PS1_4,	sid_R0
-	_token_ sid_SRCREP,		sid_AAAA
-
-	// mov r(x).g, r(y).r
-	_token_ sid_UNARYOP,	sid_MOV
-	_token_ sid_REG_PS1_4,	sid_R1
-	_token_ sid_DSTMASK,	sid_G
-	_token_ sid_SEPERATOR,	sid_COMMA
-	_token_ sid_REG_PS1_4,	sid_R0
-	_token_ sid_SRCREP,		sid_RRRR
-
-	// texld r(x), r(x)
-	_token_ sid_TEXOP_PS1_4, sid_TEXLD
-	_token_ sid_REG_PS1_4,	sid_R1
-	_token_ sid_SEPERATOR,	sid_COMMA
-	_token_ sid_REG_PS1_4,	sid_R1
-	_token_end_
-};
-
-PS_1_4::RegModOffset PS_1_4::texreg2xx_RegMods[] = {
-	{1, R_BASE, 0},
-	{7, R_BASE, 0},
-	{13, R_BASE, 0},
-	{15, R_BASE, 0},
-	{4, R_BASE, 1},
-	{10, R_BASE, 1},
-
-};
-
-PS_1_4::MacroRegModify PS_1_4::texreg2ar_MacroMods = {
-	texreg2ar, ARRAYSIZE(texreg2ar),
-	texreg2xx_RegMods, ARRAYSIZE(texreg2xx_RegMods)
-};
-
-// macro token expansion for ps_1_2 instruction: texreg2gb
-PS_1_4::TokenInst PS_1_4::texreg2gb[] = {
-	// mov r(x).r, r(y).g
-	{		sid_UNARYOP,	sid_MOV
-	_token_ sid_REG_PS1_4,	sid_R1
-	_token_ sid_DSTMASK,	sid_R
-	_token_ sid_SEPERATOR,	sid_COMMA
-	_token_ sid_REG_PS1_4,	sid_R0
-	_token_ sid_SRCREP,		sid_GGGG
-
-	// mov r(x).g, r(y).b
-	_token_ sid_UNARYOP,	sid_MOV
-	_token_ sid_REG_PS1_4,	sid_R1
-	_token_ sid_DSTMASK,	sid_G
-	_token_ sid_SEPERATOR,	sid_COMMA
-	_token_ sid_REG_PS1_4,	sid_R0
-	_token_ sid_SRCREP,		sid_BBBB
-
-	// texld r(x), r(x)
-	_token_ sid_TEXOP_PS1_4, sid_TEXLD
-	_token_ sid_REG_PS1_4,	sid_R1
-	_token_ sid_SEPERATOR,	sid_COMMA
-	_token_ sid_REG_PS1_4,	sid_R1
-	_token_end_
-};
-
-PS_1_4::MacroRegModify PS_1_4::texreg2gb_MacroMods = {
-	texreg2gb, ARRAYSIZE(texreg2gb),
-	texreg2xx_RegMods, ARRAYSIZE(texreg2xx_RegMods)
-};
-
-
-// macro token expansion for ps_1_1 instruction: texdp3
-PS_1_4::TokenInst PS_1_4::texdp3[] = {
-	// texcoord t(x)
-	{		sid_TEXOP_PS1_1_3, sid_TEXCOORD
-	_token_ sid_TEX_PS1_1_3, sid_1T1
-
-	// dp3 r(x), r(x), r(y)
-	_token_ sid_BINARYOP,	sid_DP3
-	_token_ sid_REG_PS1_4,	sid_R1
-	_token_ sid_SEPERATOR,	sid_COMMA
-	_token_ sid_REG_PS1_4,	sid_R1
-	_token_ sid_SEPERATOR,	sid_COMMA
-	_token_ sid_REG_PS1_4,	sid_R0
-	_token_end_
-};
-
-
-PS_1_4::RegModOffset PS_1_4::texdp3_RegMods[] = {
-	{1, T_BASE, 0},
-	{3, R_BASE, 0},
-	{5, R_BASE, 0},
-	{7, R_BASE, 1},
-
-};
-
-
-PS_1_4::MacroRegModify PS_1_4::texdp3_MacroMods = {
-	texdp3, ARRAYSIZE(texdp3),
-	texdp3_RegMods, ARRAYSIZE(texdp3_RegMods)
-};
-
-
-// macro token expansion for ps_1_1 instruction: texdp3tex
-PS_1_4::TokenInst PS_1_4::texdp3tex[] = {
-	// texcoord t(x)
-	{		sid_TEXOP_PS1_1_3, sid_TEXCOORD
-	_token_ sid_TEX_PS1_1_3, sid_1T1
-
-	// dp3 r1, r(x), r(y)
-	_token_ sid_BINARYOP,	sid_DP3
-	_token_ sid_REG_PS1_4,	sid_R1
-	_token_ sid_SEPERATOR,	sid_COMMA
-	_token_ sid_REG_PS1_4,	sid_R1
-	_token_ sid_SEPERATOR,	sid_COMMA
-	_token_ sid_REG_PS1_4,	sid_R0
-
-	// texld r(x), r(x)
-	_token_ sid_TEXOP_PS1_4, sid_TEXLD
-	_token_ sid_REG_PS1_4,	sid_R1
-	_token_ sid_SEPERATOR,	sid_COMMA
-	_token_ sid_REG_PS1_4,	sid_R1
-	_token_end_
-};
-
-
-PS_1_4::RegModOffset PS_1_4::texdp3tex_RegMods[] = {
-	{1, T_BASE, 0},
-	{3, R_BASE, 0},
-	{5, R_BASE, 0},
-	{7, R_BASE, 1},
-	{9, R_BASE, 1},
-	{11, R_BASE, 1},
-
-};
-
-
-PS_1_4::MacroRegModify PS_1_4::texdp3tex_MacroMods = {
-	texdp3tex, ARRAYSIZE(texdp3tex),
-	texdp3tex_RegMods, ARRAYSIZE(texdp3tex_RegMods)
-};
-
-
-// macro token expansion for ps_1_1 instruction: texm3x2pad
-PS_1_4::TokenInst PS_1_4::texm3x2pad[] = {
-	// texcoord t(x)
-	{		sid_TEXOP_PS1_1_3, sid_TEXCOORD
-	_token_ sid_TEX_PS1_1_3, sid_1T0
-
-	// dp3 r4.r, r(x), r(y)
-	_token_ sid_BINARYOP,	sid_DP3
-	_token_ sid_REG_PS1_4,	sid_R4
-	_token_ sid_DSTMASK,	sid_R
-	_token_ sid_SEPERATOR,	sid_COMMA
-	_token_ sid_REG_PS1_4,	sid_R1
-	_token_ sid_SEPERATOR,	sid_COMMA
-	_token_ sid_REG_PS1_4,	sid_R0
-	_token_end_
-
-};
-
-
-PS_1_4::RegModOffset PS_1_4::texm3xxpad_RegMods[] = {
-	{1, T_BASE, 0},
-	{6, R_BASE, 0},
-	{8, R_BASE, 1},
-};
-
-
-PS_1_4::MacroRegModify PS_1_4::texm3x2pad_MacroMods = {
-	texm3x2pad, ARRAYSIZE(texm3x2pad),
-	texm3xxpad_RegMods, ARRAYSIZE(texm3xxpad_RegMods)
-};
-
-
-// macro token expansion for ps_1_1 instruction: texm3x2tex
-PS_1_4::TokenInst PS_1_4::texm3x2tex[] = {
-	// texcoord t(x)
-	{		sid_TEXOP_PS1_1_3, sid_TEXCOORD
-	_token_ sid_TEX_PS1_1_3, sid_1T1
-
-	// dp3 r4.g, r(x), r(y)
-	_token_ sid_BINARYOP,	sid_DP3
-	_token_ sid_REG_PS1_4,	sid_R4
-	_token_ sid_DSTMASK,	sid_G
-	_token_ sid_SEPERATOR,	sid_COMMA
-	_token_ sid_REG_PS1_4,	sid_R1
-	_token_ sid_SEPERATOR,	sid_COMMA
-	_token_ sid_REG_PS1_4,	sid_R0
-
-	// texld r(x), r4
-	_token_ sid_TEXOP_PS1_4, sid_TEXLD
-	_token_ sid_REG_PS1_4,	sid_R1
-	_token_ sid_SEPERATOR,	sid_COMMA
-	_token_ sid_REG_PS1_4,	sid_R4
-	_token_end_
-
-};
-
-PS_1_4::RegModOffset PS_1_4::texm3xxtex_RegMods[] = {
-	{1, T_BASE, 0},
-	{6, R_BASE, 0},
-	{8, R_BASE, 1},
-	{10, R_BASE, 0}
-};
-
-PS_1_4::MacroRegModify PS_1_4::texm3x2tex_MacroMods = {
-	texm3x2tex, ARRAYSIZE(texm3x2tex),
-	texm3xxtex_RegMods, ARRAYSIZE(texm3xxtex_RegMods)
-};
-
-// macro token expansion for ps_1_1 instruction: texm3x3tex
-PS_1_4::TokenInst PS_1_4::texm3x3pad[] = {
-	// texcoord t(x)
-	{		sid_TEXOP_PS1_1_3, sid_TEXCOORD
-	_token_ sid_TEX_PS1_1_3, sid_1T0
-
-	// dp3 r4.b, r(x), r(y)
-	_token_ sid_BINARYOP,	sid_DP3
-	_token_ sid_REG_PS1_4,	sid_R4
-	_token_ sid_DSTMASK,	sid_B
-	_token_ sid_SEPERATOR,	sid_COMMA
-	_token_ sid_REG_PS1_4,	sid_R1
-	_token_ sid_SEPERATOR,	sid_COMMA
-	_token_ sid_REG_PS1_4,	sid_R0
-	_token_end_
-
-};
-
-
-PS_1_4::MacroRegModify PS_1_4::texm3x3pad_MacroMods = {
-	texm3x3pad, ARRAYSIZE(texm3x3pad),
-	texm3xxpad_RegMods, ARRAYSIZE(texm3xxpad_RegMods)
-};
-
-
-// macro token expansion for ps_1_1 instruction: texm3x3pad
-PS_1_4::TokenInst PS_1_4::texm3x3tex[] = {
-	// texcoord t(x)
-	{		sid_TEXOP_PS1_1_3, sid_TEXCOORD
-	_token_ sid_TEX_PS1_1_3, sid_1T1
-
-	// dp3 r4.b, r(x), r(y)
-	_token_ sid_BINARYOP,	sid_DP3
-	_token_ sid_REG_PS1_4,	sid_R4
-	_token_ sid_DSTMASK,	sid_B
-	_token_ sid_SEPERATOR,	sid_COMMA
-	_token_ sid_REG_PS1_4,	sid_R1
-	_token_ sid_SEPERATOR,	sid_COMMA
-	_token_ sid_REG_PS1_4,	sid_R0
-
-	// texld r1, r4
-	_token_ sid_TEXOP_PS1_4, sid_TEXLD
-	_token_ sid_REG_PS1_4,	sid_R1
-	_token_ sid_SEPERATOR,	sid_COMMA
-	_token_ sid_REG_PS1_4,	sid_R4
-	_token_end_
-};
-
-
-
-
-
-
-PS_1_4::MacroRegModify PS_1_4::texm3x3tex_MacroMods = {
-	texm3x3tex, ARRAYSIZE(texm3x3tex),
-	texm3xxtex_RegMods, ARRAYSIZE(texm3xxtex_RegMods)
-};
-
-
-// macro token expansion for ps_1_1 instruction: texm3x3spec
-PS_1_4::TokenInst PS_1_4::texm3x3spec[] = {
-	// texcoord t(x)
-	{		sid_TEXOP_PS1_1_3, sid_TEXCOORD
-	_token_ sid_TEX_PS1_1_3, sid_1T3
-
-	// dp3 r4.b, r3, r(x)
-	_token_ sid_BINARYOP,	sid_DP3
-	_token_ sid_REG_PS1_4,	sid_R4
-	_token_ sid_DSTMASK,	sid_B
-	_token_ sid_SEPERATOR,	sid_COMMA
-	_token_ sid_REG_PS1_4,	sid_R3
-	_token_ sid_SEPERATOR,	sid_COMMA
-	_token_ sid_REG_PS1_4,	sid_R0
-
-	// dp3_x2 r3, r4, c(x)
-	_token_ sid_BINARYOP,	sid_DP3
-	_token_ sid_DSTMOD,		sid_X2
-	_token_ sid_REG_PS1_4,	sid_R3
-	_token_ sid_SEPERATOR,	sid_COMMA
-	_token_ sid_REG_PS1_4,	sid_R4
-	_token_ sid_SEPERATOR,	sid_COMMA
-	_token_ sid_CONSTANT,	sid_C0
-
-	// mul r3, r3, c(x)
-	_token_ sid_UNARYOP,	sid_MUL
-	_token_ sid_REG_PS1_4,	sid_R3
-	_token_ sid_SEPERATOR,	sid_COMMA
-	_token_ sid_REG_PS1_4,	sid_R3
-	_token_ sid_SEPERATOR,	sid_COMMA
-	_token_ sid_CONSTANT,	sid_C0
-
-	// dp3 r2, r4, r4
-	_token_ sid_BINARYOP,	sid_DP3
-	_token_ sid_REG_PS1_4,	sid_R2
-	_token_ sid_SEPERATOR,	sid_COMMA
-	_token_ sid_REG_PS1_4,	sid_R4
-	_token_ sid_SEPERATOR,	sid_COMMA
-	_token_ sid_REG_PS1_4,	sid_R4
-
-	// mad r4.rgb, 1-c(x), r2, r3
-	_token_ sid_TERNARYOP,	sid_MAD
-	_token_ sid_REG_PS1_4,	sid_R4
-	_token_ sid_DSTMASK,	sid_RGB
-	_token_ sid_SEPERATOR,	sid_COMMA
-	_token_ sid_PRESRCMOD,	sid_INVERT
-	_token_ sid_CONSTANT,	sid_C0
-	_token_ sid_SEPERATOR,	sid_COMMA
-	_token_ sid_REG_PS1_4,	sid_R2
-	_token_ sid_SEPERATOR,	sid_COMMA
-	_token_ sid_REG_PS1_4,	sid_R3
-
-	// + mov r4.a, r2.r
-	_token_ sid_UNARYOP,	sid_MOV
-	_token_ sid_REG_PS1_4,	sid_R4
-	_token_ sid_DSTMASK,	sid_A
-	_token_ sid_SEPERATOR,	sid_COMMA
-	_token_ sid_REG_PS1_4,	sid_R2
-	_token_ sid_SRCREP,		sid_RRRR
-
-	// texld r3, r4.xyz_dz
-	_token_ sid_TEXOP_PS1_4, sid_TEXLD
-	_token_ sid_REG_PS1_4,	sid_R3
-	_token_ sid_SEPERATOR,	sid_COMMA
-	_token_ sid_REG_PS1_4,	sid_R4
-	_token_ sid_TEXSWIZZLE,	sid_STRDR
-	_token_end_
-
-};
-
-PS_1_4::RegModOffset PS_1_4::texm3x3spec_RegMods[] = {
-	{8, R_BASE, 1},
-	{15, R_BASE, 2},
-	{21, C_BASE, 2},
-	{33, C_BASE, 2},
-
-};
-
-PS_1_4::MacroRegModify PS_1_4::texm3x3spec_MacroMods = {
-	texm3x3spec, ARRAYSIZE(texm3x3spec),
-	texm3x3spec_RegMods, ARRAYSIZE(texm3x3spec_RegMods)
-};
-
-
-/* ********************* END OF CLASS STATIC DATA ********************************* */
-
-PS_1_4::PS_1_4()
-{
-	// allocate enough room for a large pixel shader
-	mPhase1TEX_mi.reserve(50);
-	mPhase2TEX_mi.reserve(30);
-	mPhase1ALU_mi.reserve(100);
-	mPhase2ALU_mi.reserve(100);
-
-
-	mSymbolTypeLib = PS_1_4_SymbolTypeLib;
-	mSymbolTypeLibCnt = ARRAYSIZE(PS_1_4_SymbolTypeLib);
-	mRootRulePath = PS_1_x_RulePath;
-	mRulePathLibCnt = ARRAYSIZE(PS_1_x_RulePath);
-	// tell compiler what the symbol id is for a numeric value
-	mValueID = sid_VALUE;
-	// The type library must have text definitions initialized
-	// before compiler is invoked
-
-	// only need to initialize the rule database once
-	if(LibInitialized == false) {
-		InitSymbolTypeLib();
-		LibInitialized = true;
-	}
-
-	// set initial context to recognize PS base instructions
-	mActiveContexts = ckp_PS_BASE;
-
-}
-
-
-bool PS_1_4::bindMachineInstInPassToFragmentShader(const MachineInstContainer & PassMachineInstructions)
-{
-  size_t instIDX = 0;
-  size_t instCount = PassMachineInstructions.size();
-  bool error = false;
-
-  while ((instIDX < instCount) && !error) {
-    switch(PassMachineInstructions[instIDX]) {
-      case mi_COLOROP1:
-        if((instIDX+7) < instCount)
-          glColorFragmentOp1ATI(PassMachineInstructions[instIDX+1], // op
-            PassMachineInstructions[instIDX+2], // dst
-            PassMachineInstructions[instIDX+3], // dstMask
-            PassMachineInstructions[instIDX+4], // dstMod
-            PassMachineInstructions[instIDX+5], // arg1
-            PassMachineInstructions[instIDX+6], // arg1Rep
-            PassMachineInstructions[instIDX+7]);// arg1Mod
-        instIDX += 8;
-        break;
-
-      case mi_COLOROP2:
-        if((instIDX+10) < instCount)
-          glColorFragmentOp2ATI(PassMachineInstructions[instIDX+1], // op
-            PassMachineInstructions[instIDX+2], // dst
-            PassMachineInstructions[instIDX+3], // dstMask
-            PassMachineInstructions[instIDX+4], // dstMod
-            PassMachineInstructions[instIDX+5], // arg1
-            PassMachineInstructions[instIDX+6], // arg1Rep
-            PassMachineInstructions[instIDX+7], // arg1Mod
-            PassMachineInstructions[instIDX+8], // arg2
-            PassMachineInstructions[instIDX+9], // arg2Rep
-            PassMachineInstructions[instIDX+10]);// arg2Mod
-        instIDX += 11;
-        break;
-
-      case mi_COLOROP3:
-        if((instIDX+13) < instCount)
-          glColorFragmentOp3ATI(PassMachineInstructions[instIDX+1], // op
-            PassMachineInstructions[instIDX+2],  // dst
-            PassMachineInstructions[instIDX+3],  // dstMask
-            PassMachineInstructions[instIDX+4],  // dstMod
-            PassMachineInstructions[instIDX+5],  // arg1
-            PassMachineInstructions[instIDX+6],  // arg1Rep
-            PassMachineInstructions[instIDX+7],  // arg1Mod
-            PassMachineInstructions[instIDX+8],  // arg2
-            PassMachineInstructions[instIDX+9],  // arg2Rep
-            PassMachineInstructions[instIDX+10], // arg2Mod
-            PassMachineInstructions[instIDX+11], // arg2
-            PassMachineInstructions[instIDX+12], // arg2Rep
-            PassMachineInstructions[instIDX+13]);// arg2Mod
-        instIDX += 14;
-        break;
-
-      case mi_ALPHAOP1:
-        if((instIDX+6) < instCount)
-          glAlphaFragmentOp1ATI(PassMachineInstructions[instIDX+1], // op
-            PassMachineInstructions[instIDX+2],   // dst
-            PassMachineInstructions[instIDX+3],   // dstMod
-            PassMachineInstructions[instIDX+4],   // arg1
-            PassMachineInstructions[instIDX+5],   // arg1Rep
-            PassMachineInstructions[instIDX+6]);  // arg1Mod
-        instIDX += 7;
-        break;
-
-      case mi_ALPHAOP2:
-        if((instIDX+9) < instCount)
-          glAlphaFragmentOp2ATI(PassMachineInstructions[instIDX+1], // op
-            PassMachineInstructions[instIDX+2],   // dst
-            PassMachineInstructions[instIDX+3],   // dstMod
-            PassMachineInstructions[instIDX+4],   // arg1
-            PassMachineInstructions[instIDX+5],   // arg1Rep
-            PassMachineInstructions[instIDX+6],   // arg1Mod
-            PassMachineInstructions[instIDX+7],   // arg2
-            PassMachineInstructions[instIDX+8],   // arg2Rep
-            PassMachineInstructions[instIDX+9]);  // arg2Mod
-        instIDX += 10;
-        break;
-
-      case mi_ALPHAOP3:
-        if((instIDX+12) < instCount)
-          glAlphaFragmentOp3ATI(PassMachineInstructions[instIDX+1], // op
-            PassMachineInstructions[instIDX+2],   // dst
-            PassMachineInstructions[instIDX+3],   // dstMod
-            PassMachineInstructions[instIDX+4],   // arg1
-            PassMachineInstructions[instIDX+5],   // arg1Rep
-            PassMachineInstructions[instIDX+6],   // arg1Mod
-            PassMachineInstructions[instIDX+7],   // arg2
-            PassMachineInstructions[instIDX+8],   // arg2Rep
-            PassMachineInstructions[instIDX+9],   // arg2Mod
-            PassMachineInstructions[instIDX+10],  // arg2
-            PassMachineInstructions[instIDX+11],  // arg2Rep
-            PassMachineInstructions[instIDX+12]); // arg2Mod
-        instIDX += 13;
-        break;
-
-      case mi_SETCONSTANTS:
-        if((instIDX+2) < instCount)
-          glSetFragmentShaderConstantATI(PassMachineInstructions[instIDX+1], // dst
-            &mConstants[PassMachineInstructions[instIDX+2]]);
-        instIDX += 3;
-        break;
-
-      case mi_PASSTEXCOORD:
-        if((instIDX+3) < instCount)
-          glPassTexCoordATI(PassMachineInstructions[instIDX+1], // dst
-            PassMachineInstructions[instIDX+2], // coord
-            PassMachineInstructions[instIDX+3]); // swizzle
-        instIDX += 4;
-        break;
-
-      case mi_SAMPLEMAP:
-        if((instIDX+3) < instCount)
-          glSampleMapATI(PassMachineInstructions[instIDX+1], // dst
-            PassMachineInstructions[instIDX+2], // interp
-            PassMachineInstructions[instIDX+3]); // swizzle
-        instIDX += 4;
-        break;
-
-	  default:
-		instIDX = instCount;
-		// should generate an error since an unknown instruction was found
-		// instead for now the bind process is terminated and the fragment program may still function
-		// but its output may not be what was programmed
-
-    } // end of switch
-
-    error = (glGetError() != GL_NO_ERROR);
-  }// end of while
-
-  return !error;
-
-}
-
-
-size_t PS_1_4::getMachineInst( size_t Idx)
-{
-	if (Idx < mPhase1TEX_mi.size()) {
-		return mPhase1TEX_mi[Idx];
-	}
-	else {
-		Idx -= mPhase1TEX_mi.size();
-		if (Idx < mPhase1ALU_mi.size()) {
-			return mPhase1ALU_mi[Idx];
-		}
-		else {
-			Idx -= mPhase1ALU_mi.size();
-			if (Idx < mPhase2TEX_mi.size()) {
-				return mPhase2TEX_mi[Idx];
-			}
-			else {
-				Idx -= mPhase2TEX_mi.size();
-				if (Idx < mPhase2ALU_mi.size()) {
-					return mPhase2ALU_mi[Idx];
-				}
-
-			}
-
-		}
-
-	}
-
-	return 0;
-
-}
-
-
-void PS_1_4::addMachineInst(const PhaseType phase, const UINT32 inst)
-{
-	switch(phase) {
-
-		case ptPHASE1TEX:
-			mPhase1TEX_mi.push_back(inst);
-			break;
-
-		case ptPHASE1ALU:
-			mPhase1ALU_mi.push_back(inst);
-			break;
-
-		case ptPHASE2TEX:
-			mPhase2TEX_mi.push_back(inst);
-
-			break;
-
-		case ptPHASE2ALU:
-			mPhase2ALU_mi.push_back(inst);
-			break;
-
-
-	} // end switch(phase)
-
-}
-
-size_t PS_1_4::getMachineInstCount()
-{
-
-	return (mPhase1TEX_mi.size() + mPhase1ALU_mi.size() + mPhase2TEX_mi.size() + mPhase2ALU_mi.size());
-}
-
-
-bool PS_1_4::bindAllMachineInstToFragmentShader()
-{
-	bool passed;
-
-	// there are 4 machine instruction ques to pass to the ATI fragment shader
-	passed = bindMachineInstInPassToFragmentShader(mPhase1TEX_mi);
-	passed &= bindMachineInstInPassToFragmentShader(mPhase1ALU_mi);
-	passed &= bindMachineInstInPassToFragmentShader(mPhase2TEX_mi);
-	passed &= bindMachineInstInPassToFragmentShader(mPhase2ALU_mi);
-	return passed;
-
-}
-
-
-bool PS_1_4::expandMacro(const MacroRegModify & MacroMod)
-{
-
-	RegModOffset * regmod;
-
-	// set source and destination registers in macro expansion
-	for (UINT32 i = 0; i < MacroMod.RegModSize; i++) {
-		regmod = &MacroMod.RegMods[i];
-		MacroMod.Macro[regmod->MacroOffset].mID = regmod->RegisterBase + mOpParrams[regmod->OpParramsIndex].Arg;
-
-	}
-
-	// turn macro support on so that ps.1.4 ALU instructions get put in phase 1 alu instruction sequence container
-	mMacroOn = true;
-	// pass macro tokens on to be turned into machine instructions
-	// expand macro to ps.1.4 by doing recursive call to doPass2
-	bool passed = Pass2scan(MacroMod.Macro, MacroMod.MacroSize);
-	mMacroOn = false;
-
-	return passed;
-}
-
-
-bool PS_1_4::BuildMachineInst()
-{
-
-	// check the states to see if a machine instruction can be assembled
-
-	// assume all arguments have been set up
-	bool passed = false;
-
-	
-
-	passed = true; // assume everything will go okay untill proven otherwise
-
-	// start with machine NOP instuction
-	// this is used after the switch to see if an instruction was set up
-	// determine which MachineInstID is required based on the op instruction
-	mOpType = mi_NOP;
-
-	switch(mOpInst) {
-		// ALU operations
-		case sid_ADD:
-		case sid_SUB:
-		case sid_MUL:
-		case sid_MAD:
-		case sid_LRP:
-		case sid_MOV:
-		case sid_CMP:
-		case sid_CND:
-		case sid_DP2ADD:
-		case sid_DP3:
-		case sid_DP4:
-			mOpType = (MachineInstID)(mi_COLOROP1 + mArgCnt - 1);
-
-			// if context is ps.1.x and Macro not on or a phase marker was found then put all ALU ops in phase 2 ALU container
-			if (((mActiveContexts & ckp_PS_1_1) && !mMacroOn) || mPhaseMarkerFound) mInstructionPhase = ptPHASE2ALU;
-			else mInstructionPhase = ptPHASE1ALU;
-			// check for alpha op in destination register which is OpParrams[0]
-			// if no Mask for destination then make it .rgba
-			if(mOpParrams[0].MaskRep == 0) mOpParrams[0].MaskRep =
-			GL_RED_BIT_ATI | GL_GREEN_BIT_ATI | GL_BLUE_BIT_ATI | ALPHA_BIT;
-			if (mOpParrams[0].MaskRep & ALPHA_BIT) {
-				mDo_Alpha = true;
-				mOpParrams[0].MaskRep -= ALPHA_BIT;
-				if(mOpParrams[0].MaskRep == 0) mOpType = mi_NOP; // only do alpha op
-			}
-			break;
-
-		case sid_TEXCRD:
-			mOpType = mi_PASSTEXCOORD;
-			if (mPhaseMarkerFound) mInstructionPhase = ptPHASE2TEX;
-			else mInstructionPhase = ptPHASE1TEX;
-			break;
-
-		case sid_TEXLD:
-			mOpType = mi_SAMPLEMAP;
-			if (mPhaseMarkerFound) mInstructionPhase = ptPHASE2TEX;
-			else mInstructionPhase = ptPHASE1TEX;
-			break;
-
-		case sid_TEX: // PS_1_1 emulation
-			mOpType = mi_TEX;
-			mInstructionPhase = ptPHASE1TEX;
-			break;
-
-		case sid_TEXCOORD: // PS_1_1 emulation
-			mOpType = mi_TEXCOORD;
-			mInstructionPhase = ptPHASE1TEX;
-			break;
-
-		case sid_TEXREG2AR:
-			passed = expandMacro(texreg2ar_MacroMods);
-			break;
-
-		case sid_TEXREG2GB:
-			passed = expandMacro(texreg2gb_MacroMods);
-			break;
-
-		case sid_TEXDP3:
-			passed = expandMacro(texdp3_MacroMods);
-			break;
-
-		case sid_TEXDP3TEX:
-			passed = expandMacro(texdp3tex_MacroMods);
-			break;
-
-		case sid_TEXM3X2PAD:
-			passed = expandMacro(texm3x2pad_MacroMods);
-			break;
-
-		case sid_TEXM3X2TEX:
-			passed = expandMacro(texm3x2tex_MacroMods);
-			break;
-
-		case sid_TEXM3X3PAD:
-			// only 2 texm3x3pad instructions allowed
-			// use count to modify macro to select which mask to use
-			if(mTexm3x3padCount<2) {
-				texm3x3pad[4].mID = sid_R + mTexm3x3padCount;
-				mTexm3x3padCount++;
-				passed = expandMacro(texm3x3pad_MacroMods);
-
-			}
-			else passed = false;
-
-			break;
-
-		case sid_TEXM3X3TEX:
-			passed = expandMacro(texm3x3tex_MacroMods);
-			break;
-
-		case sid_DEF:
-			mOpType = mi_SETCONSTANTS;
-			mInstructionPhase = ptPHASE1TEX;
-			break;
-
-		case sid_PHASE: // PS_1_4 only
-			mPhaseMarkerFound = true;
-			break;
-
-	} // end of switch
-
-	if(passed) passed = expandMachineInstruction();
-
-	return passed;
-}
-
-
-bool PS_1_4::expandMachineInstruction()
-{
-	// now push instructions onto MachineInstructions container
-	// assume that an instruction will be expanded
-	bool passed = true;
-
-	if (mOpType != mi_NOP) {
-
-		// a machine instruction will be built
-		// this is currently the last one being built so keep track of it
-		if (mInstructionPhase == ptPHASE2ALU) { 
-			mSecondLastInstructionPos = mLastInstructionPos;
-			mLastInstructionPos = mPhase2ALU_mi.size();
-		}
-
-
-		switch (mOpType) {
-			case mi_COLOROP1:
-			case mi_COLOROP2:
-			case mi_COLOROP3:
-				{
-					addMachineInst(mInstructionPhase, mOpType);
-					addMachineInst(mInstructionPhase, mSymbolTypeLib[mOpInst].mPass2Data);
-					// send all parameters to machine inst container
-					for(int i=0; i<=mArgCnt; i++) {
-						addMachineInst(mInstructionPhase, mOpParrams[i].Arg);
-						addMachineInst(mInstructionPhase, mOpParrams[i].MaskRep);
-						addMachineInst(mInstructionPhase, mOpParrams[i].Mod);
-						// check if source register read is valid in this phase
-						passed &= isRegisterReadValid(mInstructionPhase, i);
-					}
-
-					// record which registers were written to and in which phase
-					// mOpParrams[0].Arg is always the destination register r0 -> r5
-					updateRegisterWriteState(mInstructionPhase);
-
-				}
-				break;
-
-			case mi_SETCONSTANTS:
-				addMachineInst(mInstructionPhase, mOpType);
-				addMachineInst(mInstructionPhase, mOpParrams[0].Arg); // dst
-				addMachineInst(mInstructionPhase, mConstantsPos); // index into constants array
-				break;
-
-			case mi_PASSTEXCOORD:
-			case mi_SAMPLEMAP:
-				// if source is a temp register than place instruction in phase 2 Texture ops
-				if ((mOpParrams[1].Arg >= GL_REG_0_ATI) && (mOpParrams[1].Arg <= GL_REG_5_ATI)) {
-					mInstructionPhase = ptPHASE2TEX;
-				}
-
-				addMachineInst(mInstructionPhase, mOpType);
-				addMachineInst(mInstructionPhase, mOpParrams[0].Arg); // dst
-				addMachineInst(mInstructionPhase, mOpParrams[1].Arg); // coord
-				addMachineInst(mInstructionPhase, mOpParrams[1].MaskRep + GL_SWIZZLE_STR_ATI); // swizzle
-				// record which registers were written to and in which phase
-				// mOpParrams[0].Arg is always the destination register r0 -> r5
-				updateRegisterWriteState(mInstructionPhase);
-				break;
-
-			case mi_TEX: // PS_1_1 emulation - turn CISC into RISC - phase 1
-				addMachineInst(mInstructionPhase, mi_SAMPLEMAP);
-				addMachineInst(mInstructionPhase, mOpParrams[0].Arg); // dst
-				// tex tx becomes texld rx, tx with x: 0 - 3
-				addMachineInst(mInstructionPhase, mOpParrams[0].Arg - GL_REG_0_ATI + GL_TEXTURE0_ARB); // interp
-				// default to str which fills rgb of destination register
-				addMachineInst(mInstructionPhase, GL_SWIZZLE_STR_ATI); // swizzle
-				// record which registers were written to and in which phase
-				// mOpParrams[0].Arg is always the destination register r0 -> r5
-				updateRegisterWriteState(mInstructionPhase);
-				break;
-
-			case mi_TEXCOORD: // PS_1_1 emulation - turn CISC into RISC - phase 1
-				addMachineInst(mInstructionPhase, mi_PASSTEXCOORD);
-				addMachineInst(mInstructionPhase, mOpParrams[0].Arg); // dst
-				// texcoord tx becomes texcrd rx, tx with x: 0 - 3
-				addMachineInst(mInstructionPhase, mOpParrams[0].Arg - GL_REG_0_ATI + GL_TEXTURE0_ARB); // interp
-				// default to str which fills rgb of destination register
-				addMachineInst(mInstructionPhase, GL_SWIZZLE_STR_ATI); // swizzle
-				// record which registers were written to and in which phase
-				// mOpParrams[0].Arg is always the destination register r0 -> r5
-				updateRegisterWriteState(mInstructionPhase);
-				break;
-
-            case mi_ALPHAOP1:
-            case mi_ALPHAOP2:
-            case mi_ALPHAOP3:
-            case mi_TEXREG2RGB:
-            case mi_NOP:
-                break;
-
-
-		} // end of switch (mOpType)
-	} // end of if (mOpType != mi_NOP)
-
-	if(mDo_Alpha) {
-		// process alpha channel
-		//
-		// a scaler machine instruction will be built
-		// this is currently the last one being built so keep track of it
-		if (mInstructionPhase == ptPHASE2ALU) { 
-			mSecondLastInstructionPos = mLastInstructionPos;
-			mLastInstructionPos = mPhase2ALU_mi.size();
-		}
-
-		MachineInstID alphaoptype = (MachineInstID)(mi_ALPHAOP1 + mArgCnt - 1);
-		addMachineInst(mInstructionPhase, alphaoptype);
-		addMachineInst(mInstructionPhase, mSymbolTypeLib[mOpInst].mPass2Data);
-		// put all parameters in instruction que
-		for(int i=0; i<=mArgCnt; i++) {
-			addMachineInst(mInstructionPhase, mOpParrams[i].Arg);
-			// destination parameter has no mask since it is the alpha channel
-			// don't push mask for parrameter 0 (dst)
-			if(i>0) addMachineInst(mInstructionPhase, mOpParrams[i].MaskRep);
-			addMachineInst(mInstructionPhase, mOpParrams[i].Mod);
-			// check if source register read is valid in this phase
-			passed &= isRegisterReadValid(mInstructionPhase, i);
-		}
-
-		updateRegisterWriteState(mInstructionPhase);
-	}
-
-	// instruction passed on to machine instruction so clear the pipe
-	clearMachineInstState();
-
-	return passed;
-
-}
-
-
-void PS_1_4::updateRegisterWriteState(const PhaseType phase)
-{
-	int reg_offset = mOpParrams[0].Arg - GL_REG_0_ATI;
-
-	switch(phase) {
-
-		case ptPHASE1TEX:
-		case ptPHASE1ALU:
-			Phase_RegisterUsage[reg_offset].Phase1Write = true;
-			break;
-
-		case ptPHASE2TEX:
-		case ptPHASE2ALU:
-			Phase_RegisterUsage[reg_offset].Phase2Write = true;
-			break;
-
-	} // end switch(phase)
-
-}
-
-
-bool PS_1_4::isRegisterReadValid(const PhaseType phase, const int param)
-{
-	bool passed = true; // assume everything will go alright
-	// if in phase 2 ALU and argument is a source
-	if((phase == ptPHASE2ALU) && (param>0)) {
-		// is source argument a temp register r0 - r5?
-		if((mOpParrams[param].Arg >= GL_REG_0_ATI) && (mOpParrams[param].Arg <= GL_REG_5_ATI)) {
-			int reg_offset = mOpParrams[param].Arg - GL_REG_0_ATI;
-			// if register was not written to in phase 2 but was in phase 1
-			if((Phase_RegisterUsage[reg_offset].Phase2Write == false) && Phase_RegisterUsage[reg_offset].Phase1Write) {
-				// only perform register pass if there are ALU instructions in phase 1
-				
-				if(mPhase1ALU_mi.size() > 0) {
-					// build machine instructions for passing a register from phase 1 to phase 2
-					// NB: only rgb components of register will get passed
-
-					addMachineInst(ptPHASE2TEX, mi_PASSTEXCOORD);
-					addMachineInst(ptPHASE2TEX, mOpParrams[param].Arg); // dst
-					addMachineInst(ptPHASE2TEX, mOpParrams[param].Arg); // coord
-					addMachineInst(ptPHASE2TEX, GL_SWIZZLE_STR_ATI); // swizzle
-					// mark register as being written to
-					Phase_RegisterUsage[reg_offset].Phase2Write = true;
-				}
-
-			}
-			// register can not be used because it has not been written to previously
-			else passed = false;
-		}
-
-	}
-
-	return passed;
-
-}
-
-
-void PS_1_4::optimize()
-{
-	// perform some optimizations on ps.1.1 machine instructions
-	if (mActiveContexts & ckp_PS_1_1) {
-		// need to check last few instructions to make sure r0 is set
-		// ps.1.1 emulation uses r4 for r0 so last couple of instructions will probably require
-		// changine destination register back to r0
-		if (mLastInstructionPos < mPhase2ALU_mi.size()) {
-			// first argument at mLastInstructionPos + 2 is destination register for all ps.1.1 ALU instructions
-			mPhase2ALU_mi[mLastInstructionPos + 2] = GL_REG_0_ATI; 
-			// if was an alpha op only then modify second last instruction destination register
-			if ((mPhase2ALU_mi[mLastInstructionPos] == mi_ALPHAOP1) ||
-				(mPhase2ALU_mi[mLastInstructionPos] == mi_ALPHAOP2) ||
-				(mPhase2ALU_mi[mLastInstructionPos] == mi_ALPHAOP3)
-				
-				) {
-
-				mPhase2ALU_mi[mSecondLastInstructionPos + 2] = GL_REG_0_ATI; 
-			}
-
-		}// end if (mLastInstructionPos < mMachineInstructions.size())
-
-	}// end if (mActiveContexts & ckp_PS_1_1)
-
-}
-
-
-void PS_1_4::clearMachineInstState()
-{
-	// set current Machine Instruction State to baseline
-	mOpType = mi_NOP;
-	mOpInst = sid_INVALID;
-	mDo_Alpha = false;
-	mArgCnt = 0;
-
-	for(int i=0; i<MAXOPPARRAMS; i++) {
-		mOpParrams[i].Arg = GL_NONE;
-		mOpParrams[i].Filled = false;
-		mOpParrams[i].MaskRep = GL_NONE;
-		mOpParrams[i].Mod = GL_NONE;
-	}
-
-}
-
-
-void PS_1_4::clearAllMachineInst()
-{
-
-	mPhase1TEX_mi.clear();
-	mPhase1ALU_mi.clear();
-	mPhase2TEX_mi.clear();
-	mPhase2ALU_mi.clear();
-
-	// reset write state for all registers
-	for(int i = 0; i<6; i++) {
-		Phase_RegisterUsage[i].Phase1Write = false;
-		Phase_RegisterUsage[i].Phase2Write = false;
-
-	}
-
-	mPhaseMarkerFound = false;
-	mConstantsPos = -4;
-	// keep track of the last instruction built
-	// this info is used at the end of pass 2 to optimize the machine code
-	mLastInstructionPos = 0;
-	mSecondLastInstructionPos = 0;
-
-	mMacroOn = false;  // macro's off at the beginning
-	mTexm3x3padCount = 0;
-
-}
-
-bool PS_1_4::doPass2()
-{
-	clearAllMachineInst();
-	// if pass 2 was successful, optimize the machine instructions
-	bool passed = Pass2scan(&mTokenInstructions[0], mTokenInstructions.size());
-	if (passed) optimize();  
-
-	return passed;
-
-}
-
-
-bool PS_1_4::Pass2scan(const TokenInst * Tokens, const size_t size)
-{
-
-	// execute TokenInstructions to build MachineInstructions
-	bool passed = true;
-	SymbolDef* cursymboldef;
-	UINT32 ActiveNTTRuleID;
-
-	clearMachineInstState();
-
-
-	// iterate through all the tokens and build machine instruction
-	// for each machine instruction need: optype, opinst, and up to 5 parameters
-	for(UINT32 i = 0; i < size; i++) {
-		// lookup instruction type in library
-
-		cursymboldef = &mSymbolTypeLib[Tokens[i].mID];
-		ActiveNTTRuleID = Tokens[i].mNTTRuleID;
-		mCurrentLine = Tokens[i].mLine;
-		mCharPos = Tokens[i].mPos;
-
-		switch(ActiveNTTRuleID) {
-
-			case sid_CONSTANT:
-			case sid_COLOR:
-			case sid_REG_PS1_4:
-			case sid_TEX_PS1_4:
-			case sid_REG_PS1_1_3:
-			case sid_TEX_PS1_1_3:
-				// registars can be used for read and write so they can be used for dst and arg
-				passed = setOpParram(cursymboldef);
-				break;
-
-
-			case sid_DEFCONST:
-			case sid_UNARYOP:
-			case sid_BINARYOP:
-			case sid_TERNARYOP:
-			case sid_TEXOP_PS1_1_3:
-			case sid_TEXOP_PS1_4:
-			case sid_PHASEMARKER:
-			case sid_TEXCISCOP_PS1_1_3:
-				// if the last instruction has not been passed on then do it now
-				// make sure the pipe is clear for a new instruction
-				BuildMachineInst();
-				if(mOpInst == sid_INVALID) {
-					mOpInst = cursymboldef->mID;
-				}
-				else passed = false;
-				break;
-
-			case sid_DSTMASK:
-			case sid_SRCREP:
-			case sid_TEXSWIZZLE:
-				// could be a dst mask or a arg replicator
-				// if dst mask and alpha included then make up a alpha instruction: maybe best to wait until instruction args completed
-				mOpParrams[mArgCnt].MaskRep = cursymboldef->mPass2Data;
-				break;
-
-			case sid_DSTMOD:
-			case sid_DSTSAT:
-			case sid_PRESRCMOD:
-			case sid_POSTSRCMOD:
-				mOpParrams[mArgCnt].Mod |= cursymboldef->mPass2Data;
-				break;
-
-
-			case sid_NUMVAL:
-				passed = setOpParram(cursymboldef);
-				// keep track of how many values are used
-				// update Constants array position
-				mConstantsPos++;
-				break;
-
-			case sid_SEPERATOR:
-				mArgCnt++;
-				break;
-		} // end of switch
-
-		if(!passed) break;
-	}// end of for: i<TokenInstCnt
-
-	// check to see if there is still an instruction left in the pipe
-	if(passed) {
-		BuildMachineInst();
-		// if there are no more instructions in the pipe than OpInst should be invalid
-		if(mOpInst != sid_INVALID) passed = false;
-	}
-
-
-	return passed;
-}
-
-
-
-bool PS_1_4::setOpParram(const SymbolDef* symboldef)
-{
-  bool success = true;
-  if(mArgCnt<MAXOPPARRAMS) {
-    if(mOpParrams[mArgCnt].Filled) mArgCnt++;
-  }
-  if (mArgCnt<MAXOPPARRAMS) {
-    mOpParrams[mArgCnt].Filled = true;
-    mOpParrams[mArgCnt].Arg = symboldef->mPass2Data;
-  }
-  else success = false;
-
-  return success;
-}
-
-
-
-
-// *********************************************************************************
-//  this is where the tests are carried out to make sure the PS_1_4 compiler works
-
-#ifdef _DEBUG
-// check the functionality of functions in PS_1_4: each test will print to the output file PASSED of FAILED
-void PS_1_4::test()
-{
-  
-
-  struct test1result{
-    char character;
-    int line;
-  };
-
-  struct testfloatresult{
-    char *teststr;
-    float fvalue;
-    int charsize;
-  };
-
-  char TestStr1[] = "   \n\r  //c  \n\r// test\n\r  \t  c   - \n\r ,  e";
-  test1result test1results[] = {
-    {'c', 4},
-    {'-', 4},
-    {',', 5},
-    {'e', 5}
-  };
-
-  testfloatresult testfloatresults[] = {
-    {"1 test", 1.0f, 1},
-    {"2.3f test", 2.3f, 3},
-    {"-0.5 test", -0.5f, 4},
-    {" 23.6 test", 23.6f, 5},
-    {"  -0.021 test", -0.021f, 8},
-    {"12 test", 12.0f, 2},
-    {"3test", 3.0f, 1}
-  };
-
-
-
-  SymbolID test3result[] = { sid_MOV, sid_COMMA, sid_MUL, sid_ADD, sid_NEGATE, sid_T0
-  };
-
-  #define PART2INST 17
-  char TestStr3[] = "mov r0,c1";
-  char TestSymbols[] = "mov";
-  char passed[] = "PASSED\n";
-  char failed[] = "***** FAILED *****\n";
-
-  size_t resultID = 0;
-
-  // loop variable used in for loops
-  int i;
-  fp = fopen("ASMTests.txt", "wt");
-
-// **************************************************************
-  // first test: see if positionToNextSymbol can find a valid Symbol
-  fprintf(fp, "Testing: positionToNextSymbol\n");
-
-  mSource = TestStr1;
-  mCharPos = 0;
-  mCurrentLine = 1;
-  mEndOfSource = (int)strlen(mSource);
-  while (positionToNextSymbol()) {
-    fprintf(fp,"  character found: [%c]   Line:%d  : " , mSource[mCharPos], mCurrentLine);
-    if( (mSource[mCharPos] == test1results[resultID].character) && (mCurrentLine==test1results[resultID].line)) fprintf(fp, passed);
-    else fprintf(fp, failed);
-    resultID++;
-    mCharPos++;
-  }
-  fprintf(fp, "finished testing: positionToNextSymbol\n");
-
-
-// **************************************************************
-  // Second Test
-  // did the type lib get initialized properly with a default name index
-  fprintf(fp, "\nTesting: getTypeDefText\n");
-  const char* resultstr = getTypeDefText(sid_MOV);
-  fprintf(fp, "  default name of mov is: [%s]: %s", resultstr, (strcmp("mov", resultstr)==0)?passed:failed);
-  fprintf(fp, "finished testing: getTypeDefText\n");
-
-// **************************************************************
-// **************************************************************
-  // fourth test - does isSymbol work correctly
-  fprintf(fp, "\nTesting: isSymbol\n");
-  mSource = TestStr3;
-  mCharPos = 0;
-  fprintf(fp, "  before: [%s]\n", mSource + mCharPos);
-  fprintf(fp, "  symbol to find: [%s]\n", TestSymbols);
-  if(isSymbol(TestSymbols, resultID)) {
-    fprintf(fp, "  after: [%s] : %s", mSource + resultID + 1, (mSource[resultID + 1] == 'r')? passed:failed);
-  }
-  else fprintf(fp, failed);
-  fprintf(fp,"  symbol size: %d\n", resultID);
-  fprintf(fp, "finished testing: isSymbol\n");
-
-// **************************************************************
-  fprintf(fp, "\nTesting: isFloatValue\n");
-  float fvalue = 0;
-  size_t charsize = 0;
-  char teststrfloat1[] = "1 test";
-  mCharPos = 0;
-  int testsize = ARRAYSIZE(testfloatresults);
-  for(i=0; i<testsize; i++) {
-    mSource = testfloatresults[i].teststr;
-    fprintf(fp, "  test string [%s]\n", mSource);
-    isFloatValue(fvalue, charsize);
-    fprintf(fp, "   value is: %f should be %f: %s", fvalue, testfloatresults[i].fvalue, (fvalue == testfloatresults[i].fvalue)?passed:failed);
-    fprintf(fp, "   char size is: %d should be %d: %s", charsize, testfloatresults[i].charsize, (charsize == testfloatresults[i].charsize)?passed:failed);
-  }
-
-  fprintf(fp, "finished testing: isFloatValue\n");
-
-
-// **************************************************************
-
-  // simple compile test:
-  char CompileTest1src[] = "ps.1.4\n";
-  SymbolID CompileTest1result[] = {sid_PS_1_4};
-
-  testCompile("Basic PS_1_4", CompileTest1src, CompileTest1result, ARRAYSIZE(CompileTest1result));
-
-// **************************************************************
-  char CompileTest2src[] = "ps.1.1\n";
-  SymbolID CompileTest2result[] = {sid_PS_1_1};
-
-  testCompile("Basic PS_1_1", CompileTest2src, CompileTest2result, ARRAYSIZE(CompileTest2result));
-
-// **************************************************************
-  char CompileTest3src[] = "ps.1.4\ndef c0, 1.0, 2.0, 3.0, 4.0\n";
-  SymbolID CompileTest3result[] = {sid_PS_1_4, sid_DEF, sid_C0, sid_COMMA, sid_VALUE, sid_COMMA,
-		sid_VALUE, sid_COMMA, sid_VALUE, sid_COMMA, sid_VALUE};
-
-  testCompile("PS_1_4 with defines", CompileTest3src, CompileTest3result, ARRAYSIZE(CompileTest3result));
-
-
-// **************************************************************
-  char CompileTest4src[] = "ps.1.4\n//test kkl \ndef c0, 1.0, 2.0, 3.0, 4.0\ndef c3, 1.0, 2.0, 3.0, 4.0\n";
-  SymbolID CompileTest4result[] = {sid_PS_1_4, sid_DEF, sid_C0, sid_COMMA, sid_VALUE, sid_COMMA,
-		sid_VALUE, sid_COMMA, sid_VALUE, sid_COMMA, sid_VALUE,sid_DEF, sid_C3, sid_COMMA, sid_VALUE, sid_COMMA,
-		sid_VALUE, sid_COMMA, sid_VALUE, sid_COMMA, sid_VALUE};
-
-  testCompile("PS_1_4 with 2 defines", CompileTest4src, CompileTest4result, ARRAYSIZE(CompileTest4result));
-
-// **************************************************************
-  char CompileTest5src[] = "ps.1.4\ndef c0, 1.0, 2.0, 3.0, 4.0\n";
-  SymbolID CompileTest5result[] = {sid_PS_1_4, sid_DEF, sid_C0, sid_COMMA, sid_VALUE, sid_COMMA,
-		sid_VALUE, sid_COMMA, sid_VALUE, sid_COMMA, sid_VALUE};
-  GLuint CompileTest5MachinInstResults[] = {mi_SETCONSTANTS, GL_CON_0_ATI, 0};
-
-  testCompile("PS_1_4 with defines", CompileTest3src, CompileTest3result, ARRAYSIZE(CompileTest3result), CompileTest5MachinInstResults, ARRAYSIZE(CompileTest5MachinInstResults));
-// **************************************************************
-  char CompileTest6Src[] = "ps.1.4\nmov r0.xzw, c1 \nmul r3, r2, c3";
-  SymbolID CompileTest6result[] = {sid_PS_1_4, sid_MOV, sid_R0, sid_RBA, sid_COMMA, sid_C1,
-	  sid_MUL, sid_R3, sid_COMMA, sid_R2, sid_COMMA, sid_C3};
-  
-  testCompile("PS_1_4 ALU simple", CompileTest6Src, CompileTest6result, ARRAYSIZE(CompileTest6result));
-
-// **************************************************************
-  // test to see if PS_1_4 compile pass 2 generates the proper machine instructions
-	char CompileTest7Src[] = "ps.1.4\ndef c0,1.0,2.0,3.0,4.0\nmov_x8 r1,v0\nmov r0,r1.g";
-
-	SymbolID CompileTest7result[] = {
-		sid_PS_1_4, sid_DEF, sid_C0, sid_COMMA, sid_VALUE, sid_COMMA,
-		sid_VALUE, sid_COMMA, sid_VALUE, sid_COMMA, sid_VALUE, sid_MOV, sid_X8, sid_R1, sid_COMMA,
-		sid_V0, sid_MOV, sid_R0, sid_COMMA, sid_R1, sid_GGGG
-	};
-
-	GLuint CompileTest7MachinInstResults[] = {
-		mi_SETCONSTANTS, GL_CON_0_ATI, 0,
-		mi_COLOROP1, GL_MOV_ATI, GL_REG_1_ATI, RGB_BITS, GL_8X_BIT_ATI,	GL_PRIMARY_COLOR_ARB, GL_NONE, GL_NONE,
-		mi_ALPHAOP1, GL_MOV_ATI, GL_REG_1_ATI, GL_8X_BIT_ATI, GL_PRIMARY_COLOR_ARB, GL_NONE, GL_NONE,
-		mi_COLOROP1, GL_MOV_ATI, GL_REG_0_ATI, RGB_BITS, GL_NONE,GL_REG_1_ATI, GL_GREEN, GL_NONE,
-		mi_ALPHAOP1, GL_MOV_ATI, GL_REG_0_ATI, GL_NONE, GL_REG_1_ATI, GL_GREEN, GL_NONE,
-	};
-
-
-	testCompile("PS_1_4 ALU simple modifier", CompileTest7Src, CompileTest7result, ARRAYSIZE(CompileTest7result), CompileTest7MachinInstResults, ARRAYSIZE(CompileTest7MachinInstResults));
-
-// **************************************************************
-// test to see if a PS_1_1 can be compiled - pass 1 and pass 2 are checked
-
-	char TestStr5[] = "ps.1.1\ndef c0,1.0,2.0,3.0,4.0\ntex t0\n// test\ntex t1\ndp3 t0.rgb, t0_bx2, t1_bx2\n+ mov r0,1 - t0";
-
-	SymbolID test5result[] = {
-		sid_PS_1_1, sid_DEF, sid_C0, sid_COMMA, sid_VALUE, sid_COMMA,
-		sid_VALUE, sid_COMMA, sid_VALUE, sid_COMMA, sid_VALUE, sid_TEX, sid_1T0, sid_TEX, sid_1T1,
-		sid_DP3, sid_1T0, sid_RGB, sid_COMMA, sid_1T0, sid_BX2, sid_COMMA, sid_1T1, sid_BX2,
-		
-		sid_PLUS, sid_MOV, sid_1R0, sid_COMMA, sid_INVERT, sid_1T0
-	};
-
-	GLuint test5MachinInstResults[] = {
-		mi_SETCONSTANTS, GL_CON_0_ATI, 0, mi_SAMPLEMAP, GL_REG_0_ATI, GL_TEXTURE0_ARB, GL_SWIZZLE_STR_ATI, mi_SAMPLEMAP, GL_REG_1_ATI, GL_TEXTURE1_ARB, GL_SWIZZLE_STR_ATI,
-		mi_COLOROP2, GL_DOT3_ATI, GL_REG_0_ATI, RGB_BITS, GL_NONE, GL_REG_0_ATI, GL_NONE, GL_2X_BIT_ATI | GL_BIAS_BIT_ATI,
-		GL_REG_1_ATI, GL_NONE, GL_2X_BIT_ATI | GL_BIAS_BIT_ATI,
-		mi_COLOROP1, GL_MOV_ATI, GL_REG_0_ATI, RGB_BITS, GL_NONE, GL_REG_0_ATI, GL_NONE, GL_COMP_BIT_ATI, mi_ALPHAOP1, GL_MOV_ATI, GL_REG_0_ATI,
-		GL_NONE, GL_REG_0_ATI, GL_NONE, GL_COMP_BIT_ATI,
-	};
-
-
-	testCompile("PS_1_1 Texture simple", TestStr5, test5result, ARRAYSIZE(test5result), test5MachinInstResults, ARRAYSIZE(test5MachinInstResults));
-
-
-// **************************************************************
-// test to see if a PS_1_2 CISC instructions can be compiled - pass 1 and pass 2 are checked
-
-	char TestStr6[] = "ps.1.2\ndef c0,1.0,2.0,3.0,4.0\ntex t0\n// test\ntexreg2ar t1, t0";
-
-	SymbolID test6result[] = {
-		sid_PS_1_2, sid_DEF, sid_C0, sid_COMMA, sid_VALUE, sid_COMMA,
-		sid_VALUE, sid_COMMA, sid_VALUE, sid_COMMA, sid_VALUE,
-		sid_TEX, sid_1T0,
-		sid_TEXREG2AR, sid_1T1, sid_COMMA, sid_1T0
-	};
-
-	GLuint test6MachinInstResults[] = {
-		// def c0
-		mi_SETCONSTANTS, GL_CON_0_ATI, 0,
-		// texld r0, t0.str
-		mi_SAMPLEMAP, GL_REG_0_ATI, GL_TEXTURE0_ARB, GL_SWIZZLE_STR_ATI,
-		// mov r1.r, r0.a 
-		mi_COLOROP1, GL_MOV_ATI, GL_REG_1_ATI, GL_RED_BIT_ATI, GL_NONE, GL_REG_0_ATI, GL_ALPHA, GL_NONE,
-		// mov r1.g, r0.r
-		mi_COLOROP1, GL_MOV_ATI, GL_REG_1_ATI, GL_GREEN_BIT_ATI, GL_NONE, GL_REG_0_ATI, GL_RED, GL_NONE,
-		// texld r1, r1
-		mi_SAMPLEMAP, GL_REG_1_ATI, GL_REG_1_ATI, GL_SWIZZLE_STR_ATI,
-	};
-
-
-	testCompile("PS_1_2 CISC instructions", TestStr6, test6result, ARRAYSIZE(test6result), test6MachinInstResults, ARRAYSIZE(test6MachinInstResults));
-
-// **************************************************************
-// test to see if a PS_1_4 two phase can be compiled - pass 1 and pass 2 are checked
-
-	char TestStr7[] = "ps.1.4\ndef c0,1.0,2.0,3.0,4.0\ntexld r0, t0\n// test\nmul r0, r0, c0\nphase\ntexld r1, r0\nmul r0,r0,r1\n";
-
-	SymbolID test7result[] = {
-		sid_PS_1_4,
-		// def c0,1.0,2.0,3.0,4.0
-		sid_DEF, sid_C0, sid_COMMA, sid_VALUE, sid_COMMA, sid_VALUE, sid_COMMA, sid_VALUE, sid_COMMA, sid_VALUE,
-		// texld r0, t0
-		sid_TEXLD, sid_R0, sid_COMMA, sid_T0,
-		// mul r0, r0, c0
-		sid_MUL, sid_R0, sid_COMMA, sid_R0, sid_COMMA, sid_C0,
-		// phase
-		sid_PHASE,
-		// texld r1, r0
-		sid_TEXLD, sid_R1, sid_COMMA, sid_R0,
-		// mul r0, r0, r1
-		sid_MUL, sid_R0, sid_COMMA, sid_R0, sid_COMMA, sid_R1,
-
-	};
-
-	GLuint test7MachinInstResults[] = {
-		// def c0
-		mi_SETCONSTANTS, GL_CON_0_ATI, 0,
-		// texld r0, t0.str
-		mi_SAMPLEMAP, GL_REG_0_ATI, GL_TEXTURE0_ARB, GL_SWIZZLE_STR_ATI,
-		// mul r0, r0, c0
-		mi_COLOROP2, GL_MUL_ATI, GL_REG_0_ATI, RGB_BITS, GL_NONE, GL_REG_0_ATI, GL_NONE, GL_NONE, GL_CON_0_ATI, GL_NONE, GL_NONE,
-		mi_ALPHAOP2, GL_MUL_ATI, GL_REG_0_ATI, GL_NONE, GL_REG_0_ATI, GL_NONE, GL_NONE, GL_CON_0_ATI, GL_NONE, GL_NONE,
-		// phase
-		// texld r1, r0.str
-		mi_SAMPLEMAP, GL_REG_1_ATI, GL_REG_0_ATI, GL_SWIZZLE_STR_ATI,
-		// pass ro register
-		mi_PASSTEXCOORD, GL_REG_0_ATI, GL_REG_0_ATI, GL_SWIZZLE_STR_ATI,
-		// mul r0, r0, r1
-		mi_COLOROP2, GL_MUL_ATI, GL_REG_0_ATI, RGB_BITS, GL_NONE, GL_REG_0_ATI, GL_NONE, GL_NONE, GL_REG_1_ATI, GL_NONE, GL_NONE,
-		// mul r0.a, r0
-		mi_ALPHAOP2, GL_MUL_ATI, GL_REG_0_ATI, GL_NONE, GL_REG_0_ATI, GL_NONE, GL_NONE, GL_REG_1_ATI, GL_NONE, GL_NONE,
-	};
-
-
-	testCompile("PS_1_4 texture complex : Phase - instructions", TestStr7, test7result, ARRAYSIZE(test7result), test7MachinInstResults, ARRAYSIZE(test7MachinInstResults));
-
-
-	fclose(fp);
-	fp = NULL;
-	//reset contexts
-
-// **************************************************************
-}
-
-void PS_1_4::testCompile(char* testname, char* teststr, SymbolID* testresult, UINT32 testresultsize, GLuint* MachinInstResults, UINT32 MachinInstResultsSize)
-{
-
-	char passed[] = "PASSED\n";
-	char failed[] = "***** FAILED ****\n";
-
-	setActiveContexts(ckp_PS_BASE);
-
-	fprintf(fp, "\n*** TESTING: %s Compile: Check Pass 1 and 2\n", testname);
-	fprintf(fp, "  source to compile:\n[\n%s\n]\n", teststr);
-	bool compiled = compile(teststr);
-	fprintf(fp, "  Pass 1 Lines scaned: %d, Tokens produced: %d out of %d: %s",
-		mCurrentLine, mTokenInstructions.size(), testresultsize,
-		(mTokenInstructions.size() == (UINT32)testresultsize) ? passed : failed);
-
-	fprintf(fp, "\n  Validating Pass 1:\n");
-
-	fprintf(fp, "\n  Tokens:\n");
-    UINT32 i;
-	for(i = 0; i<(mTokenInstructions.size()); i++) {
-		fprintf(fp,"    Token[%d] [%s] %d: [%s] %d: %s", i, getTypeDefText(mTokenInstructions[i].mID),
-			mTokenInstructions[i].mID, getTypeDefText(testresult[i]), testresult[i],
-			(mTokenInstructions[i].mID == (UINT32)testresult[i]) ? passed : failed);
-	}
-
-	if(MachinInstResults != NULL) {
-		fprintf(fp, "\n  Machine Instructions:\n");
-
-		fprintf(fp, "  Pass 2 Machine Instructions generated: %d out of %d: %s", getMachineInstCount(),
-			MachinInstResultsSize, (getMachineInstCount() == MachinInstResultsSize) ? passed : failed);
-
-		size_t MIcount = getMachineInstCount();
-
-		fprintf(fp, "\n  Validating Pass 2:\n");
-		for(i = 0; i<MIcount; i++) {
-			fprintf(fp,"    instruction[%d] = 0x%x : 0x%x : %s", i, getMachineInst(i), MachinInstResults[i], (getMachineInst(i) == MachinInstResults[i]) ? passed : failed);
-		}
-
-		fprintf(fp, "\n  Constants:\n");
-		for(i=0; i<4; i++) {
-			fprintf(fp, "    Constants[%d] = %f : %s", i, mConstants[i], (mConstants[i] == (1.0f+i)) ? passed : failed);
-		}
-	}
-	if(!compiled) fprintf(fp, failed);
-
-	fprintf(fp, "\nfinished testing: %s Compile: Check Pass 2\n\n", testname);
-
-	setActiveContexts(ckp_PS_BASE);
-}
-
-void PS_1_4::testbinder()
-{
-  FILE* fp;
-  char BindTestStr[] = "mov_x8 r0,v0";
-  char passed[] = "PASSED\n";
-  char failed[] = "FAILED\n";
-  #define BinderInstCnt 8
-  GLuint BindMachinInst[BinderInstCnt] = {mi_COLOROP1, GL_MOV_ATI, GL_REG_0_ATI, GL_NONE, GL_8X_BIT_ATI,
-   GL_PRIMARY_COLOR_ARB, GL_NONE, GL_NONE};
-
-  fp = fopen("ASMTests.txt", "at");
-  fprintf(fp,"Testing: bindMachineInstToFragmentShader\n");
-  // fill Machin instruction container with predefined code
-  clearAllMachineInst();
-  for(int i=0; i<BinderInstCnt; i++) {
-    mPhase2ALU_mi.push_back(BindMachinInst[i]);
-  }
-  fprintf(fp,"bindMachineInstToFragmentShader succes: %s\n",bindAllMachineInstToFragmentShader()?passed:failed);
-  fprintf(fp,"finished testing: bindAllMachineInstToFragmentShader\n");
-  fclose(fp);
-}
-
-#endif
-
-
-

+ 14 - 55
CamelotRenderer/TODO.txt

@@ -19,42 +19,25 @@
 /////
 -----------GpuProgramParameters/Pass/Material REFACTOR------------------------------
 
+Finish up GL port:
+ - GL shader and param binding happens in the shader itself, while it should happen on the RenderSystem (to be consistent with DX9 and DX11)
+ - Remove those DefaultHardwareBuffermanagers as I don't think they serve a purpose anymore (OpenGL seems to only use them if API doesn't support hardware buffers, which won't happen on modern hardware)
+ - Re-do GL attribute bindings (currently it parses program source manually)
+ - Params aren't being initialized anywhere
+ - Uniforms or uniform blocks aren't assigned anywhere
+ - Implement GLRenderSystem::bindGpuParams
+
 Re-enable DX11 and GL project dependencies in CamelotClient
 Saving/loading of material params isn't completed (in MAterialRTTI)
-In D3D9HLSLProgram make:
- mpConstTable local to localFromSource
- Remove old parameter creation methods
-Port OpenGL and DX11 paramters system
+Delete old bindGpuProgramParameters and old unused classes/files
+Port DX11 to new shader param system
+Ability to switch out GpuParamBlocks (i.e. share them between programs)
+Ability to create Pass without automatically creating param blocks
+Automatically creating a pass should be smart about not creating duplicate param blocks
 
 Handling of array parameters? This needs testing
+ - I'm currently ignoring array elements in GL due to the name their names are handled
 
-Material remains a simple structure you use for easily setting all and every type of parameters for every stage.
- - Each instantiation of Material creates its own unique constant buffers
-  - Attempt to detect duplicates on initialization
- - Set/GetConstantBuffer allows you to switch out and share constant buffers
-
-GpuParamDesc
- - Contains a list of all constant buffers with their parameters (param name, type, size, slot, etc.)
- - Also a list of all textures/buffers/samplers
- - Each created GpuProgram contains one of these
-
-HardwareBufferManager::createConstantBuffer(GpuParamDesc)
- - Creates a constant buffer according to the specifications
-
-Pass
- - Constant buffers are stored on a pass
- - Supports previously mentioned Set/GetConstantBuffer
-   - When setting check GpuParamDesc of the shader to see if it matches
- - Also holds a list of Textures/SamplerStates/Buffers
-   - Doesn't make sense to store it in ConstantBuffer since it would just be one per buffer
-
-Possibly keep GpuProgramParams class so it unifies access to ConstantBuffer and Textures/SamplerStates/Buffers?
-
-RenderSystem::bindGpuProgramParameters (maybe rename to something nicer?)
- - It retrieves Constant buffer from Pass, converts it to a platform specific version and sets the needed parameters
-
-
-Port OpenGL so it uses Uniform buffers
 
 ---------------------------------------------------
 
@@ -71,8 +54,6 @@ RenderSystem::setScissorRect(RECT[] array)
 RenderSystem::setViewport(RECT[] array)
  - Change it so it accepts an array
 
-Modify how are Material/Pass parameters & GpuProgramParameters handled
-
 monitorIndex is ignored in DX11
 
 Creating a primary window and initializing the render system should probably be one step
@@ -86,13 +67,9 @@ Unity has a common class for both RenderTexture and DepthStencilBuffer
  - Maybe rename DepthStencilBuffer to DepthStencilTexture?
 
 waitForVsync can probably be moved somewhere other than being directly in RenderSystem? (where is it in DX11?)
-Drop OpenGL support for low level shaders? (See if cg can translate to GLSL)
 
 Keeping a list of all render targets in RenderSystem shouldn't be needed (and calling attach/detach renderTarget). Renderer should determine in what order are render targets presented.
 
-Constant buffers are created in a weird way. Maybe they should only be created internally by GpuProgramParameters?
- - Multiple GpuProgramParameters get returned from GpuProgram after createParameters() is called, in a map, each with its own name
-
 Make CommandQueue not use mutexes and use atomics instead??
 Make sure that the simulation can't run faster then the render thread! (Block the main thread until previous render finishes)
 Figure out how to handle accessing texture from a non-render thread?
@@ -135,24 +112,12 @@ RenderSystem needed modifications
 
 Command buffer TODO:
  - When importing a resource, and registering it with Resources I don't think it properly gets added to the loaded resources array? For some reason shaders get created twice.
- - My current approach doesn't allow multiple threads to use the RenderSystem (contexts should be handled differently)
-   - Instead of requiring the user to constantly call setActiveContext, make the call peristent per thread. 
-   - Store sequential thread idx in local thread storage, and then we can easily look up a context for a thread and
-     automatically use it, if it's set. (Use boost::thread_specific_ptr for local thread storage)
- - Make sure to allow the user to submit the context manually to the gpu. (Right now all contexts are submitted at once, and when I'll have compute
- shaders running I'm sure I'll want other threads to do different things on the gpu)
  - Doing setPixels_async in the texture doesn't make sure that the user doesn't actually modify the provided PixelData after
     that call.
 
 Mesh
  - Make sure to queue up mesh deletion to make sure it gets destroyed on the render thread
 
-GpuProgram/HighLevelGpuProgram
- - Do a pass of refactoring
- - Fix it up for multithreading
-  - In general everything needs to be checked
-  - Add thread checks
-
 Make initialize & initialize_internal protected?
  - Only their factories and RTTI classes need to access it (and they can be friends)
  - Would need to modify HighLevelGpuProgram::mAssemblerProgram
@@ -171,7 +136,6 @@ HIGH PRIORITY TODO:
  - GetRenderOperation doesn't consider sub-meshes
 
 Mid priority TODO:
- - Add multithreaded version of RenderTarget::getCustomAttribute_internal
  - Compiler2Pass in GL renderer doesn't seem to be 64bit ready. I hacked it together but it will likely cause problems.
  - Resource handle should store a unique integer ID, which just points to a table of GUIDs. Keeping GUID string everywhere in not efficient.
  - Add a field that tracks % of resource deserialization in BinarySerializer
@@ -203,9 +167,6 @@ Low priority TODO:
    if pointer is saved/loaded as a plain field. I need to add a check that ensures the type is POD. 
    See: http://www.boost.org/doc/libs/1_51_0/boost/mpi/datatype.hpp for a possible implementation of a compile time check.
  - Fix up WorkQueue as it doesn't lock when initializing, to make sure threads are actually started before returning
- - D3D9HLSLProgram stuff that isn't used (it needs to be initialized before initializing the shader, which currently isn't possible). Maybe adding it to HighLevelGpuProgramFactory?
-     - setPreprocessorDefines, setColumnMajorMatrices, setOptimisationLevel
- - OpenGL seems to generate a mip pyramid regardless of the setting (in createInternalResourcesImpl)
  - DepthStencilBuffer & Texture should possibly share the same interface instead of being two separate classes? I'll need to assign DepthStencil to shaders sometimes. Not possible in DX9 but possible in DX11.
  - CPU reading or writing to a render texture in OpenGL is not supported. (CmGLHardwarePixelBuffer::upload/download). 
 
@@ -213,8 +174,6 @@ Optional TODO:
  - Add precompiled headers to all projects
  - If possible, make sure GLSL uses EntryPoint and Profile fields I have added to GpuProgram
  - Move all x86 libs to x86 folders. Move all binaries to x86 folders as well
- - Drop support for assembly shaders?
- - Shared shader parameters (Since there will be values that are constant between all Draw call it doesn't make sense to set them every call?)
  - Serializable callbacks can't be null otherwise compiler complains
  - FBX importer can be greatly sped up by implementing a better allocator
  - Extend texture copy so it accepts different subregions & subresources (currently only entire resource can be copied)

+ 0 - 1
CamelotUtility/Include/CmException.h

@@ -130,7 +130,6 @@ namespace CamelotEngine
 			: Exception("RuntimeAssertionException", inDescription, inSource, inFile, inLine) {}
 	};
 
-	// TODO - Temporarily disabled until I include boost
 #ifndef CM_EXCEPT
 #define CM_EXCEPT(type, desc)	\
 	{                           \