Browse Source

All render systems work after shader refactor
Modified DX9 parameter parsing so it properly accounts for possible compiler optimizations (type might not be the same size as requested)

Marko Pintera 11 năm trước cách đây
mục cha
commit
b60ea8260c
24 tập tin đã thay đổi với 457 bổ sung135 xóa
  1. 13 13
      BansheeEngine/Source/BsD3D11BuiltinMaterialFactory.cpp
  2. 13 13
      BansheeEngine/Source/BsD3D9BuiltinMaterialFactory.cpp
  3. 13 13
      BansheeEngine/Source/BsGLBuiltinMaterialFactory.cpp
  4. 4 3
      CamelotCore/Include/CmGpuParam.h
  5. 2 2
      CamelotCore/Include/CmGpuProgram.h
  6. 2 10
      CamelotCore/Include/CmGpuProgramManager.h
  7. 5 3
      CamelotCore/Source/CmGpuParam.cpp
  8. 3 13
      CamelotCore/Source/CmGpuProgramManager.cpp
  9. 53 10
      CamelotD3D11RenderSystem/Include/CmD3D11GpuProgram.h
  10. 1 1
      CamelotD3D11RenderSystem/Include/CmD3D11HLSLProgramFactory.h
  11. 7 1
      CamelotD3D11RenderSystem/Include/CmD3D11Prerequisites.h
  12. 89 10
      CamelotD3D11RenderSystem/Source/CmD3D11GpuProgram.cpp
  13. 25 7
      CamelotD3D11RenderSystem/Source/CmD3D11HLSLProgramFactory.cpp
  14. 20 4
      CamelotD3D9Renderer/Include/CmD3D9GpuProgram.h
  15. 78 0
      CamelotD3D9Renderer/Include/CmD3D9GpuProgramRTTI.h
  16. 59 15
      CamelotD3D9Renderer/Include/CmD3D9HLSLParamParser.h
  17. 1 1
      CamelotD3D9Renderer/Include/CmD3D9HLSLProgramFactory.h
  18. 3 1
      CamelotD3D9Renderer/Include/CmD3D9Prerequisites.h
  19. 33 6
      CamelotD3D9Renderer/Source/CmD3D9GpuProgram.cpp
  20. 18 6
      CamelotD3D9Renderer/Source/CmD3D9HLSLProgramFactory.cpp
  21. 2 0
      CamelotGLRenderer/Source/GLSL/include/CmGLSLGpuProgram.h
  22. 1 1
      CamelotGLRenderer/Source/GLSL/include/CmGLSLProgramFactory.h
  23. 10 0
      CamelotGLRenderer/Source/GLSL/src/CmGLSLGpuProgram.cpp
  24. 2 2
      CamelotGLRenderer/Source/GLSL/src/CmGLSLProgramFactory.cpp

+ 13 - 13
BansheeEngine/Source/BsD3D11BuiltinMaterialFactory.cpp

@@ -1,6 +1,6 @@
 #include "BsD3D11BuiltinMaterialFactory.h"
 #include "CmRendererManager.h"
-#include "CmHighLevelGpuProgram.h"
+#include "CmGpuProgram.h"
 #include "CmShader.h"
 #include "CmTechnique.h"
 #include "CmPass.h"
@@ -114,8 +114,8 @@ namespace BansheeEngine
 				return color;																		\
 			}";
 
-		HHighLevelGpuProgram vsProgram = HighLevelGpuProgram::create(vsCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_4_0);
-		HHighLevelGpuProgram psProgram = HighLevelGpuProgram::create(psCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_PS_4_0);
+		HGpuProgram vsProgram = GpuProgram::create(vsCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_4_0);
+		HGpuProgram psProgram = GpuProgram::create(psCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_PS_4_0);
 
 		vsProgram.synchronize();
 		psProgram.synchronize();
@@ -186,8 +186,8 @@ namespace BansheeEngine
 						return color * tint;																\
 						}";
 
-		HHighLevelGpuProgram vsProgram = HighLevelGpuProgram::create(vsCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_4_0);
-		HHighLevelGpuProgram psProgram = HighLevelGpuProgram::create(psCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_PS_4_0);
+		HGpuProgram vsProgram = GpuProgram::create(vsCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_4_0);
+		HGpuProgram psProgram = GpuProgram::create(psCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_PS_4_0);
 
 		vsProgram.synchronize();
 		psProgram.synchronize();
@@ -244,8 +244,8 @@ namespace BansheeEngine
 		}																						\
 		";	
 
-		HHighLevelGpuProgram vsProgram = HighLevelGpuProgram::create(vsCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_4_0);
-		HHighLevelGpuProgram psProgram = HighLevelGpuProgram::create(psCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_PS_4_0);
+		HGpuProgram vsProgram = GpuProgram::create(vsCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_4_0);
+		HGpuProgram psProgram = GpuProgram::create(psCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_PS_4_0);
 
 		vsProgram.synchronize();
 		psProgram.synchronize();
@@ -300,8 +300,8 @@ namespace BansheeEngine
 						}																						\
 						";	
 
-		HHighLevelGpuProgram vsProgram = HighLevelGpuProgram::create(vsCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_4_0);
-		HHighLevelGpuProgram psProgram = HighLevelGpuProgram::create(psCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_PS_4_0);
+		HGpuProgram vsProgram = GpuProgram::create(vsCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_4_0);
+		HGpuProgram psProgram = GpuProgram::create(psCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_PS_4_0);
 
 		vsProgram.synchronize();
 		psProgram.synchronize();
@@ -354,8 +354,8 @@ namespace BansheeEngine
 						}																						\
 						";	
 
-		HHighLevelGpuProgram vsProgram = HighLevelGpuProgram::create(vsCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_4_0);
-		HHighLevelGpuProgram psProgram = HighLevelGpuProgram::create(psCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_PS_4_0);
+		HGpuProgram vsProgram = GpuProgram::create(vsCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_4_0);
+		HGpuProgram psProgram = GpuProgram::create(psCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_PS_4_0);
 
 		vsProgram.synchronize();
 		psProgram.synchronize();
@@ -415,8 +415,8 @@ namespace BansheeEngine
 						}																						\
 						";	
 
-		HHighLevelGpuProgram vsProgram = HighLevelGpuProgram::create(vsCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_4_0);
-		HHighLevelGpuProgram psProgram = HighLevelGpuProgram::create(psCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_PS_4_0);
+		HGpuProgram vsProgram = GpuProgram::create(vsCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_4_0);
+		HGpuProgram psProgram = GpuProgram::create(psCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_PS_4_0);
 
 		vsProgram.synchronize();
 		psProgram.synchronize();

+ 13 - 13
BansheeEngine/Source/BsD3D9BuiltinMaterialFactory.cpp

@@ -1,5 +1,5 @@
 #include "BsD3D9BuiltinMaterialFactory.h"
-#include "CmHighLevelGpuProgram.h"
+#include "CmGpuProgram.h"
 #include "CmShader.h"
 #include "CmTechnique.h"
 #include "CmPass.h"
@@ -113,8 +113,8 @@ namespace BansheeEngine
 				return color;															\
 			}";
 
-		HHighLevelGpuProgram vsProgram = HighLevelGpuProgram::create(vsCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_3_0);
-		HHighLevelGpuProgram psProgram = HighLevelGpuProgram::create(psCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_PS_3_0);
+		HGpuProgram vsProgram = GpuProgram::create(vsCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_3_0);
+		HGpuProgram psProgram = GpuProgram::create(psCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_PS_3_0);
 
 		vsProgram.synchronize();
 		psProgram.synchronize();
@@ -184,8 +184,8 @@ namespace BansheeEngine
 						return color * tint;							\
 						}";
 
-		HHighLevelGpuProgram vsProgram = HighLevelGpuProgram::create(vsCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
-		HHighLevelGpuProgram psProgram = HighLevelGpuProgram::create(psCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_PS_2_0);
+		HGpuProgram vsProgram = GpuProgram::create(vsCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
+		HGpuProgram psProgram = GpuProgram::create(psCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_PS_2_0);
 
 		vsProgram.synchronize();
 		psProgram.synchronize();
@@ -242,8 +242,8 @@ namespace BansheeEngine
 						return color;									\
 						}";
 
-		HHighLevelGpuProgram vsProgram = HighLevelGpuProgram::create(vsCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
-		HHighLevelGpuProgram psProgram = HighLevelGpuProgram::create(psCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_PS_2_0);
+		HGpuProgram vsProgram = GpuProgram::create(vsCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
+		HGpuProgram psProgram = GpuProgram::create(psCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_PS_2_0);
 
 		vsProgram.synchronize();
 		psProgram.synchronize();
@@ -298,8 +298,8 @@ namespace BansheeEngine
 						return color;									\
 						}";
 
-		HHighLevelGpuProgram vsProgram = HighLevelGpuProgram::create(vsCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
-		HHighLevelGpuProgram psProgram = HighLevelGpuProgram::create(psCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_PS_2_0);
+		HGpuProgram vsProgram = GpuProgram::create(vsCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
+		HGpuProgram psProgram = GpuProgram::create(psCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_PS_2_0);
 
 		vsProgram.synchronize();
 		psProgram.synchronize();
@@ -352,8 +352,8 @@ namespace BansheeEngine
 						return color;									\
 						}";
 
-		HHighLevelGpuProgram vsProgram = HighLevelGpuProgram::create(vsCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
-		HHighLevelGpuProgram psProgram = HighLevelGpuProgram::create(psCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_PS_2_0);
+		HGpuProgram vsProgram = GpuProgram::create(vsCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
+		HGpuProgram psProgram = GpuProgram::create(psCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_PS_2_0);
 
 		vsProgram.synchronize();
 		psProgram.synchronize();
@@ -413,8 +413,8 @@ namespace BansheeEngine
 						return color;									\
 						}";
 
-		HHighLevelGpuProgram vsProgram = HighLevelGpuProgram::create(vsCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
-		HHighLevelGpuProgram psProgram = HighLevelGpuProgram::create(psCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_PS_2_0);
+		HGpuProgram vsProgram = GpuProgram::create(vsCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
+		HGpuProgram psProgram = GpuProgram::create(psCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_PS_2_0);
 
 		vsProgram.synchronize();
 		psProgram.synchronize();

+ 13 - 13
BansheeEngine/Source/BsGLBuiltinMaterialFactory.cpp

@@ -1,9 +1,9 @@
 #include "BsGLBuiltinMaterialFactory.h"
-#include "CmHighLevelGpuProgram.h"
 #include "CmShader.h"
 #include "CmTechnique.h"
 #include "CmPass.h"
 #include "CmMaterial.h"
+#include "CmGpuProgram.h"
 #include "CmBlendState.h"
 #include "CmDepthStencilState.h"
 #include "CmRendererManager.h"
@@ -116,8 +116,8 @@ namespace BansheeEngine
 						fragColor = color;									\
 						}";
 
-		HHighLevelGpuProgram vsProgram = HighLevelGpuProgram::create(vsCode, "main", "glsl", GPT_VERTEX_PROGRAM, GPP_VS_4_0);
-		HHighLevelGpuProgram psProgram = HighLevelGpuProgram::create(psCode, "main", "glsl", GPT_FRAGMENT_PROGRAM, GPP_PS_4_0);
+		HGpuProgram vsProgram = GpuProgram::create(vsCode, "main", "glsl", GPT_VERTEX_PROGRAM, GPP_VS_4_0);
+		HGpuProgram psProgram = GpuProgram::create(psCode, "main", "glsl", GPT_FRAGMENT_PROGRAM, GPP_PS_4_0);
 
 		vsProgram.synchronize();
 		psProgram.synchronize();
@@ -190,8 +190,8 @@ namespace BansheeEngine
 						fragColor = color * tint;							\
 						}";
 
-		HHighLevelGpuProgram vsProgram = HighLevelGpuProgram::create(vsCode, "main", "glsl", GPT_VERTEX_PROGRAM, GPP_VS_4_0);
-		HHighLevelGpuProgram psProgram = HighLevelGpuProgram::create(psCode, "main", "glsl", GPT_FRAGMENT_PROGRAM, GPP_PS_4_0);
+		HGpuProgram vsProgram = GpuProgram::create(vsCode, "main", "glsl", GPT_VERTEX_PROGRAM, GPP_VS_4_0);
+		HGpuProgram psProgram = GpuProgram::create(psCode, "main", "glsl", GPT_FRAGMENT_PROGRAM, GPP_PS_4_0);
 
 		vsProgram.synchronize();
 		psProgram.synchronize();
@@ -252,8 +252,8 @@ namespace BansheeEngine
 						fragColor = color0;					\
 						}";
 
-		HHighLevelGpuProgram vsProgram = HighLevelGpuProgram::create(vsCode, "vs_main", "glsl", GPT_VERTEX_PROGRAM, GPP_VS_4_0);
-		HHighLevelGpuProgram psProgram = HighLevelGpuProgram::create(psCode, "ps_main", "glsl", GPT_FRAGMENT_PROGRAM, GPP_PS_4_0);
+		HGpuProgram vsProgram = GpuProgram::create(vsCode, "vs_main", "glsl", GPT_VERTEX_PROGRAM, GPP_VS_4_0);
+		HGpuProgram psProgram = GpuProgram::create(psCode, "ps_main", "glsl", GPT_FRAGMENT_PROGRAM, GPP_PS_4_0);
 
 		vsProgram.synchronize();
 		psProgram.synchronize();
@@ -312,8 +312,8 @@ namespace BansheeEngine
 						fragColor = color0;					\
 						}";
 
-		HHighLevelGpuProgram vsProgram = HighLevelGpuProgram::create(vsCode, "vs_main", "glsl", GPT_VERTEX_PROGRAM, GPP_VS_4_0);
-		HHighLevelGpuProgram psProgram = HighLevelGpuProgram::create(psCode, "ps_main", "glsl", GPT_FRAGMENT_PROGRAM, GPP_PS_4_0);
+		HGpuProgram vsProgram = GpuProgram::create(vsCode, "vs_main", "glsl", GPT_VERTEX_PROGRAM, GPP_VS_4_0);
+		HGpuProgram psProgram = GpuProgram::create(psCode, "ps_main", "glsl", GPT_FRAGMENT_PROGRAM, GPP_PS_4_0);
 
 		vsProgram.synchronize();
 		psProgram.synchronize();
@@ -371,8 +371,8 @@ namespace BansheeEngine
 						fragColor = color0;					\
 						}";
 
-		HHighLevelGpuProgram vsProgram = HighLevelGpuProgram::create(vsCode, "vs_main", "glsl", GPT_VERTEX_PROGRAM, GPP_VS_4_0);
-		HHighLevelGpuProgram psProgram = HighLevelGpuProgram::create(psCode, "ps_main", "glsl", GPT_FRAGMENT_PROGRAM, GPP_PS_4_0);
+		HGpuProgram vsProgram = GpuProgram::create(vsCode, "vs_main", "glsl", GPT_VERTEX_PROGRAM, GPP_VS_4_0);
+		HGpuProgram psProgram = GpuProgram::create(psCode, "ps_main", "glsl", GPT_FRAGMENT_PROGRAM, GPP_PS_4_0);
 
 		vsProgram.synchronize();
 		psProgram.synchronize();
@@ -436,8 +436,8 @@ namespace BansheeEngine
 						fragColor = color0;					\
 						}";
 
-		HHighLevelGpuProgram vsProgram = HighLevelGpuProgram::create(vsCode, "vs_main", "glsl", GPT_VERTEX_PROGRAM, GPP_VS_4_0);
-		HHighLevelGpuProgram psProgram = HighLevelGpuProgram::create(psCode, "ps_main", "glsl", GPT_FRAGMENT_PROGRAM, GPP_PS_4_0);
+		HGpuProgram vsProgram = GpuProgram::create(vsCode, "vs_main", "glsl", GPT_VERTEX_PROGRAM, GPP_VS_4_0);
+		HGpuProgram psProgram = GpuProgram::create(psCode, "ps_main", "glsl", GPT_FRAGMENT_PROGRAM, GPP_PS_4_0);
 
 		vsProgram.synchronize();
 		psProgram.synchronize();

+ 4 - 3
CamelotCore/Include/CmGpuParam.h

@@ -116,7 +116,8 @@ namespace BansheeEngine
 			}
 #endif
 
-			UINT32 sizeBytes = sizeof(T);
+			UINT32 elementSizeBytes = paramDesc->elementSize * sizeof(UINT32);
+			UINT32 sizeBytes = std::min(elementSizeBytes, (UINT32)sizeof(T)); // Truncate if it doesn't fit within parameter size
 			GpuParamBlock* paramBlock = mData->paramBlocks[paramDesc->paramBlockSlot];
 
 			if(TransposePolicy<T>::transposeEnabled(mData->transpose))
@@ -128,7 +129,6 @@ namespace BansheeEngine
 				paramBlock->write((paramDesc->cpuMemOffset + arrayIdx * paramDesc->arrayElementStride) * sizeof(UINT32), &value, sizeBytes);
 
 			// Set unused bytes to 0
-			UINT32 elementSizeBytes = paramDesc->elementSize * sizeof(UINT32);
 			if(sizeBytes < elementSizeBytes)
 			{
 				UINT32 diffSize = elementSizeBytes - sizeBytes;
@@ -157,7 +157,8 @@ namespace BansheeEngine
 			}
 #endif
 
-			UINT32 sizeBytes = sizeof(T);
+			UINT32 elementSizeBytes = paramDesc->elementSize * sizeof(UINT32);
+			UINT32 sizeBytes = std::min(elementSizeBytes, (UINT32)sizeof(T));
 			GpuParamBlock* paramBlock = mData->paramBlocks[paramDesc->paramBlockSlot];
 
 			T value;

+ 2 - 2
CamelotCore/Include/CmGpuProgram.h

@@ -153,7 +153,7 @@ namespace BansheeEngine
 		 * @param	requiresAdjacency	If true then adjacency information will be provided when rendering using this program.
 		 */
 		static HGpuProgram create(const String& source, const String& entryPoint, const String& language, GpuProgramType gptype,
-			GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes, bool requiresAdjacency = false);
+			GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes = nullptr, bool requiresAdjacency = false);
 
 		/**
 		 * @copydoc	create
@@ -161,7 +161,7 @@ namespace BansheeEngine
 		 * @note	Internal method. For normal use call "create".
 		 */
 		static GpuProgramPtr _createPtr(const String& source, const String& entryPoint, const String& language, GpuProgramType gptype, 
-			GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes, bool requiresAdjacency = false);
+			GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes = nullptr, bool requiresAdjacency = false);
 
 	protected:
 		friend class GpuProgramManager;

+ 2 - 10
CamelotCore/Include/CmGpuProgramManager.h

@@ -17,7 +17,7 @@ namespace BansheeEngine
 		virtual GpuProgramPtr create(const String& source, const String& entryPoint,
 			GpuProgramType gptype, GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes,
 			bool requiresAdjacencyInformation) = 0;
-		virtual GpuProgramPtr create() = 0;
+		virtual GpuProgramPtr create(GpuProgramType type) = 0;
 	};
 
 	class CM_EXPORT GpuProgramManager : public Module<GpuProgramManager>
@@ -57,19 +57,11 @@ namespace BansheeEngine
 			GpuProgramType gptype, GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes,
 			bool requiresAdjacencyInformation = false);
 
-		/** Create a new HighLevelGpuProgram. 
-		@par
-			This method creates a new program of the specified language. You need to set other 
-			properties like source, entry point, type, profile manually.
-		@param language Code of the language to use (e.g. "cg")
-		*/
-		GpuProgramPtr create(const String& language);
-
 		/**
 		 * @brief	Creates a completely empty and uninitialized HighLevelGpuProgram.
 		 * 			Should only be used for VERY specific purposes, like deserialization,
 		 * 			as it requires additional manual initialization that is not required normally.
 		 */
-		GpuProgramPtr createEmpty(const String& language);
+		GpuProgramPtr createEmpty(const String& language, GpuProgramType type);
 	};
 }

+ 5 - 3
CamelotCore/Source/CmGpuParam.cpp

@@ -36,7 +36,7 @@ namespace BansheeEngine
 #if CM_DEBUG_MODE
 		if(sizeBytes > elementSizeBytes)
 		{
-			CM_EXCEPT(InvalidParametersException, "Provided element size larger than maximum element size. Maximum size: " + 
+			LOGWRN("Provided element size larger than maximum element size. Maximum size: " + 
 				toString(elementSizeBytes) + ". Supplied size: " + toString(sizeBytes));
 		}
 
@@ -47,6 +47,8 @@ namespace BansheeEngine
 		}
 #endif
 
+		sizeBytes = std::min(elementSizeBytes, sizeBytes);
+
 		GpuParamBlock* paramBlock = mData->paramBlocks[paramDesc->paramBlockSlot];
 		paramBlock->write((paramDesc->cpuMemOffset + arrayIdx * paramDesc->arrayElementStride) * sizeof(UINT32), value, sizeBytes);
 
@@ -69,7 +71,7 @@ namespace BansheeEngine
 #if CM_DEBUG_MODE
 		if(sizeBytes > elementSizeBytes)
 		{
-			CM_EXCEPT(InvalidParametersException, "Provided element size larger than maximum element size. Maximum size: " + 
+			LOGWRN("Provided element size larger than maximum element size. Maximum size: " + 
 				toString(elementSizeBytes) + ". Supplied size: " + toString(sizeBytes));
 		}
 
@@ -79,9 +81,9 @@ namespace BansheeEngine
 				toString(paramDesc->arraySize) + ". Requested size: " + toString(arrayIdx));
 		}
 #endif
+		sizeBytes = std::min(elementSizeBytes, sizeBytes);
 
 		GpuParamBlock* paramBlock = mData->paramBlocks[paramDesc->paramBlockSlot];
-
 		paramBlock->read((paramDesc->cpuMemOffset + arrayIdx * paramDesc->arrayElementStride) * sizeof(UINT32), value, sizeBytes);
 	}
 

+ 3 - 13
CamelotCore/Source/CmGpuProgramManager.cpp

@@ -57,7 +57,7 @@ namespace BansheeEngine
 		{
 			return cm_core_ptr<NullProgram, PoolAlloc>();
 		}
-		GpuProgramPtr create()
+		GpuProgramPtr create(GpuProgramType type)
 		{
 			return cm_core_ptr<NullProgram, PoolAlloc>();
 		}
@@ -123,20 +123,10 @@ namespace BansheeEngine
         return ret;
     }
 
-	GpuProgramPtr GpuProgramManager::create(const String& language)
+	GpuProgramPtr GpuProgramManager::createEmpty(const String& language, GpuProgramType type)
 	{
 		GpuProgramFactory* factory = getFactory(language);
-		GpuProgramPtr ret = factory->create();
-		ret->_setThisPtr(ret);
-		ret->initialize();
-
-		return ret;
-	}
-
-	GpuProgramPtr GpuProgramManager::createEmpty(const String& language)
-	{
-		GpuProgramFactory* factory = getFactory(language);
-		GpuProgramPtr ret = factory->create();
+		GpuProgramPtr ret = factory->create(type);
 		ret->_setThisPtr(ret);
 
 		return ret;

+ 53 - 10
CamelotD3D11RenderSystem/Include/CmD3D11GpuProgram.h

@@ -88,8 +88,7 @@ namespace BansheeEngine
 		friend class D3D11HLSLProgramFactory;
 
 		D3D11GpuVertexProgram(const String& source, const String& entryPoint,
-			GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes,
-			bool isAdjacencyInfoRequired);
+			GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes);
 
 		/**
 		 * @copydoc GpuProgram::destroy_internal().
@@ -98,6 +97,14 @@ namespace BansheeEngine
 
 	protected:
 		ID3D11VertexShader* mVertexShader;
+
+		/************************************************************************/
+		/* 								SERIALIZATION                      		*/
+		/************************************************************************/
+	public:
+		friend class D3D11GpuVertexProgramRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const;
 	};
 
 	class CM_D3D11_EXPORT D3D11GpuFragmentProgram : public D3D11GpuProgram
@@ -111,8 +118,7 @@ namespace BansheeEngine
 		friend class D3D11HLSLProgramFactory;
 
 		D3D11GpuFragmentProgram(const String& source, const String& entryPoint,
-			GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes,
-			bool isAdjacencyInfoRequired);
+			GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes);
 
 		/**
 		 * @copydoc GpuProgram::destroy_internal().
@@ -120,6 +126,14 @@ namespace BansheeEngine
 		void destroy_internal();
 	protected:
 		ID3D11PixelShader* mPixelShader;
+
+		/************************************************************************/
+		/* 								SERIALIZATION                      		*/
+		/************************************************************************/
+	public:
+		friend class D3D11GpuFragmentProgramRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const;
 	};
 
 	class CM_D3D11_EXPORT D3D11GpuDomainProgram : public D3D11GpuProgram
@@ -133,8 +147,7 @@ namespace BansheeEngine
 		friend class D3D11HLSLProgramFactory;
 
 		D3D11GpuDomainProgram(const String& source, const String& entryPoint,
-			GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes,
-			bool isAdjacencyInfoRequired);
+			GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes);
 
 		/**
 		 * @copydoc GpuProgram::destroy_internal().
@@ -143,6 +156,14 @@ namespace BansheeEngine
 
 	protected:
 		ID3D11DomainShader* mDomainShader;
+
+		/************************************************************************/
+		/* 								SERIALIZATION                      		*/
+		/************************************************************************/
+	public:
+		friend class D3D11GpuDomainProgramRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const;
 	};
 
 	class CM_D3D11_EXPORT D3D11GpuHullProgram : public D3D11GpuProgram
@@ -156,8 +177,7 @@ namespace BansheeEngine
 		friend class D3D11HLSLProgramFactory;
 
 		D3D11GpuHullProgram(const String& source, const String& entryPoint,
-			GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes,
-			bool isAdjacencyInfoRequired);
+			GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes);
 
 		/**
 		 * @copydoc GpuProgram::destroy_internal().
@@ -166,6 +186,14 @@ namespace BansheeEngine
 
 	protected:
 		ID3D11HullShader* mHullShader;
+
+		/************************************************************************/
+		/* 								SERIALIZATION                      		*/
+		/************************************************************************/
+	public:
+		friend class D3D11GpuHullProgramRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const;
 	};
 
 	class CM_D3D11_EXPORT D3D11GpuGeometryProgram : public D3D11GpuProgram
@@ -190,6 +218,14 @@ namespace BansheeEngine
 
 	protected:
 		ID3D11GeometryShader* mGeometryShader;
+
+		/************************************************************************/
+		/* 								SERIALIZATION                      		*/
+		/************************************************************************/
+	public:
+		friend class D3D11GpuGeometryProgramRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const;
 	};
 
 	class CM_D3D11_EXPORT D3D11GpuComputeProgram : public D3D11GpuProgram
@@ -204,8 +240,7 @@ namespace BansheeEngine
 		friend class D3D11HLSLProgramFactory;
 
 		D3D11GpuComputeProgram(const String& source, const String& entryPoint,
-			GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes,
-			bool isAdjacencyInfoRequired);
+			GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes);
 
 		/**
 		 * @copydoc GpuProgram::destroy_internal().
@@ -214,5 +249,13 @@ namespace BansheeEngine
 
 	protected:
 		ID3D11ComputeShader* mComputeShader;
+
+		/************************************************************************/
+		/* 								SERIALIZATION                      		*/
+		/************************************************************************/
+	public:
+		friend class D3D11GpuComputeProgramRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const;
 	};
 }

+ 1 - 1
CamelotD3D11RenderSystem/Include/CmD3D11HLSLProgramFactory.h

@@ -14,7 +14,7 @@ namespace BansheeEngine
 		const String& getLanguage(void) const;
 		GpuProgramPtr create(const String& source, const String& entryPoint, GpuProgramType gptype, 
 			GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes, bool requireAdjacencyInfo);
-		GpuProgramPtr create();
+		GpuProgramPtr create(GpuProgramType type);
 
 	protected:
 		static const String LANGUAGE_NAME;

+ 7 - 1
CamelotD3D11RenderSystem/Include/CmD3D11Prerequisites.h

@@ -56,7 +56,13 @@ namespace BansheeEngine
 
 	enum TypeID_D3D11
 	{
-		TID_D3D11_GpuProgram = 12000
+		TID_D3D11_GpuProgram = 12000,
+		TID_D3D11_GpuVertexProgram = 12001,
+		TID_D3D11_GpuFragmentProgram = 12002,
+		TID_D3D11_GpuGeometryProgram = 12003,
+		TID_D3D11_GpuHullProgram = 12004,
+		TID_D3D11_GpuDomainProgram = 12005,
+		TID_D3D11_GpuComputeProgram = 12006
 	};
 
 	typedef Vector<char*> HLSLMicroCode;

+ 89 - 10
CamelotD3D11RenderSystem/Source/CmD3D11GpuProgram.cpp

@@ -33,6 +33,7 @@ namespace BansheeEngine
 			mIsCompiled = false;
 			mCompileError = "Specified program is not supported by the current render system.";
 
+			GpuProgram::initialize_internal();
 			return;
 		}
 
@@ -160,8 +161,8 @@ namespace BansheeEngine
 	}
 
 	D3D11GpuVertexProgram::D3D11GpuVertexProgram(const String& source, const String& entryPoint,
-		GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes, bool isAdjacencyInfoRequired)
-		: D3D11GpuProgram(source, entryPoint, GPT_VERTEX_PROGRAM, profile, includes, isAdjacencyInfoRequired)
+		GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes)
+		: D3D11GpuProgram(source, entryPoint, GPT_VERTEX_PROGRAM, profile, includes, false)
 		, mVertexShader(nullptr)
 	{ }
 
@@ -195,9 +196,22 @@ namespace BansheeEngine
 		return mVertexShader;
 	}
 
+	/************************************************************************/
+	/* 								SERIALIZATION                      		*/
+	/************************************************************************/
+	RTTITypeBase* D3D11GpuVertexProgram::getRTTIStatic()
+	{
+		return D3D11GpuVertexProgramRTTI::instance();
+	}
+
+	RTTITypeBase* D3D11GpuVertexProgram::getRTTI() const
+	{
+		return D3D11GpuVertexProgram::getRTTIStatic();
+	}
+
 	D3D11GpuFragmentProgram::D3D11GpuFragmentProgram(const String& source, const String& entryPoint,
-		GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes, bool isAdjacencyInfoRequired)
-		: D3D11GpuProgram(source, entryPoint, GPT_FRAGMENT_PROGRAM, profile, includes, isAdjacencyInfoRequired)
+		GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes)
+		: D3D11GpuProgram(source, entryPoint, GPT_FRAGMENT_PROGRAM, profile, includes, false)
 		, mPixelShader(nullptr)
 	{ }
 
@@ -230,6 +244,19 @@ namespace BansheeEngine
 		return mPixelShader;
 	}
 
+	/************************************************************************/
+	/* 								SERIALIZATION                      		*/
+	/************************************************************************/
+	RTTITypeBase* D3D11GpuFragmentProgram::getRTTIStatic()
+	{
+		return D3D11GpuFragmentProgramRTTI::instance();
+	}
+
+	RTTITypeBase* D3D11GpuFragmentProgram::getRTTI() const
+	{
+		return D3D11GpuFragmentProgram::getRTTIStatic();
+	}
+
 	D3D11GpuGeometryProgram::D3D11GpuGeometryProgram(const String& source, const String& entryPoint,
 		GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes, bool isAdjacencyInfoRequired)
 		: D3D11GpuProgram(source, entryPoint, GPT_GEOMETRY_PROGRAM, profile, includes, isAdjacencyInfoRequired)
@@ -265,9 +292,22 @@ namespace BansheeEngine
 		return mGeometryShader;
 	}
 
+	/************************************************************************/
+	/* 								SERIALIZATION                      		*/
+	/************************************************************************/
+	RTTITypeBase* D3D11GpuGeometryProgram::getRTTIStatic()
+	{
+		return D3D11GpuGeometryProgramRTTI::instance();
+	}
+
+	RTTITypeBase* D3D11GpuGeometryProgram::getRTTI() const
+	{
+		return D3D11GpuGeometryProgram::getRTTIStatic();
+	}
+
 	D3D11GpuDomainProgram::D3D11GpuDomainProgram(const String& source, const String& entryPoint,
-		GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes, bool isAdjacencyInfoRequired)
-		: D3D11GpuProgram(source, entryPoint, GPT_DOMAIN_PROGRAM, profile, includes, isAdjacencyInfoRequired)
+		GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes)
+		: D3D11GpuProgram(source, entryPoint, GPT_DOMAIN_PROGRAM, profile, includes, false)
 		, mDomainShader(nullptr)
 	{ }
 
@@ -300,9 +340,22 @@ namespace BansheeEngine
 		return mDomainShader;
 	}
 
+	/************************************************************************/
+	/* 								SERIALIZATION                      		*/
+	/************************************************************************/
+	RTTITypeBase* D3D11GpuDomainProgram::getRTTIStatic()
+	{
+		return D3D11GpuDomainProgramRTTI::instance();
+	}
+
+	RTTITypeBase* D3D11GpuDomainProgram::getRTTI() const
+	{
+		return D3D11GpuDomainProgram::getRTTIStatic();
+	}
+
 	D3D11GpuHullProgram::D3D11GpuHullProgram(const String& source, const String& entryPoint,
-		GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes, bool isAdjacencyInfoRequired)
-		: D3D11GpuProgram(source, entryPoint, GPT_HULL_PROGRAM, profile, includes, isAdjacencyInfoRequired)
+		GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes)
+		: D3D11GpuProgram(source, entryPoint, GPT_HULL_PROGRAM, profile, includes, false)
 		, mHullShader(nullptr)
 	{ }
 
@@ -336,9 +389,22 @@ namespace BansheeEngine
 		return mHullShader;
 	}
 
+	/************************************************************************/
+	/* 								SERIALIZATION                      		*/
+	/************************************************************************/
+	RTTITypeBase* D3D11GpuHullProgram::getRTTIStatic()
+	{
+		return D3D11GpuHullProgramRTTI::instance();
+	}
+
+	RTTITypeBase* D3D11GpuHullProgram::getRTTI() const
+	{
+		return D3D11GpuHullProgram::getRTTIStatic();
+	}
+
 	D3D11GpuComputeProgram::D3D11GpuComputeProgram(const String& source, const String& entryPoint,
-		GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes, bool isAdjacencyInfoRequired)
-		: D3D11GpuProgram(source, entryPoint, GPT_COMPUTE_PROGRAM, profile, includes, isAdjacencyInfoRequired)
+		GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes)
+		: D3D11GpuProgram(source, entryPoint, GPT_COMPUTE_PROGRAM, profile, includes, false)
 		, mComputeShader(nullptr)
 	{ }
 
@@ -370,4 +436,17 @@ namespace BansheeEngine
 	{
 		return mComputeShader;
 	}
+
+	/************************************************************************/
+	/* 								SERIALIZATION                      		*/
+	/************************************************************************/
+	RTTITypeBase* D3D11GpuComputeProgram::getRTTIStatic()
+	{
+		return D3D11GpuComputeProgramRTTI::instance();
+	}
+
+	RTTITypeBase* D3D11GpuComputeProgram::getRTTI() const
+	{
+		return D3D11GpuComputeProgram::getRTTIStatic();
+	}
 }

+ 25 - 7
CamelotD3D11RenderSystem/Source/CmD3D11HLSLProgramFactory.cpp

@@ -25,16 +25,16 @@ namespace BansheeEngine
 		{
 		case GPT_VERTEX_PROGRAM:
 			return cm_core_ptr<D3D11GpuVertexProgram, PoolAlloc>(new (cm_alloc<D3D11GpuVertexProgram, PoolAlloc>()) 
-				D3D11GpuVertexProgram(source, entryPoint, profile, includes, requireAdjacencyInfo));
+				D3D11GpuVertexProgram(source, entryPoint, profile, includes));
 		case GPT_FRAGMENT_PROGRAM:
 			return cm_core_ptr<D3D11GpuFragmentProgram, PoolAlloc>(new (cm_alloc<D3D11GpuFragmentProgram, PoolAlloc>()) 
-				D3D11GpuFragmentProgram(source, entryPoint, profile, includes, requireAdjacencyInfo));
+				D3D11GpuFragmentProgram(source, entryPoint, profile, includes));
 		case GPT_HULL_PROGRAM:
 			return cm_core_ptr<D3D11GpuHullProgram, PoolAlloc>(new (cm_alloc<D3D11GpuHullProgram, PoolAlloc>()) 
-				D3D11GpuHullProgram(source, entryPoint, profile, includes, requireAdjacencyInfo));
+				D3D11GpuHullProgram(source, entryPoint, profile, includes));
 		case GPT_DOMAIN_PROGRAM:
 			return cm_core_ptr<D3D11GpuDomainProgram, PoolAlloc>(new (cm_alloc<D3D11GpuDomainProgram, PoolAlloc>()) 
-				D3D11GpuDomainProgram(source, entryPoint, profile, includes, requireAdjacencyInfo));
+				D3D11GpuDomainProgram(source, entryPoint, profile, includes));
 		case GPT_GEOMETRY_PROGRAM:
 			return cm_core_ptr<D3D11GpuGeometryProgram, PoolAlloc>(new (cm_alloc<D3D11GpuGeometryProgram, PoolAlloc>()) 
 				D3D11GpuGeometryProgram(source, entryPoint, profile, includes, requireAdjacencyInfo));
@@ -43,9 +43,27 @@ namespace BansheeEngine
 		return nullptr;
     }
 
-	GpuProgramPtr D3D11HLSLProgramFactory::create()
+	GpuProgramPtr D3D11HLSLProgramFactory::create(GpuProgramType type)
 	{
-		return cm_core_ptr<D3D11GpuVertexProgram, PoolAlloc>(new (cm_alloc<D3D11GpuVertexProgram, PoolAlloc>())
-			D3D11GpuVertexProgram("", "", GPP_NONE, nullptr, false));
+		switch (type)
+		{
+		case GPT_VERTEX_PROGRAM:
+			return cm_core_ptr<D3D11GpuVertexProgram, PoolAlloc>(new (cm_alloc<D3D11GpuVertexProgram, PoolAlloc>())
+				D3D11GpuVertexProgram("", "", GPP_NONE, nullptr));
+		case GPT_FRAGMENT_PROGRAM:
+			return cm_core_ptr<D3D11GpuFragmentProgram, PoolAlloc>(new (cm_alloc<D3D11GpuFragmentProgram, PoolAlloc>())
+				D3D11GpuFragmentProgram("", "", GPP_NONE, nullptr));
+		case GPT_HULL_PROGRAM:
+			return cm_core_ptr<D3D11GpuHullProgram, PoolAlloc>(new (cm_alloc<D3D11GpuHullProgram, PoolAlloc>())
+				D3D11GpuHullProgram("", "", GPP_NONE, nullptr));
+		case GPT_DOMAIN_PROGRAM:
+			return cm_core_ptr<D3D11GpuDomainProgram, PoolAlloc>(new (cm_alloc<D3D11GpuDomainProgram, PoolAlloc>())
+				D3D11GpuDomainProgram("", "", GPP_NONE, nullptr));
+		case GPT_GEOMETRY_PROGRAM:
+			return cm_core_ptr<D3D11GpuGeometryProgram, PoolAlloc>(new (cm_alloc<D3D11GpuGeometryProgram, PoolAlloc>())
+				D3D11GpuGeometryProgram("", "", GPP_NONE, nullptr, false));
+		}
+
+		return nullptr;
 	}
 }

+ 20 - 4
CamelotD3D9Renderer/Include/CmD3D9GpuProgram.h

@@ -50,7 +50,7 @@ namespace BansheeEngine
 
 		D3D9GpuProgram(const String& source, const String& entryPoint, 
 			GpuProgramType gptype, GpuProgramProfile profile, 
-			const Vector<HGpuProgInclude>* includes, bool isAdjacencyInfoRequired = false);
+			const Vector<HGpuProgInclude>* includes);
 
 		void createInternalResources(IDirect3DDevice9* d3d9Device);
 
@@ -101,7 +101,7 @@ namespace BansheeEngine
 		friend class D3D9HLSLProgramFactory;
 
 		D3D9GpuVertexProgram(const String& source, const String& entryPoint, GpuProgramProfile profile,
-			const Vector<HGpuProgInclude>* includes, bool isAdjacencyInfoRequired = false);
+			const Vector<HGpuProgInclude>* includes);
 
 		/**
 		 * @copydoc D3D9GpuProgram::destroy_internal.
@@ -115,6 +115,14 @@ namespace BansheeEngine
 		typedef DeviceToVertexShaderMap::iterator						DeviceToVertexShaderIterator;
 	
 		DeviceToVertexShaderMap		mMapDeviceToVertexShader;	
+
+		/************************************************************************/
+		/* 								SERIALIZATION                      		*/
+		/************************************************************************/
+	public:
+		friend class D3D9GpuVertexProgramRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const;
     };
 
     /** Direct3D implementation of low-level fragment programs. */
@@ -136,7 +144,7 @@ namespace BansheeEngine
 		friend class D3D9HLSLProgramFactory;
 
 		D3D9GpuFragmentProgram(const String& source, const String& entryPoint, GpuProgramProfile profile,
-			const Vector<HGpuProgInclude>* includes, bool isAdjacencyInfoRequired = false);
+			const Vector<HGpuProgInclude>* includes);
 
 		/**
 		 * @copydoc D3D9GpuProgram::destroy_internal.
@@ -149,7 +157,15 @@ namespace BansheeEngine
 		typedef Map<IDirect3DDevice9*, IDirect3DPixelShader9*>	DeviceToPixelShaderMap;
 		typedef DeviceToPixelShaderMap::iterator						DeviceToPixelShaderIterator;
 
-		DeviceToPixelShaderMap		mMapDeviceToPixelShader;			
+		DeviceToPixelShaderMap		mMapDeviceToPixelShader;	
+
+		/************************************************************************/
+		/* 								SERIALIZATION                      		*/
+		/************************************************************************/
+	public:
+		friend class D3D9GpuFragmentProgramRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const;
     };
 
 	typedef std::shared_ptr<D3D9GpuProgram> D3D9GpuProgramPtr;

+ 78 - 0
CamelotD3D9Renderer/Include/CmD3D9GpuProgramRTTI.h

@@ -0,0 +1,78 @@
+#pragma once
+
+#include "CmPrerequisites.h"
+#include "CmRTTIType.h"
+#include "CmGpuProgramManager.h"
+#include "CmD3D9GpuProgram.h"
+
+namespace BansheeEngine
+{
+	class CM_D3D9_EXPORT D3D9GpuProgramRTTI : public RTTIType<D3D9GpuProgram, GpuProgram, D3D9GpuProgramRTTI>
+	{
+	public:
+		D3D9GpuProgramRTTI()
+		{ }
+
+		virtual const String& getRTTIName()
+		{
+			static String name = "D3D9GpuProgram";
+			return name;
+		}
+
+		virtual UINT32 getRTTIId()
+		{
+			return TID_D3D9_GpuProgram;
+		}
+
+		virtual std::shared_ptr<IReflectable> newRTTIObject()
+		{
+			CM_EXCEPT(InvalidStateException, "Cannot create an instance of an abstract class.");
+		}
+	};
+
+	class CM_D3D9_EXPORT D3D9GpuVertexProgramRTTI : public RTTIType<D3D9GpuVertexProgram, D3D9GpuProgram, D3D9GpuVertexProgramRTTI>
+	{
+	public:
+		D3D9GpuVertexProgramRTTI()
+		{ }
+
+		virtual const String& getRTTIName()
+		{
+			static String name = "D3D9GpuVertexProgram";
+			return name;
+		}
+
+		virtual UINT32 getRTTIId()
+		{
+			return TID_D3D9_GpuVertexProgram;
+		}
+
+		virtual std::shared_ptr<IReflectable> newRTTIObject()
+		{
+			return GpuProgramManager::instance().createEmpty("hlsl", GPT_VERTEX_PROGRAM);
+		}
+	};
+
+	class CM_D3D9_EXPORT D3D9GpuFragmentProgramRTTI : public RTTIType<D3D9GpuFragmentProgram, D3D9GpuProgram, D3D9GpuFragmentProgramRTTI>
+	{
+	public:
+		D3D9GpuFragmentProgramRTTI()
+		{ }
+
+		virtual const String& getRTTIName()
+		{
+			static String name = "D3D9GpuFragmentProgram";
+			return name;
+		}
+
+		virtual UINT32 getRTTIId()
+		{
+			return TID_D3D9_GpuFragmentProgram;
+		}
+
+		virtual std::shared_ptr<IReflectable> newRTTIObject()
+		{
+			return GpuProgramManager::instance().createEmpty("hlsl", GPT_FRAGMENT_PROGRAM);
+		}
+	};
+}

+ 59 - 15
CamelotD3D9Renderer/Include/CmD3D9HLSLParamParser.h

@@ -185,77 +185,121 @@ namespace BansheeEngine
 			case D3DXPC_MATRIX_ROWS:
 				{
 					int firstDim, secondDim;
-					firstDim = d3dDesc.RegisterCount / d3dDesc.Elements;
+					int firstActualDim; // Actual size might be less than requested because of optimization, we need to know both
+					firstActualDim = d3dDesc.RegisterCount / d3dDesc.Elements;
 
 					if (d3dDesc.Class == D3DXPC_MATRIX_ROWS)
+					{
+						firstDim = d3dDesc.Rows;
 						secondDim = d3dDesc.Columns;
+					}
 					else
+					{
+						firstDim = d3dDesc.Columns;
 						secondDim = d3dDesc.Rows;
+					}
 
-					switch(firstDim)
+					switch (firstActualDim)
 					{
 					case 2:
 						switch(secondDim)
 						{
 						case 2:
-							memberDesc.type = GPDT_MATRIX_2X2;
 							memberDesc.elementSize = 8; // HLSL always packs
 							memberDesc.arrayElementStride = 8;
 							break;
 						case 3:
-							memberDesc.type = GPDT_MATRIX_2X3;
 							memberDesc.elementSize = 8; // HLSL always packs
 							memberDesc.arrayElementStride = 8;
 							break;
 						case 4:
-							memberDesc.type = GPDT_MATRIX_2X4;
 							memberDesc.elementSize = 8; 
 							memberDesc.arrayElementStride = 8;
 							break;
-						} // columns
+						}
 						break;
 					case 3:
 						switch(secondDim)
 						{
 						case 2:
-							memberDesc.type = GPDT_MATRIX_3X2;
 							memberDesc.elementSize = 12; // HLSL always packs
 							memberDesc.arrayElementStride = 12;
 							break;
 						case 3:
-							memberDesc.type = GPDT_MATRIX_3X3;
 							memberDesc.elementSize = 12; // HLSL always packs
 							memberDesc.arrayElementStride = 12;
 							break;
 						case 4:
-							memberDesc.type = GPDT_MATRIX_3X4;
 							memberDesc.elementSize = 12; 
 							memberDesc.arrayElementStride = 12;
 							break;
-						} // columns
+						}
 						break;
 					case 4:
 						switch(secondDim)
 						{
 						case 2:
-							memberDesc.type = GPDT_MATRIX_4X2;
 							memberDesc.elementSize = 16; // HLSL always packs
 							memberDesc.arrayElementStride = 16;
 							break;
 						case 3:
-							memberDesc.type = GPDT_MATRIX_4X3;
 							memberDesc.elementSize = 16; // HLSL always packs
 							memberDesc.arrayElementStride = 16;
 							break;
 						case 4:
-							memberDesc.type = GPDT_MATRIX_4X4;
 							memberDesc.elementSize = 16; 
 							memberDesc.arrayElementStride = 16;
 							break;
-						} // secondDim
+						}
 						break;
 
-					} // firstDim
+					}
+
+					switch (firstDim)
+					{
+					case 2:
+						switch (secondDim)
+						{
+						case 2:
+							memberDesc.type = GPDT_MATRIX_2X2;
+							break;
+						case 3:
+							memberDesc.type = GPDT_MATRIX_2X3;
+							break;
+						case 4:
+							memberDesc.type = GPDT_MATRIX_2X4;
+							break;
+						} 
+						break;
+					case 3:
+						switch (secondDim)
+						{
+						case 2:
+							memberDesc.type = GPDT_MATRIX_3X2;
+							break;
+						case 3:
+							memberDesc.type = GPDT_MATRIX_3X3;
+							break;
+						case 4:
+							memberDesc.type = GPDT_MATRIX_3X4;
+							break;
+						} 
+						break;
+					case 4:
+						switch (secondDim)
+						{
+						case 2:
+							memberDesc.type = GPDT_MATRIX_4X2;
+							break;
+						case 3:
+							memberDesc.type = GPDT_MATRIX_4X3;
+							break;
+						case 4:
+							memberDesc.type = GPDT_MATRIX_4X4;
+							break;
+						}
+						break;
+					}
 				}
 				break;
 			case D3DXPC_SCALAR:

+ 1 - 1
CamelotD3D9Renderer/Include/CmD3D9HLSLProgramFactory.h

@@ -17,7 +17,7 @@ namespace BansheeEngine
         GpuProgramPtr create(const String& source, const String& entryPoint, GpuProgramType gptype, 
 			GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes, bool requiresAdjacency);
 
-		GpuProgramPtr create();
+		GpuProgramPtr create(GpuProgramType type);
 
 	protected:
 		static String LANGUAGE_NAME;

+ 3 - 1
CamelotD3D9Renderer/Include/CmD3D9Prerequisites.h

@@ -82,7 +82,9 @@ namespace BansheeEngine
 
 	enum TypeID_D3D9
 	{
-		TID_D3D9_GpuProgram = 10000
+		TID_D3D9_GpuProgram = 10000,
+		TID_D3D9_GpuVertexProgram = 10001,
+		TID_D3D9_GpuFragmentProgram = 10002
 	};
 
     //-------------------------------------------

+ 33 - 6
CamelotD3D9Renderer/Source/CmD3D9GpuProgram.cpp

@@ -13,8 +13,8 @@
 namespace BansheeEngine 
 {
     D3D9GpuProgram::D3D9GpuProgram(const String& source, const String& entryPoint, 
-		GpuProgramType gptype, GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes, bool isAdjacencyInfoRequired)
-		: GpuProgram(source, entryPoint, gptype, profile, includes, isAdjacencyInfoRequired),
+		GpuProgramType gptype, GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes)
+		: GpuProgram(source, entryPoint, gptype, profile, includes, false),
 		mMicrocode(nullptr), mColumnMajorMatrices(false), mOptimisationLevel(OPT_DEFAULT)
     { }
 
@@ -28,6 +28,7 @@ namespace BansheeEngine
 			mIsCompiled = false;
 			mCompileError = "Specified program is not supported by the current render system.";
 
+			GpuProgram::initialize_internal();
 			return;
 		}
 
@@ -235,8 +236,8 @@ namespace BansheeEngine
 	}
 
 	D3D9GpuVertexProgram::D3D9GpuVertexProgram(const String& source, const String& entryPoint, 
-		GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes, bool isAdjacencyInfoRequired)
-		: D3D9GpuProgram(source, entryPoint, GPT_VERTEX_PROGRAM, profile, includes, isAdjacencyInfoRequired)
+		GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes)
+		: D3D9GpuProgram(source, entryPoint, GPT_VERTEX_PROGRAM, profile, includes)
     {
 
     }
@@ -323,9 +324,22 @@ namespace BansheeEngine
 		return it->second;
 	}
 
+	/************************************************************************/
+	/* 								SERIALIZATION                      		*/
+	/************************************************************************/
+	RTTITypeBase* D3D9GpuVertexProgram::getRTTIStatic()
+	{
+		return D3D9GpuVertexProgramRTTI::instance();
+	}
+
+	RTTITypeBase* D3D9GpuVertexProgram::getRTTI() const
+	{
+		return D3D9GpuVertexProgram::getRTTIStatic();
+	}
+
     D3D9GpuFragmentProgram::D3D9GpuFragmentProgram(const String& source, const String& entryPoint, 
-		GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes, bool isAdjacencyInfoRequired)
-		: D3D9GpuProgram(source, entryPoint, GPT_FRAGMENT_PROGRAM, profile, includes, isAdjacencyInfoRequired)
+		GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes)
+		: D3D9GpuProgram(source, entryPoint, GPT_FRAGMENT_PROGRAM, profile, includes)
     {
 
     }
@@ -407,5 +421,18 @@ namespace BansheeEngine
 
 		return it->second;
 	}
+
+	/************************************************************************/
+	/* 								SERIALIZATION                      		*/
+	/************************************************************************/
+	RTTITypeBase* D3D9GpuFragmentProgram::getRTTIStatic()
+	{
+		return D3D9GpuFragmentProgramRTTI::instance();
+	}
+
+	RTTITypeBase* D3D9GpuFragmentProgram::getRTTI() const
+	{
+		return D3D9GpuFragmentProgram::getRTTIStatic();
+	}
 }
 

+ 18 - 6
CamelotD3D9Renderer/Source/CmD3D9HLSLProgramFactory.cpp

@@ -25,14 +25,14 @@ namespace BansheeEngine
 		if (gptype == GPT_VERTEX_PROGRAM)
 		{
 			D3D9GpuVertexProgram* prog = new (cm_alloc<D3D9GpuVertexProgram, PoolAlloc>()) 
-				D3D9GpuVertexProgram(source, entryPoint, profile, includes, requiresAdjacency);
+				D3D9GpuVertexProgram(source, entryPoint, profile, includes);
 
 			return cm_core_ptr<D3D9GpuVertexProgram, PoolAlloc>(prog);
 		}
 		else if (gptype == GPT_FRAGMENT_PROGRAM)
 		{
 			D3D9GpuFragmentProgram* prog = new (cm_alloc<D3D9GpuFragmentProgram, PoolAlloc>())
-				D3D9GpuFragmentProgram(source, entryPoint, profile, includes, requiresAdjacency);
+				D3D9GpuFragmentProgram(source, entryPoint, profile, includes);
 
 			return cm_core_ptr<D3D9GpuFragmentProgram, PoolAlloc>(prog);
 		}
@@ -40,11 +40,23 @@ namespace BansheeEngine
 		return nullptr;
     }
 
-	GpuProgramPtr D3D9HLSLProgramFactory::create()
+	GpuProgramPtr D3D9HLSLProgramFactory::create(GpuProgramType type)
 	{
-		D3D9GpuVertexProgram* prog = new (cm_alloc<D3D9GpuVertexProgram, PoolAlloc>())
-			D3D9GpuVertexProgram("", "", GPP_NONE, nullptr);
+		if (type == GPT_VERTEX_PROGRAM)
+		{
+			D3D9GpuVertexProgram* prog = new (cm_alloc<D3D9GpuVertexProgram, PoolAlloc>())
+				D3D9GpuVertexProgram("", "", GPP_NONE, nullptr);
+
+			return cm_core_ptr<D3D9GpuVertexProgram, PoolAlloc>(prog);
+		}
+		else if (type == GPT_FRAGMENT_PROGRAM)
+		{
+			D3D9GpuFragmentProgram* prog = new (cm_alloc<D3D9GpuFragmentProgram, PoolAlloc>())
+				D3D9GpuFragmentProgram("", "", GPP_NONE, nullptr);
 
-		return cm_core_ptr<D3D9GpuVertexProgram, PoolAlloc>(prog);
+			return cm_core_ptr<D3D9GpuFragmentProgram, PoolAlloc>(prog);
+		}
+
+		return nullptr;
 	}
 }

+ 2 - 0
CamelotGLRenderer/Source/GLSL/include/CmGLSLGpuProgram.h

@@ -19,6 +19,8 @@ namespace BansheeEngine {
 	public:
 		~GLSLGpuProgram();
 
+		bool isSupported() const;
+
 		const GLuint getGLHandle() const { return mGLHandle; }
 
 		/** Sets the preprocessor defines use to compile the program. */

+ 1 - 1
CamelotGLRenderer/Source/GLSL/include/CmGLSLProgramFactory.h

@@ -14,7 +14,7 @@ namespace BansheeEngine
 		/// create an instance of GLSLProgram
         GpuProgramPtr create(const String& source, const String& entryPoint, GpuProgramType gptype, 
 			GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes, bool requireAdjacency);
-		GpuProgramPtr create();
+		GpuProgramPtr create(GpuProgramType type);
 
 	protected:
 		static const String LANGUAGE_NAME;

+ 10 - 0
CamelotGLRenderer/Source/GLSL/src/CmGLSLGpuProgram.cpp

@@ -83,6 +83,7 @@ namespace BansheeEngine {
 			mIsCompiled = false;
 			mCompileError = "Specified program is not supported by the current render system.";
 
+			GpuProgram::initialize_internal();
 			return;
 		}
 
@@ -212,6 +213,15 @@ namespace BansheeEngine {
 		GpuProgram::destroy_internal();
 	}
 
+	bool GLSLGpuProgram::isSupported() const
+	{
+		if (!isRequiredCapabilitiesSupported())
+			return false;
+
+		RenderSystem* rs = BansheeEngine::RenderSystem::instancePtr();
+		return rs->getCapabilities()->isShaderProfileSupported("glsl");
+	}
+
 	const String& GLSLGpuProgram::getLanguage() const
 	{
 		static const String language = "glsl";

+ 2 - 2
CamelotGLRenderer/Source/GLSL/src/CmGLSLProgramFactory.cpp

@@ -18,9 +18,9 @@ namespace BansheeEngine
 		return cm_core_ptr<GLSLGpuProgram, PoolAlloc>(prog);
     }
 
-	GpuProgramPtr GLSLProgramFactory::create()
+	GpuProgramPtr GLSLProgramFactory::create(GpuProgramType type)
 	{
-		GLSLGpuProgram* prog = new (cm_alloc<GLSLGpuProgram, PoolAlloc>()) GLSLGpuProgram("", "", GPT_VERTEX_PROGRAM, GPP_NONE, nullptr, false);
+		GLSLGpuProgram* prog = new (cm_alloc<GLSLGpuProgram, PoolAlloc>()) GLSLGpuProgram("", "", type, GPP_NONE, nullptr, false);
 
 		return cm_core_ptr<GLSLGpuProgram, PoolAlloc>(prog);
 	}