Browse Source

BansheeSL: Shader parser generates an actual Shader
Added StringID for neater and faster way of identifying objects (compared to raw strings)

Marko Pintera 10 years ago
parent
commit
ab1746c542
45 changed files with 2723 additions and 1480 deletions
  1. 3 0
      BansheeCore/Include/BsCorePrerequisites.h
  2. 16 21
      BansheeCore/Include/BsCoreRenderer.h
  3. 1 1
      BansheeCore/Include/BsRenderAPI.h
  4. 3 3
      BansheeCore/Include/BsRenderAPICapabilities.h
  5. 0 13
      BansheeCore/Include/BsRendererManager.h
  6. 7 6
      BansheeCore/Include/BsShader.h
  7. 8 9
      BansheeCore/Include/BsTechnique.h
  8. 4 4
      BansheeCore/Include/BsTechniqueRTTI.h
  9. 1 1
      BansheeCore/Source/BsMaterial.cpp
  10. 0 6
      BansheeCore/Source/BsRendererManager.cpp
  11. 4 3
      BansheeCore/Source/BsShader.cpp
  12. 16 15
      BansheeCore/Source/BsTechnique.cpp
  13. 1 1
      BansheeD3D11RenderSystem/Include/BsD3D11RenderAPI.h
  14. 2 2
      BansheeD3D11RenderSystem/Source/BsD3D11RenderAPI.cpp
  15. 1 1
      BansheeD3D9RenderSystem/Include/BsD3D9RenderAPI.h
  16. 2 2
      BansheeD3D9RenderSystem/Source/BsD3D9RenderAPI.cpp
  17. 1 1
      BansheeEditor/Include/BsBuiltinEditorResources.h
  18. 12 12
      BansheeEditor/Source/BsBuiltinEditorResources.cpp
  19. 1 1
      BansheeEditor/Source/BsScenePicking.cpp
  20. 1 1
      BansheeEngine/Include/BsBuiltinResources.h
  21. 4 5
      BansheeEngine/Include/BsPrerequisites.h
  22. 4 4
      BansheeEngine/Source/BsBuiltinResources.cpp
  23. 1 1
      BansheeGLRenderSystem/Include/BsGLRenderAPI.h
  24. 2 2
      BansheeGLRenderSystem/Source/BsGLRenderAPI.cpp
  25. 6 8
      BansheeRenderer/Include/BsBansheeRenderer.h
  26. 4 10
      BansheeRenderer/Source/BsBansheeLitTexRenderableController.cpp
  27. 3 3
      BansheeRenderer/Source/BsBansheeRenderer.cpp
  28. 449 530
      BansheeSL/BsLexerFX.c
  29. 1 117
      BansheeSL/BsLexerFX.h
  30. 73 73
      BansheeSL/BsLexerFX.l
  31. 462 437
      BansheeSL/BsParserFX.c
  32. 45 44
      BansheeSL/BsParserFX.h
  33. 60 3
      BansheeSL/BsParserFX.y
  34. 66 3
      BansheeSL/Include/BsASTFX.h
  35. 1 1
      BansheeSL/Include/BsMMAlloc.h
  36. 2 2
      BansheeSL/Source/BSMMAlloc.c
  37. 5 0
      BansheeSL/Source/BsASTFX.c
  38. 1048 0
      BansheeSL/Source/BsSLPlugin.cpp
  39. 2 0
      BansheeUtility/BansheeUtility.vcxproj
  40. 6 0
      BansheeUtility/BansheeUtility.vcxproj.filters
  41. 1 0
      BansheeUtility/Include/BsFwdDeclUtil.h
  42. 2 1
      BansheeUtility/Include/BsPrerequisitesUtil.h
  43. 205 0
      BansheeUtility/Include/BsStringID.h
  44. 146 0
      BansheeUtility/Source/BsStringID.cpp
  45. 41 133
      TODO.txt

+ 3 - 0
BansheeCore/Include/BsCorePrerequisites.h

@@ -59,6 +59,9 @@
 
 namespace BansheeEngine 
 {
+	static const StringID RenderAPIAny = "AnyRenderAPI";
+	static const StringID RendererAny = "AnyRenderer";
+
     class Color;
     class GpuProgram;
     class GpuProgramManager;

+ 16 - 21
BansheeCore/Include/BsCoreRenderer.h

@@ -3,34 +3,29 @@
 #include "BsCorePrerequisites.h"
 #include "BsGameObject.h"
 #include "BsEvent.h"
+#include "BsStringID.h"
 
 namespace BansheeEngine
 {
 	/**
-	 * @brief	Available parameter block semantics that allow the renderer to identify
-	 *			the use of a GPU program parameter block specified in a shader.
+	 * Available parameter block semantics that allow the renderer to identify
+	 * the use of a GPU program parameter block specified in a shader.
 	 */
-	enum RendererBlockSemantic
-	{
-		// 0 - Reserved
-		RBS_Static = 1,
-		RBS_PerCamera = 2,
-		RBS_PerFrame = 3,
-		RBS_PerObject = 4
-	};
+
+	static StringID RBS_Static = "Static";
+	static StringID RBS_PerCamera = "PerCamera";
+	static StringID RBS_PerFrame = "PerFrame";
+	static StringID RBS_PerObject = "PerObject";
 
 	/**
-	 * @brief	Available parameter semantics that allow the renderer to identify
-	 *			the use of a GPU parameter specified in a shader.
+	 * Available parameter semantics that allow the renderer to identify
+	 * the use of a GPU parameter specified in a shader.
 	 */
-	enum RendererParamSemantic
-	{
-		// 0 - Reserved
-		RPS_WorldViewProjTfrm = 1,
-		RPS_ViewProjTfrm = 2,
-		RPS_WorldTfrm = 3,
-		RPS_MainTex = 4
-	};
+
+	static StringID RPS_WorldViewProjTfrm = "WVP";
+	static StringID RPS_ViewProjTfrm = "VP";
+	static StringID RPS_WorldTfrm = "World";
+	static StringID RPS_Diffuse = "Diffuse";
 
 	/**
 	 * @brief	Primarily rendering class that allows you to specify how to render objects that exist
@@ -62,7 +57,7 @@ namespace BansheeEngine
 		 * @brief	Name of the renderer. Used by materials to find 
 		 * 			an appropriate technique for this renderer.
 		 */
-		virtual const String& getName() const = 0;
+		virtual const StringID& getName() const = 0;
 
 		/**
 		 * @brief	Called in order to render all currently active cameras.

+ 1 - 1
BansheeCore/Include/BsRenderAPI.h

@@ -155,7 +155,7 @@ namespace BansheeEngine
 		 *
 		 * @note	Thread safe.
 		 */
-		virtual const String& getName() const = 0;
+		virtual const StringID& getName() const = 0;
 
 		/**
 		 * @brief	Gets the name of the primary shading language

+ 3 - 3
BansheeCore/Include/BsRenderAPICapabilities.h

@@ -576,7 +576,7 @@ namespace BansheeEngine
 		/**
 		 * @brief	Get the identifier of the render system from which these capabilities were generated.
 		 */
-		String getRenderSystemName() const
+		StringID getRenderSystemName() const
 		{
 			return mRenderSystemName;
 		}
@@ -584,7 +584,7 @@ namespace BansheeEngine
 		/**
 		 * @brief	Set the identifier of the render system from which these capabilities were generated.
 		 */
-		void setRenderSystemName(const String& rs)
+		void setRenderSystemName(const StringID& rs)
 		{
 			mRenderSystemName = rs;
 		}
@@ -618,7 +618,7 @@ namespace BansheeEngine
 		// The name of the device as reported by the render system
 		String mDeviceName;
 		// The identifier associated with the render system for which these capabilities are valid
-		String mRenderSystemName;
+		StringID mRenderSystemName;
 
 		// The number of floating-point constants vertex programs support
 		UINT16 mVertexProgramConstantFloatCount = 0;

+ 0 - 13
BansheeCore/Include/BsRendererManager.h

@@ -28,19 +28,6 @@ namespace BansheeEngine
 		 */
 		CoreRendererPtr getActive() { return mActiveRenderer; }
 
-		/**
-		 * @brief	Core renderer represents a set of shared features within all renderers.
-		 * 			Techniques using this renderer name will report as if they are supported regardless
-		 * 			of the active renderer.
-		 *
-		 * @note	Useful when you want to make a technique working on all renderers. (Normally techniques
-		 * 			need to be different as far as render system is concerned but can often be same from
-		 * 			renderers perspective).
-		 * 			
-		 * @see		Technique
-		 */
-		static const String& getCoreRendererName();
-
 		/**
 		 * @brief	Registers a new renderer factory. Any renderer you try to make active with
 		 * 			"setActive" you will need to have previously registered here.

+ 7 - 6
BansheeCore/Include/BsShader.h

@@ -2,6 +2,7 @@
 
 #include "BsCorePrerequisites.h"
 #include "BsResource.h"
+#include "BsStringID.h"
 
 namespace BansheeEngine
 {
@@ -15,7 +16,7 @@ namespace BansheeEngine
 		String name;
 		String gpuVariableName;
 		GpuParamDataType type;
-		UINT32 rendererSemantic;
+		StringID rendererSemantic;
 		UINT32 arraySize;
 		UINT32 elementSize;
 	};
@@ -29,7 +30,7 @@ namespace BansheeEngine
 	{
 		String name;
 		Vector<String> gpuVariableNames;
-		UINT32 rendererSemantic;
+		StringID rendererSemantic;
 		GpuParamObjectType type;
 	};
 
@@ -40,7 +41,7 @@ namespace BansheeEngine
 	{
 		String name;
 		bool shared;
-		UINT32 rendererSemantic;
+		StringID rendererSemantic;
 		GpuParamBlockUsage usage;
 	};
 
@@ -67,7 +68,7 @@ namespace BansheeEngine
 		 * @param	elementSize	   	 (optional) Size of an individual element in the array, in bytes. You only need to set this if you are setting variable
 		 * 							 length parameters, like structs.
 		 */
-		void addParameter(const String& name, const String& gpuVariableName, GpuParamDataType type, UINT32 rendererSemantic = 0,
+		void addParameter(const String& name, const String& gpuVariableName, GpuParamDataType type, StringID rendererSemantic = StringID::NONE,
 			UINT32 arraySize = 1, UINT32 elementSize = 0);
 
 		/**
@@ -87,7 +88,7 @@ namespace BansheeEngine
 		 * @note	Mapping multiple GPU variables to a single parameter is useful when you are defining a shader that supports techniques across different render
 		 *			systems where GPU variable names for the same parameters might differ.
 		 */
-		void addParameter(const String& name, const String& gpuVariableName, GpuParamObjectType type, UINT32 rendererSemantic = 0);
+		void addParameter(const String& name, const String& gpuVariableName, GpuParamObjectType type, StringID rendererSemantic = StringID::NONE);
 
 		/**
 		 * @brief	Changes parameters of a parameter block with the specified name.
@@ -104,7 +105,7 @@ namespace BansheeEngine
 		 *							 buffer and you will need to respect them. If you don't respect them your shader will be deemed incompatible and won't be used. 
 		 *							 Value of 0 signifies the parameter block is not used by the renderer.
 		 */
-		void setParamBlockAttribs(const String& name, bool shared, GpuParamBlockUsage usage, UINT32 rendererSemantic = 0);
+		void setParamBlockAttribs(const String& name, bool shared, GpuParamBlockUsage usage, StringID rendererSemantic = StringID::NONE);
 
 		/**
 		 * @brief	sorting type to use when performing sort in the render queue. Default value is sort front to back

+ 8 - 9
BansheeCore/Include/BsTechnique.h

@@ -18,7 +18,7 @@ namespace BansheeEngine
 	class BS_CORE_EXPORT TechniqueBase
 	{
 	public:
-		TechniqueBase(const String& renderSystem, const String& renderer);
+		TechniqueBase(const StringID& renderAPI, const StringID& renderer);
 		virtual ~TechniqueBase() { }
 
 		/**
@@ -28,9 +28,8 @@ namespace BansheeEngine
 		bool isSupported() const;
 
 	protected:
-
-		String mRenderSystem;
-		String mRenderer;
+		StringID mRenderAPI;
+		StringID mRenderer;
 	};
 
 	/**
@@ -50,7 +49,7 @@ namespace BansheeEngine
 		typedef typename TPassType<Core>::Type PassType;
 		
 		TTechnique();
-		TTechnique(const String& renderSystem, const String& renderer, const Vector<SPtr<PassType>>& passes);
+		TTechnique(const StringID& renderAPI, const StringID& renderer, const Vector<SPtr<PassType>>& passes);
 		virtual ~TTechnique() { }
 
 		/**
@@ -75,12 +74,12 @@ namespace BansheeEngine
 	class BS_CORE_EXPORT TechniqueCore : public CoreObjectCore, public TTechnique<true>
 	{
 	public:
-		TechniqueCore(const String& renderSystem, const String& renderer, const Vector<SPtr<PassCore>>& passes);
+		TechniqueCore(const StringID& renderAPI, const StringID& renderer, const Vector<SPtr<PassCore>>& passes);
 
 		/**
 		 * @brief	Creates a new technique.
 		 */
-		static SPtr<TechniqueCore> create(const String& renderSystem, const String& renderer, const Vector<SPtr<PassCore>>& passes);
+		static SPtr<TechniqueCore> create(const StringID& renderAPI, const StringID& renderer, const Vector<SPtr<PassCore>>& passes);
 	};
 
 	/**
@@ -91,7 +90,7 @@ namespace BansheeEngine
 	class BS_CORE_EXPORT Technique : public IReflectable, public CoreObject, public TTechnique<false>
 	{
 	public:
-		Technique(const String& renderSystem, const String& renderer, const Vector<SPtr<Pass>>& passes);
+		Technique(const StringID& renderAPI, const StringID& renderer, const Vector<SPtr<Pass>>& passes);
 
 		/**
 		 * @brief	Retrieves an implementation of a technique usable only from the
@@ -102,7 +101,7 @@ namespace BansheeEngine
 		/**
 		 * @brief	Creates a new technique.
 		 */
-		static TechniquePtr create(const String& renderSystem, const String& renderer, const Vector<SPtr<Pass>>& passes);
+		static TechniquePtr create(const StringID& renderAPI, const StringID& renderer, const Vector<SPtr<Pass>>& passes);
 
 	protected:
 		/**

+ 4 - 4
BansheeCore/Include/BsTechniqueRTTI.h

@@ -9,11 +9,11 @@ namespace BansheeEngine
 	class BS_CORE_EXPORT TechniqueRTTI : public RTTIType<Technique, IReflectable, TechniqueRTTI>
 	{
 	private:
-		String& getRenderSystem(Technique* obj) { return obj->mRenderSystem; }
-		void setRenderSystem(Technique* obj, String& val) { obj->mRenderSystem = val; } 
+		StringID& getRenderSystem(Technique* obj) { return obj->mRenderAPI; }
+		void setRenderSystem(Technique* obj, StringID& val) { obj->mRenderAPI = val; }
 
-		String& getRenderer(Technique* obj) { return obj->mRenderer; }
-		void setRenderer(Technique* obj, String& val) { obj->mRenderer = val; } 
+		StringID& getRenderer(Technique* obj) { return obj->mRenderer; }
+		void setRenderer(Technique* obj, StringID& val) { obj->mRenderer = val; }
 
 		PassPtr getPass(Technique* obj, UINT32 idx)
 		{

+ 1 - 1
BansheeCore/Source/BsMaterial.cpp

@@ -329,7 +329,7 @@ namespace BansheeEngine
 			auto iterFind = shaderDesc.find(*iter);
 			if (iterFind != shaderDesc.end())
 			{
-				shaderBlockDesc.create = !iterFind->second.shared && iterFind->second.rendererSemantic == 0;
+				shaderBlockDesc.create = !iterFind->second.shared && iterFind->second.rendererSemantic == StringID::NONE;
 				shaderBlockDesc.usage = iterFind->second.usage;
 			}
 

+ 0 - 6
BansheeCore/Source/BsRendererManager.cpp

@@ -35,12 +35,6 @@ namespace BansheeEngine
 		}
 	}
 
-	const String& RendererManager::getCoreRendererName()
-	{
-		static String name = "CoreRenderer";
-		return name;
-	}
-
 	void RendererManager::_registerFactory(RendererFactoryPtr factory)
 	{
 		assert(factory != nullptr);

+ 4 - 3
BansheeCore/Source/BsShader.cpp

@@ -15,7 +15,8 @@ namespace BansheeEngine
 
 	}
 
-	void SHADER_DESC::addParameter(const String& name, const String& gpuVariableName, GpuParamDataType type, UINT32 rendererSemantic, UINT32 arraySize, UINT32 elementSize)
+	void SHADER_DESC::addParameter(const String& name, const String& gpuVariableName, GpuParamDataType type, 
+		StringID rendererSemantic, UINT32 arraySize, UINT32 elementSize)
 	{
 		if(type == GPDT_STRUCT && elementSize <= 0)
 			BS_EXCEPT(InvalidParametersException, "You need to provide a non-zero element size for a struct parameter.")
@@ -32,7 +33,7 @@ namespace BansheeEngine
 		objectParams.erase(name);
 	}
 
-	void SHADER_DESC::addParameter(const String& name, const String& gpuVariableName, GpuParamObjectType type, UINT32 rendererSemantic)
+	void SHADER_DESC::addParameter(const String& name, const String& gpuVariableName, GpuParamObjectType type, StringID rendererSemantic)
 	{
 		auto iterFind = objectParams.find(name);
 
@@ -71,7 +72,7 @@ namespace BansheeEngine
 		dataParams.erase(name);
 	}
 
-	void SHADER_DESC::setParamBlockAttribs(const String& name, bool shared, GpuParamBlockUsage usage, UINT32 rendererSemantic)
+	void SHADER_DESC::setParamBlockAttribs(const String& name, bool shared, GpuParamBlockUsage usage, StringID rendererSemantic)
 	{
 		SHADER_PARAM_BLOCK_DESC desc;
 		desc.name = name;

+ 16 - 15
BansheeCore/Source/BsTechnique.cpp

@@ -9,17 +9,18 @@
 
 namespace BansheeEngine
 {
-	TechniqueBase::TechniqueBase(const String& renderSystem, const String& renderer)
-		:mRenderSystem(renderSystem), mRenderer(renderer)
+	TechniqueBase::TechniqueBase(const StringID& renderAPI, const StringID& renderer)
+		:mRenderAPI(renderAPI), mRenderer(renderer)
 	{
 
 	}
 
 	bool TechniqueBase::isSupported() const
 	{
-		if (RenderAPICore::instancePtr()->getName() == mRenderSystem &&
+		if ((RenderAPICore::instancePtr()->getName() == mRenderAPI ||
+			RenderAPIAny == mRenderAPI) &&
 			(RendererManager::instance().getActive()->getName() == mRenderer ||
-			RendererManager::getCoreRendererName() == mRenderer))
+			RendererAny == mRenderer))
 		{
 			return true;
 		}
@@ -28,8 +29,8 @@ namespace BansheeEngine
 	}
 
 	template<bool Core>
-	TTechnique<Core>::TTechnique(const String& renderSystem, const String& renderer, const Vector<SPtr<PassType>>& passes)
-		: TechniqueBase(renderSystem, renderer), mPasses(passes)
+	TTechnique<Core>::TTechnique(const StringID& renderAPI, const StringID& renderer, const Vector<SPtr<PassType>>& passes)
+		: TechniqueBase(renderAPI, renderer), mPasses(passes)
 	{ }
 
 	template<bool Core>
@@ -49,13 +50,13 @@ namespace BansheeEngine
 	template class TTechnique < false > ;
 	template class TTechnique < true >;
 
-	TechniqueCore::TechniqueCore(const String& renderSystem, const String& renderer, const Vector<SPtr<PassCore>>& passes)
-		:TTechnique(renderSystem, renderer, passes)
+	TechniqueCore::TechniqueCore(const StringID& renderAPI, const StringID& renderer, const Vector<SPtr<PassCore>>& passes)
+		:TTechnique(renderAPI, renderer, passes)
 	{ }
 
-	SPtr<TechniqueCore> TechniqueCore::create(const String& renderSystem, const String& renderer, const Vector<SPtr<PassCore>>& passes)
+	SPtr<TechniqueCore> TechniqueCore::create(const StringID& renderAPI, const StringID& renderer, const Vector<SPtr<PassCore>>& passes)
 	{
-		TechniqueCore* technique = new (bs_alloc<TechniqueCore>()) TechniqueCore(renderSystem, renderer, passes);
+		TechniqueCore* technique = new (bs_alloc<TechniqueCore>()) TechniqueCore(renderAPI, renderer, passes);
 		SPtr<TechniqueCore> techniquePtr = bs_shared_ptr<TechniqueCore, GenAlloc>(technique);
 		techniquePtr->_setThisPtr(techniquePtr);
 		techniquePtr->initialize();
@@ -63,8 +64,8 @@ namespace BansheeEngine
 		return techniquePtr;
 	}
 
-	Technique::Technique(const String& renderSystem, const String& renderer, const Vector<SPtr<Pass>>& passes)
-		:TTechnique(renderSystem, renderer, passes)
+	Technique::Technique(const StringID& renderAPI, const StringID& renderer, const Vector<SPtr<Pass>>& passes)
+		:TTechnique(renderAPI, renderer, passes)
 	{ }
 
 	Technique::Technique()
@@ -82,7 +83,7 @@ namespace BansheeEngine
 		for (auto& pass : mPasses)
 			passes.push_back(pass->getCore());
 
-		TechniqueCore* technique = new (bs_alloc<TechniqueCore>()) TechniqueCore(mRenderSystem, mRenderer, passes);
+		TechniqueCore* technique = new (bs_alloc<TechniqueCore>()) TechniqueCore(mRenderAPI, mRenderer, passes);
 		SPtr<TechniqueCore> techniquePtr = bs_shared_ptr<TechniqueCore, GenAlloc>(technique);
 		techniquePtr->_setThisPtr(techniquePtr);
 
@@ -95,9 +96,9 @@ namespace BansheeEngine
 			dependencies.push_back(pass);
 	}
 
-	TechniquePtr Technique::create(const String& renderSystem, const String& renderer, const Vector<SPtr<Pass>>& passes)
+	TechniquePtr Technique::create(const StringID& renderAPI, const StringID& renderer, const Vector<SPtr<Pass>>& passes)
 	{
-		Technique* technique = new (bs_alloc<Technique>()) Technique(renderSystem, renderer, passes);
+		Technique* technique = new (bs_alloc<Technique>()) Technique(renderAPI, renderer, passes);
 		TechniquePtr techniquePtr = bs_core_ptr<Technique, GenAlloc>(technique);
 		techniquePtr->_setThisPtr(techniquePtr);
 		techniquePtr->initialize();

+ 1 - 1
BansheeD3D11RenderSystem/Include/BsD3D11RenderAPI.h

@@ -18,7 +18,7 @@ namespace BansheeEngine
 		/**
 		 * @copydoc RenderAPICore::getName
 		 */
-		const String& getName() const;
+		const StringID& getName() const;
 		
 		/**
 		 * @copydoc RenderAPICore::getShadingLanguageName

+ 2 - 2
BansheeD3D11RenderSystem/Source/BsD3D11RenderAPI.cpp

@@ -44,9 +44,9 @@ namespace BansheeEngine
 
 	}
 
-	const String& D3D11RenderAPI::getName() const
+	const StringID& D3D11RenderAPI::getName() const
 	{
-		static String strName("D3D11RenderAPI");
+		static StringID strName("D3D11RenderAPI");
 		return strName;
 	}
 

+ 1 - 1
BansheeD3D9RenderSystem/Include/BsD3D9RenderAPI.h

@@ -23,7 +23,7 @@ namespace BansheeEngine
 		/**
 		 * @copydoc RenderAPICore::getName()
 		 */
-		const String& getName() const;
+		const StringID& getName() const;
 
 		/**
 		 * @copydoc RenderAPICore::getShadingLanguageName()

+ 2 - 2
BansheeD3D9RenderSystem/Source/BsD3D9RenderAPI.cpp

@@ -54,9 +54,9 @@ namespace BansheeEngine
 
 	}
 
-	const String& D3D9RenderAPI::getName() const
+	const StringID& D3D9RenderAPI::getName() const
 	{
-		static String strName( "D3D9RenderAPI");
+		static StringID strName("D3D9RenderAPI");
 		return strName;
 	}
 

+ 1 - 1
BansheeEditor/Include/BsBuiltinEditorResources.h

@@ -167,7 +167,7 @@ namespace BansheeEngine
 
 		RenderSystemPlugin mRenderSystemPlugin;
 		WString mActiveShaderSubFolder;
-		String mActiveRenderSystem;
+		StringID mActiveRenderSystem;
 
 		HShader mShaderDockOverlay;
 		HShader mShaderSceneGrid;

+ 12 - 12
BansheeEditor/Source/BsBuiltinEditorResources.cpp

@@ -1410,7 +1410,7 @@ namespace BansheeEngine
 		passDesc.depthStencilState = depthState;
 
 		PassPtr newPass = Pass::create(passDesc);
-		TechniquePtr newTechnique = Technique::create(mActiveRenderSystem, RendererInvariant, { newPass });
+		TechniquePtr newTechnique = Technique::create(mActiveRenderSystem, RendererAny, { newPass });
 
 		SHADER_DESC shaderDesc;
 		shaderDesc.addParameter("invViewportWidth", "invViewportWidth", GPDT_FLOAT1);
@@ -1455,7 +1455,7 @@ namespace BansheeEngine
 		passDesc.depthStencilState = depthStencilState;
 
 		PassPtr newPass = Pass::create(passDesc);
-		TechniquePtr newTechnique = Technique::create(mActiveRenderSystem, RendererInvariant, { newPass });
+		TechniquePtr newTechnique = Technique::create(mActiveRenderSystem, RendererAny, { newPass });
 
 		SHADER_DESC shaderDesc;
 		shaderDesc.addParameter("matViewProj", "matViewProj", GPDT_MATRIX_4X4);
@@ -1490,7 +1490,7 @@ namespace BansheeEngine
 
 		PassPtr newPass = Pass::create(passDesc);
 
-		TechniquePtr newTechnique = Technique::create(mActiveRenderSystem, RendererInvariant, { newPass });
+		TechniquePtr newTechnique = Technique::create(mActiveRenderSystem, RendererAny, { newPass });
 
 		SHADER_DESC shaderDesc;
 		shaderDesc.addParameter("colorIndex", "colorIndex", GPDT_FLOAT4);
@@ -1518,7 +1518,7 @@ namespace BansheeEngine
 		passDesc.rasterizerState = rasterizerState;
 
 		PassPtr newPass = Pass::create(passDesc);
-		TechniquePtr newTechnique = Technique::create(mActiveRenderSystem, RendererInvariant, { newPass });
+		TechniquePtr newTechnique = Technique::create(mActiveRenderSystem, RendererAny, { newPass });
 
 		SHADER_DESC shaderDesc;
 		shaderDesc.addParameter("mainTexSamp", "mainTexSamp", GPOT_SAMPLER2D);
@@ -1543,7 +1543,7 @@ namespace BansheeEngine
 		passDesc.fragmentProgram = psProgram;
 
 		PassPtr newPass = Pass::create(passDesc);
-		TechniquePtr newTechnique = Technique::create(mActiveRenderSystem, RendererInvariant, { newPass });
+		TechniquePtr newTechnique = Technique::create(mActiveRenderSystem, RendererAny, { newPass });
 
 		SHADER_DESC shaderDesc;
 		shaderDesc.addParameter("matViewProj", "matViewProj", GPDT_MATRIX_4X4);
@@ -1561,7 +1561,7 @@ namespace BansheeEngine
 		passDesc.fragmentProgram = psProgram;
 
 		PassPtr newPass = Pass::create(passDesc);
-		TechniquePtr newTechnique = Technique::create(mActiveRenderSystem, RendererInvariant, { newPass });
+		TechniquePtr newTechnique = Technique::create(mActiveRenderSystem, RendererAny, { newPass });
 
 		SHADER_DESC shaderDesc;
 		shaderDesc.addParameter("matViewProj", "matViewProj", GPDT_MATRIX_4X4);
@@ -1595,7 +1595,7 @@ namespace BansheeEngine
 		passDesc.blendState = blendState;
 
 		PassPtr newPass = Pass::create(passDesc);
-		TechniquePtr newTechnique = Technique::create(mActiveRenderSystem, RendererInvariant, { newPass });
+		TechniquePtr newTechnique = Technique::create(mActiveRenderSystem, RendererAny, { newPass });
 
 		SHADER_DESC shaderDesc;
 		shaderDesc.addParameter("matViewProj", "matViewProj", GPDT_MATRIX_4X4);
@@ -1629,7 +1629,7 @@ namespace BansheeEngine
 		passDesc.blendState = blendState;
 
 		PassPtr newPass = Pass::create(passDesc);
-		TechniquePtr newTechnique = Technique::create(mActiveRenderSystem, RendererInvariant, { newPass });
+		TechniquePtr newTechnique = Technique::create(mActiveRenderSystem, RendererAny, { newPass });
 
 		SHADER_DESC shaderDesc;
 		shaderDesc.addParameter("matViewProj", "matViewProj", GPDT_MATRIX_4X4);
@@ -1680,7 +1680,7 @@ namespace BansheeEngine
 
 		PassPtr newPass1 = Pass::create(pass1Desc);
 
-		TechniquePtr newTechnique = Technique::create(mActiveRenderSystem, RendererInvariant, { newPass0, newPass1 });
+		TechniquePtr newTechnique = Technique::create(mActiveRenderSystem, RendererAny, { newPass0, newPass1 });
 
 		SHADER_DESC shaderDesc;
 		shaderDesc.addParameter("matViewProj", "matViewProj", GPDT_MATRIX_4X4);
@@ -1707,7 +1707,7 @@ namespace BansheeEngine
 		passDesc.rasterizerState = rasterizerState;
 
 		PassPtr newPass = Pass::create(passDesc);
-		TechniquePtr newTechnique = Technique::create(mActiveRenderSystem, RendererInvariant, { newPass });
+		TechniquePtr newTechnique = Technique::create(mActiveRenderSystem, RendererAny, { newPass });
 
 		SHADER_DESC shaderDesc;
 		shaderDesc.addParameter("matViewProj", "matViewProj", GPDT_MATRIX_4X4);
@@ -1731,7 +1731,7 @@ namespace BansheeEngine
 		passDesc.rasterizerState = rasterizerState;
 
 		PassPtr newPass = Pass::create(passDesc);
-		TechniquePtr newTechnique = Technique::create(mActiveRenderSystem, RendererInvariant, { newPass });
+		TechniquePtr newTechnique = Technique::create(mActiveRenderSystem, RendererAny, { newPass });
 
 		SHADER_DESC shaderDesc;
 		shaderDesc.addParameter("mainTexSamp", "mainTexSamp", GPOT_SAMPLER2D);
@@ -1771,7 +1771,7 @@ namespace BansheeEngine
 		passDesc.blendState = blendState;
 
 		PassPtr newPass = Pass::create(passDesc);
-		TechniquePtr newTechnique = Technique::create(mActiveRenderSystem, RendererInvariant, { newPass });
+		TechniquePtr newTechnique = Technique::create(mActiveRenderSystem, RendererAny, { newPass });
 
 		SHADER_DESC shaderDesc;
 		shaderDesc.addParameter("matWorldViewProj", "matWorldViewProj", GPDT_MATRIX_4X4);

+ 1 - 1
BansheeEditor/Source/BsScenePicking.cpp

@@ -135,7 +135,7 @@ namespace BansheeEngine
 							const Map<String, SHADER_OBJECT_PARAM_DESC>& objectParams = originalMat->getShader()->getObjectParams();
 							for (auto& objectParam : objectParams)
 							{
-								if (objectParam.second.rendererSemantic == RPS_MainTex)
+								if (objectParam.second.rendererSemantic == RPS_Diffuse)
 								{
 									mainTexture = originalMat->getTexture(objectParam.first);
 									break;

+ 1 - 1
BansheeEngine/Include/BsBuiltinResources.h

@@ -180,7 +180,7 @@ namespace BansheeEngine
 		HShader mShaderDummy;
 
 		WString mActiveShaderSubFolder;
-		String mActiveRenderSystem;
+		StringID mActiveRenderSystem;
 
 		static const Path DefaultSkinFolderRaw;
 		static const Path DefaultCursorFolderRaw;

+ 4 - 5
BansheeEngine/Include/BsPrerequisites.h

@@ -23,11 +23,10 @@
 
 namespace BansheeEngine
 {
-	static const String RenderAPIDX9 = "D3D9RenderAPI";
-	static const String RenderAPIDX11 = "D3D11RenderAPI";
-	static const String RenderAPIOpenGL = "GLRenderAPI";
-	static const String RendererDefault = "BansheeRenderer";
-	static const String RendererInvariant = "CoreRenderer";
+	static const StringID RenderAPIDX9 = "D3D9RenderAPI";
+	static const StringID RenderAPIDX11 = "D3D11RenderAPI";
+	static const StringID RenderAPIOpenGL = "GLRenderAPI";
+	static const StringID RendererDefault = "BansheeRenderer";
 
 	class VirtualButton;
 	class VirtualInput;

+ 4 - 4
BansheeEngine/Source/BsBuiltinResources.cpp

@@ -859,7 +859,7 @@ namespace BansheeEngine
 		passDesc.depthStencilState = depthState;
 
 		PassPtr newPass = Pass::create(passDesc);
-		TechniquePtr newTechnique = Technique::create(mActiveRenderSystem, RendererInvariant, { newPass });
+		TechniquePtr newTechnique = Technique::create(mActiveRenderSystem, RendererAny, { newPass });
 
 		SHADER_DESC shaderDesc;
 		shaderDesc.addParameter("worldTransform", "worldTransform", GPDT_MATRIX_4X4);
@@ -902,7 +902,7 @@ namespace BansheeEngine
 		passDesc.depthStencilState = depthState;
 
 		PassPtr newPass = Pass::create(passDesc);
-		TechniquePtr newTechnique = Technique::create(mActiveRenderSystem, RendererInvariant, { newPass });
+		TechniquePtr newTechnique = Technique::create(mActiveRenderSystem, RendererAny, { newPass });
 
 		SHADER_DESC shaderDesc;
 		shaderDesc.addParameter("worldTransform", "worldTransform", GPDT_MATRIX_4X4);
@@ -935,7 +935,7 @@ namespace BansheeEngine
 		passDesc.depthStencilState = depthState;
 
 		PassPtr newPass = Pass::create(passDesc);
-		TechniquePtr newTechnique = Technique::create(mActiveRenderSystem, RendererInvariant, { newPass });
+		TechniquePtr newTechnique = Technique::create(mActiveRenderSystem, RendererAny, { newPass });
 
 		SHADER_DESC shaderDesc;
 		shaderDesc.addParameter("worldTransform", "worldTransform", GPDT_MATRIX_4X4);
@@ -961,7 +961,7 @@ namespace BansheeEngine
 		passDesc.fragmentProgram = psProgram;
 
 		PassPtr newPass = Pass::create(passDesc);
-		TechniquePtr newTechnique = Technique::create(mActiveRenderSystem, RendererInvariant, { newPass });
+		TechniquePtr newTechnique = Technique::create(mActiveRenderSystem, RendererAny, { newPass });
 
 		SHADER_DESC shaderDesc;
 		shaderDesc.addParameter("matWorldViewProj", "matWorldViewProj", GPDT_MATRIX_4X4);

+ 1 - 1
BansheeGLRenderSystem/Include/BsGLRenderAPI.h

@@ -21,7 +21,7 @@ namespace BansheeEngine
 		/**
 		 * @copydoc RenderAPICore::getName()
 		 */
-        const String& getName() const;
+		const StringID& getName() const;
 
 		/**
 		 * @copydoc RenderAPICore::getShadingLanguageName()

+ 2 - 2
BansheeGLRenderSystem/Source/BsGLRenderAPI.cpp

@@ -86,9 +86,9 @@ namespace BansheeEngine
 
 	}
 
-	const String& GLRenderAPI::getName() const
+	const StringID& GLRenderAPI::getName() const
 	{
-		static String strName("GLRenderAPI");
+		static StringID strName("GLRenderAPI");
 		return strName;
 	}
 

+ 6 - 8
BansheeRenderer/Include/BsBansheeRenderer.h

@@ -8,14 +8,12 @@
 namespace BansheeEngine
 {
 	/**
-	 * @brief	Semantics that may be used for signaling the renderer
-	 *			for what is a certain shader parameter used for.
+	 * Semantics that may be used for signaling the renderer
+	 * for what is a certain shader parameter used for.
 	 */
-	enum BansheeRendererParamSemantic
-	{
-		RPS_Time = 1000,
-		RPS_LightDir = 1001
-	};
+
+	static StringID RPS_Time = "Time";
+	static StringID RPS_LightDir = "LightDir";
 
 	/**
 	 * @brief	Default renderer for Banshee. Performs frustum culling, sorting and 
@@ -59,7 +57,7 @@ namespace BansheeEngine
 		/**
 		 * @copydoc	Renderer::getName
 		 */
-		virtual const String& getName() const;
+		virtual const StringID& getName() const;
 
 		/**
 		 * @copydoc	Renderer::renderAll

+ 4 - 10
BansheeRenderer/Source/BsBansheeLitTexRenderableController.cpp

@@ -149,18 +149,12 @@ namespace BansheeEngine
 
 		for (auto& paramBlockDesc : paramBlockDescs)
 		{
-			switch (paramBlockDesc.second.rendererSemantic)
-			{
-			case RBS_Static:
+			if (paramBlockDesc.second.rendererSemantic == RBS_Static)
 				staticBlockName = paramBlockDesc.second.name;
-				break;
-			case RBS_PerFrame:
+			else if(paramBlockDesc.second.rendererSemantic == RBS_PerFrame)
 				perFrameBlockName = paramBlockDesc.second.name;
-				break;
-			case RBS_PerObject:
+			else if (paramBlockDesc.second.rendererSemantic == RBS_PerObject)
 				perObjectBlockName = paramBlockDesc.second.name;
-				break;
-			}
 		}
 
 		for (auto& paramDesc : dataParamDescs)
@@ -275,7 +269,7 @@ namespace BansheeEngine
 
 	SPtr<ShaderCore> LitTexRenderableController::createDefaultShader()
 	{
-		String rsName = RenderAPICore::instance().getName();
+		StringID rsName = RenderAPICore::instance().getName();
 
 		SPtr<GpuProgramCore> vsProgram;
 		SPtr<GpuProgramCore> psProgram;

+ 3 - 3
BansheeRenderer/Source/BsBansheeRenderer.cpp

@@ -34,9 +34,9 @@ using namespace std::placeholders;
 
 namespace BansheeEngine
 {
-	const String& BansheeRenderer::getName() const
+	const StringID& BansheeRenderer::getName() const
 	{
-		static String name = "BansheeRenderer";
+		static StringID name = "BansheeRenderer";
 		return name;
 	}
 
@@ -378,7 +378,7 @@ namespace BansheeEngine
 
 	SPtr<ShaderCore> BansheeRenderer::createDefaultShader()
 	{
-		String rsName = RenderAPICore::instance().getName();
+		StringID rsName = RenderAPICore::instance().getName();
 
 		SPtr<GpuProgramCore> vsProgram;
 		SPtr<GpuProgramCore> psProgram;

File diff suppressed because it is too large
+ 449 - 530
BansheeSL/BsLexerFX.c


+ 1 - 117
BansheeSL/BsLexerFX.h

@@ -10,8 +10,6 @@
 
 /* A lexical scanner generated by flex */
 
-/* %not-for-header */
-
 #define FLEX_SCANNER
 #define YY_FLEX_MAJOR_VERSION 2
 #define YY_FLEX_MINOR_VERSION 5
@@ -20,32 +18,16 @@
 #define FLEX_BETA
 #endif
 
-/* %if-c++-only */
-/* %endif */
-
-/* %if-c-only */
-    
-/* %endif */
-
-/* %if-c-only */
-
-/* %endif */
-
 /* First, we deal with  platform-specific or compiler-specific issues. */
 
 /* begin standard C headers. */
-/* %if-c-only */
 #include <stdio.h>
 #include <string.h>
 #include <errno.h>
 #include <stdlib.h>
-/* %endif */
 
-/* %if-tables-serialization */
-/* %endif */
 /* end standard C headers. */
 
-/* %if-c-or-c++ */
 /* flex integer type definitions */
 
 #ifndef FLEXINT_H
@@ -110,11 +92,6 @@ typedef unsigned int flex_uint32_t;
 
 #endif /* ! FLEXINT_H */
 
-/* %endif */
-
-/* %if-c++-only */
-/* %endif */
-
 #ifdef __cplusplus
 
 /* The "const" storage-class-modifier is valid. */
@@ -136,12 +113,6 @@ typedef unsigned int flex_uint32_t;
 #define yyconst
 #endif
 
-/* %not-for-header */
-
-/* %not-for-header */
-
-/* %if-reentrant */
-
 /* An opaque pointer. */
 #ifndef YY_TYPEDEF_YY_SCANNER_T
 #define YY_TYPEDEF_YY_SCANNER_T
@@ -159,11 +130,6 @@ typedef void* yyscan_t;
 #define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
 #define yy_flex_debug yyg->yy_flex_debug_r
 
-/* %endif */
-
-/* %if-not-reentrant */
-/* %endif */
-
 /* Size of default input buffer. */
 #ifndef YY_BUF_SIZE
 #define YY_BUF_SIZE 16384
@@ -179,24 +145,11 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE;
 typedef size_t yy_size_t;
 #endif
 
-/* %if-not-reentrant */
-/* %endif */
-
-/* %if-c-only */
-/* %if-not-reentrant */
-/* %endif */
-/* %endif */
-
 #ifndef YY_STRUCT_YY_BUFFER_STATE
 #define YY_STRUCT_YY_BUFFER_STATE
 struct yy_buffer_state
 	{
-/* %if-c-only */
 	FILE *yy_input_file;
-/* %endif */
-
-/* %if-c++-only */
-/* %endif */
 
 	char *yy_ch_buf;		/* input buffer */
 	char *yy_buf_pos;		/* current position in input buffer */
@@ -243,18 +196,6 @@ struct yy_buffer_state
 	};
 #endif /* !YY_STRUCT_YY_BUFFER_STATE */
 
-/* %if-c-only Standard (non-C++) definition */
-/* %not-for-header */
-
-/* %endif */
-
-/* %if-c-only Standard (non-C++) definition */
-
-/* %if-not-reentrant */
-/* %not-for-header */
-
-/* %endif */
-
 void yyrestart (FILE *input_file ,yyscan_t yyscanner );
 void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
 YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
@@ -267,25 +208,15 @@ YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
 YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
 YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner );
 
-/* %endif */
-
 void *yyalloc (yy_size_t ,yyscan_t yyscanner );
 void *yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
 void yyfree (void * ,yyscan_t yyscanner );
 
-/* %% [1.0] yytext/yyin/yyout/yy_state_type/yylineno etc. def's & init go here */
-
 #define yywrap(yyscanner) 1
 #define YY_SKIP_YYWRAP
 
-#define FLEX_DEBUG
-
 #define yytext_ptr yytext_r
 
-/* %if-c-only Standard (non-C++) definition */
-
-/* %endif */
-
 #ifdef YY_HEADER_EXPORT_START_CONDITIONS
 #define INITIAL 0
 
@@ -298,23 +229,10 @@ void yyfree (void * ,yyscan_t yyscanner );
     
 #define YY_EXTRA_TYPE struct tagParseState *
 
-/* %if-c-only Reentrant structure and macros (non-C++). */
-/* %if-reentrant */
-
-/* %if-c-only */
-
-/* %endif */
-
-/* %if-reentrant */
-
 int yylex_init (yyscan_t* scanner);
 
 int yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
 
-/* %endif */
-
-/* %endif End reentrant structures and macros. */
-
 /* Accessor methods to globals.
    These are made visible to non-reentrant scanners for convenience. */
 
@@ -348,8 +266,6 @@ int yyget_column  (yyscan_t yyscanner );
 
 void yyset_column (int column_no ,yyscan_t yyscanner );
 
-/* %if-bison-bridge */
-
 YYSTYPE * yyget_lval (yyscan_t yyscanner );
 
 void yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
@@ -358,8 +274,6 @@ void yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
     
         void yyset_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner );
     
-/* %endif */
-
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
  */
@@ -372,10 +286,6 @@ extern int yywrap (yyscan_t yyscanner );
 #endif
 #endif
 
-/* %not-for-header */
-
-/* %endif */
-
 #ifndef yytext_ptr
 static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
 #endif
@@ -385,16 +295,9 @@ static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
 #endif
 
 #ifndef YY_NO_INPUT
-/* %if-c-only Standard (non-C++) definition */
-/* %not-for-header */
 
-/* %endif */
 #endif
 
-/* %if-c-only */
-
-/* %endif */
-
 /* Amount of stuff to slurp up with each read. */
 #ifndef YY_READ_BUF_SIZE
 #define YY_READ_BUF_SIZE 8192
@@ -405,40 +308,21 @@ static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
 #define YY_START_STACK_INCR 25
 #endif
 
-/* %if-tables-serialization structures and prototypes */
-/* %not-for-header */
-
-/* %not-for-header */
-
 /* Default declaration of generated scanner - a define so the user can
  * easily add parameters.
  */
 #ifndef YY_DECL
 #define YY_DECL_IS_OURS 1
-/* %if-c-only Standard (non-C++) definition */
 
 extern int yylex \
                (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner);
 
 #define YY_DECL int yylex \
                (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner)
-/* %endif */
-/* %if-c++-only C++ definition */
-/* %endif */
 #endif /* !YY_DECL */
 
-/* %not-for-header */
-
-/* %if-c++-only */
-/* %not-for-header */
-
-/* %endif */
-
 /* yy_get_previous_state - get the state just before the EOB char was reached */
 
-/* %if-c-only */
-/* %not-for-header */
-
 #undef YY_NEW_FILE
 #undef YY_FLUSH_BUFFER
 #undef yy_set_bol
@@ -453,6 +337,6 @@ extern int yylex \
 
 #line 226 "BsLexerFX.l"
 
-#line 457 "BsLexerFX.h"
+#line 341 "BsLexerFX.h"
 #undef yyIN_HEADER
 #endif /* yyHEADER_H */

+ 73 - 73
BansheeSL/BsLexerFX.l

@@ -8,7 +8,6 @@
 %option yylineno reentrant noyywrap nounistd never-interactive warn nodefault bison-bridge bison-locations
 %option outfile="BsLexerFX.c" header-file="BsLexerFX.h"
 %option extra-type="struct tagParseState *"
-%option debug
 
 INTEGER			[0-9][0-9]*
 INTEGER_16		0[xX][0-9a-fA-F]+
@@ -47,28 +46,28 @@ mat4x2			{ yylval->intValue = PT_Mat4x2; return TOKEN_MAT4x2TYPE; }
 mat4x3			{ yylval->intValue = PT_Mat4x3; return TOKEN_MAT4x3TYPE; } 
 mat4x4			{ yylval->intValue = PT_Mat4x4; return TOKEN_MAT4x4TYPE; }
 
-sampler1D		{ yylval->intValue = PT_Sampler1D; return TOKEN_SAMPLER1D; } 
-sampler2D		{ yylval->intValue = PT_Sampler2D; return TOKEN_SAMPLER2D; } 
-sampler3D		{ yylval->intValue = PT_Sampler3D; return TOKEN_SAMPLER3D; } 
-samplerCUBE		{ yylval->intValue = PT_SamplerCUBE; return TOKEN_SAMPLERCUBE; } 
-sampler2DMS		{ yylval->intValue = PT_Sampler2DMS; return TOKEN_SAMPLER2DMS; }
+Sampler1D		{ yylval->intValue = PT_Sampler1D; return TOKEN_SAMPLER1D; } 
+Sampler2D		{ yylval->intValue = PT_Sampler2D; return TOKEN_SAMPLER2D; } 
+Sampler3D		{ yylval->intValue = PT_Sampler3D; return TOKEN_SAMPLER3D; } 
+SamplerCUBE		{ yylval->intValue = PT_SamplerCUBE; return TOKEN_SAMPLERCUBE; } 
+Sampler2DMS		{ yylval->intValue = PT_Sampler2DMS; return TOKEN_SAMPLER2DMS; }
 
-texture1D		{ yylval->intValue = PT_Texture1D; return TOKEN_TEXTURE1D; } 
-texture2D		{ yylval->intValue = PT_Texture2D; return TOKEN_TEXTURE2D; } 
-texture3D		{ yylval->intValue = PT_Texture3D; return TOKEN_TEXTURE3D; } 
-textureCUBE		{ yylval->intValue = PT_TextureCUBE; return TOKEN_TEXTURECUBE; } 
-texture2DMS		{ yylval->intValue = PT_Texture2DMS; return TOKEN_TEXTURE2DMS; }
+Texture1D		{ yylval->intValue = PT_Texture1D; return TOKEN_TEXTURE1D; } 
+Texture2D		{ yylval->intValue = PT_Texture2D; return TOKEN_TEXTURE2D; } 
+Texture3D		{ yylval->intValue = PT_Texture3D; return TOKEN_TEXTURE3D; } 
+TextureCUBE		{ yylval->intValue = PT_TextureCUBE; return TOKEN_TEXTURECUBE; } 
+Texture2DMS		{ yylval->intValue = PT_Texture2DMS; return TOKEN_TEXTURE2DMS; }
 
-bytebuffer		{ yylval->intValue = PT_ByteBuffer; return TOKEN_BYTEBUFFER; } 
-structbuffer	{ yylval->intValue = PT_StructBuffer; return TOKEN_STRUCTBUFFER; } 
+ByteBuffer		{ yylval->intValue = PT_ByteBuffer; return TOKEN_BYTEBUFFER; } 
+StructBuffer	{ yylval->intValue = PT_StructBuffer; return TOKEN_STRUCTBUFFER; } 
 
-typedbufferRW	{ yylval->intValue = PT_TypedBufferRW; return TOKEN_RWTYPEDBUFFER; } 
-bytebufferRW	{ yylval->intValue = PT_ByteBufferRW; return TOKEN_RWBYTEBUFFER; }
-structbufferRW	{ yylval->intValue = PT_StructBufferRW; return TOKEN_RWSTRUCTBUFFER; } 
-appendbuffer	{ yylval->intValue = PT_AppendBuffer; return TOKEN_RWAPPENDBUFFER; } 
-consumebuffer	{ yylval->intValue = PT_ConsumeBuffer; return TOKEN_RWCONSUMEBUFFER; }
+TypedBufferRW	{ yylval->intValue = PT_TypedBufferRW; return TOKEN_RWTYPEDBUFFER; } 
+ByteBufferRW	{ yylval->intValue = PT_ByteBufferRW; return TOKEN_RWBYTEBUFFER; }
+StructBufferRW	{ yylval->intValue = PT_StructBufferRW; return TOKEN_RWSTRUCTBUFFER; } 
+AppendBuffer	{ yylval->intValue = PT_AppendBuffer; return TOKEN_RWAPPENDBUFFER; } 
+ConsumeBuffer	{ yylval->intValue = PT_ConsumeBuffer; return TOKEN_RWCONSUMEBUFFER; }
 
-block			{ return TOKEN_PARAMSBLOCK; }
+Block			{ return TOKEN_PARAMSBLOCK; }
 
 	/* Shader keywords */
 Separable		{ return TOKEN_SEPARABLE; }
@@ -91,6 +90,7 @@ Geometry		{ return TOKEN_GEOMETRY; }
 Hull			{ return TOKEN_HULL; }
 Domain			{ return TOKEN_DOMAIN; }
 Compute			{ return TOKEN_COMPUTE; }
+StencilRef		{ return TOKEN_STENCILREF; }
 
 	/* Rasterizer state keywords */
 Fill			{ return TOKEN_FILLMODE; }
@@ -148,45 +148,45 @@ shared				{ return TOKEN_SHARED; }
 usage				{ return TOKEN_USAGE; }
 
 	/* State values */
-wire			{ yylval->intValue = 0; return TOKEN_FILLMODEVALUE; }
-solid			{ yylval->intValue = 1; return TOKEN_FILLMODEVALUE; }
-
-nocull			{ yylval->intValue = 0; return TOKEN_CULLMODEVALUE; }
-cw				{ yylval->intValue = 1; return TOKEN_CULLMODEVALUE; }
-ccw				{ yylval->intValue = 2; return TOKEN_CULLMODEVALUE; }
-
-fail			{ yylval->intValue = 0; return TOKEN_COMPFUNCVALUE; }
-pass			{ yylval->intValue = 1; return TOKEN_COMPFUNCVALUE; }
-lt				{ yylval->intValue = 2; return TOKEN_COMPFUNCVALUE; }
-lte				{ yylval->intValue = 3; return TOKEN_COMPFUNCVALUE; }
-eq				{ yylval->intValue = 4; return TOKEN_COMPFUNCVALUE; }
-neq				{ yylval->intValue = 5; return TOKEN_COMPFUNCVALUE; }
-gte				{ yylval->intValue = 6; return TOKEN_COMPFUNCVALUE; }
-gt				{ yylval->intValue = 7; return TOKEN_COMPFUNCVALUE; }
-
-keep			{ yylval->intValue = 0; return TOKEN_OPVALUE; }
-zero			{ yylval->intValue = 1; return TOKEN_OPVALUE; }
-replace			{ yylval->intValue = 2; return TOKEN_OPVALUE; }
-incr			{ yylval->intValue = 3; return TOKEN_OPVALUE; }
-decr			{ yylval->intValue = 4; return TOKEN_OPVALUE; }
-incrwrap		{ yylval->intValue = 5; return TOKEN_OPVALUE; }
-decrwrap		{ yylval->intValue = 6; return TOKEN_OPVALUE; }
-invert			{ yylval->intValue = 7; return TOKEN_OPVALUE; }
-one				{ yylval->intValue = 8; return TOKEN_OPVALUE; }
-destcolor		{ yylval->intValue = 9; return TOKEN_OPVALUE; }
-srccolor		{ yylval->intValue = 10; return TOKEN_OPVALUE; }
-invdestcolor	{ yylval->intValue = 11; return TOKEN_OPVALUE; }
-invsrccolor		{ yylval->intValue = 12; return TOKEN_OPVALUE; }
-destalpha		{ yylval->intValue = 13; return TOKEN_OPVALUE; }
-srcalpha		{ yylval->intValue = 14; return TOKEN_OPVALUE; }
-invdestalpha	{ yylval->intValue = 15; return TOKEN_OPVALUE; }
-invsrcalpha		{ yylval->intValue = 16; return TOKEN_OPVALUE; }
-
-add				{ yylval->intValue = 0; return TOKEN_BLENDOPVALUE; }
-subtract		{ yylval->intValue = 1; return TOKEN_BLENDOPVALUE; }
-revsubtract		{ yylval->intValue = 2; return TOKEN_BLENDOPVALUE; }
-min				{ yylval->intValue = 3; return TOKEN_BLENDOPVALUE; }
-max				{ yylval->intValue = 4; return TOKEN_BLENDOPVALUE; }
+wire			{ yylval->intValue = FMV_Wire; return TOKEN_FILLMODEVALUE; }
+solid			{ yylval->intValue = FMV_Solid; return TOKEN_FILLMODEVALUE; }
+
+nocull			{ yylval->intValue = CMV_None; return TOKEN_CULLMODEVALUE; }
+cw				{ yylval->intValue = CMV_CW; return TOKEN_CULLMODEVALUE; }
+ccw				{ yylval->intValue = CMV_CCW; return TOKEN_CULLMODEVALUE; }
+
+fail			{ yylval->intValue = CFV_Fail; return TOKEN_COMPFUNCVALUE; }
+pass			{ yylval->intValue = CFV_Pass; return TOKEN_COMPFUNCVALUE; }
+lt				{ yylval->intValue = CFV_LT; return TOKEN_COMPFUNCVALUE; }
+lte				{ yylval->intValue = CFV_LTE; return TOKEN_COMPFUNCVALUE; }
+eq				{ yylval->intValue = CFV_EQ; return TOKEN_COMPFUNCVALUE; }
+neq				{ yylval->intValue = CFV_NEQ; return TOKEN_COMPFUNCVALUE; }
+gte				{ yylval->intValue = CFV_GTE; return TOKEN_COMPFUNCVALUE; }
+gt				{ yylval->intValue = CFV_GT; return TOKEN_COMPFUNCVALUE; }
+
+keep					{ yylval->intValue = OV_Keep; return TOKEN_OPVALUE; }
+zero					{ yylval->intValue = OV_Zero; return TOKEN_OPVALUE; }
+replace					{ yylval->intValue = OV_Replace; return TOKEN_OPVALUE; }
+increment				{ yylval->intValue = OV_Incr; return TOKEN_OPVALUE; }
+decrement				{ yylval->intValue = OV_Decr; return TOKEN_OPVALUE; }
+increment_wrap			{ yylval->intValue = OV_IncrWrap; return TOKEN_OPVALUE; }
+decrement_wrap			{ yylval->intValue = OV_DecrWrap; return TOKEN_OPVALUE; }
+invert					{ yylval->intValue = OV_Invert; return TOKEN_OPVALUE; }
+one						{ yylval->intValue = OV_One; return TOKEN_OPVALUE; }
+destinationRGB			{ yylval->intValue = OV_DestColor; return TOKEN_OPVALUE; }
+sourceRGB				{ yylval->intValue = OV_SrcColor; return TOKEN_OPVALUE; }
+destinationRGB_inverse	{ yylval->intValue = OV_InvDestColor; return TOKEN_OPVALUE; }
+sourceRGB_inverse		{ yylval->intValue = OV_InvSrcColor; return TOKEN_OPVALUE; }
+destinationA			{ yylval->intValue = OV_DestAlpha; return TOKEN_OPVALUE; }
+sourceA					{ yylval->intValue = OV_SrcAlpha; return TOKEN_OPVALUE; }
+destinationA_inverse	{ yylval->intValue = OV_InvDestAlpha; return TOKEN_OPVALUE; }
+sourceA_inverse			{ yylval->intValue = OV_InvSrcAlpha; return TOKEN_OPVALUE; }
+
+add					{ yylval->intValue = BOV_Add; return TOKEN_BLENDOPVALUE; }
+subtract			{ yylval->intValue = BOV_Subtract; return TOKEN_BLENDOPVALUE; }
+subtract_reverse	{ yylval->intValue = BOV_RevSubtract; return TOKEN_BLENDOPVALUE; }
+min					{ yylval->intValue = BOV_Min; return TOKEN_BLENDOPVALUE; }
+max					{ yylval->intValue = BOV_Max; return TOKEN_BLENDOPVALUE; }
 
 nocolor			{ yylval->intValue = 0x0; return TOKEN_COLORMASK; }
 R				{ yylval->intValue = 0x1; return TOKEN_COLORMASK; }
@@ -205,21 +205,21 @@ RBA				{ yylval->intValue = 0xD; return TOKEN_COLORMASK; }
 GBA				{ yylval->intValue = 0xE; return TOKEN_COLORMASK; }
 RGBA			{ yylval->intValue = 0xF; return TOKEN_COLORMASK; }
 
-wrap			{ yylval->intValue = 0; return TOKEN_ADDRMODEVALUE; }
-mirror			{ yylval->intValue = 1; return TOKEN_ADDRMODEVALUE; }
-clamp			{ yylval->intValue = 2; return TOKEN_ADDRMODEVALUE; }
-border			{ yylval->intValue = 3; return TOKEN_ADDRMODEVALUE; }
-
-nofilter		{ yylval->intValue = 0; return TOKEN_FILTERVALUE; }
-point			{ yylval->intValue = 1; return TOKEN_FILTERVALUE; }
-linear			{ yylval->intValue = 2; return TOKEN_FILTERVALUE; }
-anisotropic		{ yylval->intValue = 3; return TOKEN_FILTERVALUE; }
-pointcmp		{ yylval->intValue = 4; return TOKEN_FILTERVALUE; }
-linearcmp		{ yylval->intValue = 5; return TOKEN_FILTERVALUE; }
-anisotropiccmp	{ yylval->intValue = 6; return TOKEN_FILTERVALUE; }
-
-static			{ yylval->intValue = 0; return TOKEN_BUFFERUSAGE; }
-dynamic			{ yylval->intValue = 1; return TOKEN_BUFFERUSAGE; }
+wrap			{ yylval->intValue = AMV_Wrap; return TOKEN_ADDRMODEVALUE; }
+mirror			{ yylval->intValue = AMV_Mirror; return TOKEN_ADDRMODEVALUE; }
+clamp			{ yylval->intValue = AMV_Clamp; return TOKEN_ADDRMODEVALUE; }
+border			{ yylval->intValue = AMV_Border; return TOKEN_ADDRMODEVALUE; }
+
+nofilter		{ yylval->intValue = FV_None; return TOKEN_FILTERVALUE; }
+point			{ yylval->intValue = FV_Point; return TOKEN_FILTERVALUE; }
+linear			{ yylval->intValue = FV_Linear; return TOKEN_FILTERVALUE; }
+anisotropic		{ yylval->intValue = FV_Anisotropic; return TOKEN_FILTERVALUE; }
+point_cmp		{ yylval->intValue = FV_PointCmp; return TOKEN_FILTERVALUE; }
+linear_cmp		{ yylval->intValue = FV_LinearCmp; return TOKEN_FILTERVALUE; }
+anisotropic_cmp	{ yylval->intValue = FV_AnisotropicCmp; return TOKEN_FILTERVALUE; }
+
+static			{ yylval->intValue = BUV_Static; return TOKEN_BUFFERUSAGE; }
+dynamic			{ yylval->intValue = BUV_Dynamic; return TOKEN_BUFFERUSAGE; }
 
 {COMMENT}		{ }
 {IDENTIFIER}	{ yylval->strValue = mmalloc_strdup(yyextra->memContext, yytext); return TOKEN_IDENTIFIER; }

File diff suppressed because it is too large
+ 462 - 437
BansheeSL/BsParserFX.c


+ 45 - 44
BansheeSL/BsParserFX.h

@@ -34,7 +34,7 @@
 # define YY_YY_BSPARSERFX_H_INCLUDED
 /* Enabling traces.  */
 #ifndef YYDEBUG
-# define YYDEBUG 1
+# define YYDEBUG 0
 #endif
 #if YYDEBUG
 extern int yydebug;
@@ -142,47 +142,48 @@ extern int yydebug;
      TOKEN_HULL = 320,
      TOKEN_DOMAIN = 321,
      TOKEN_COMPUTE = 322,
-     TOKEN_FILLMODE = 323,
-     TOKEN_CULLMODE = 324,
-     TOKEN_DEPTHBIAS = 325,
-     TOKEN_SDEPTHBIAS = 326,
-     TOKEN_DEPTHCLIP = 327,
-     TOKEN_SCISSOR = 328,
-     TOKEN_MULTISAMPLE = 329,
-     TOKEN_AALINE = 330,
-     TOKEN_DEPTHREAD = 331,
-     TOKEN_DEPTHWRITE = 332,
-     TOKEN_COMPAREFUNC = 333,
-     TOKEN_STENCIL = 334,
-     TOKEN_STENCILREADMASK = 335,
-     TOKEN_STENCILWRITEMASK = 336,
-     TOKEN_STENCILOPFRONT = 337,
-     TOKEN_STENCILOPBACK = 338,
-     TOKEN_FAIL = 339,
-     TOKEN_ZFAIL = 340,
-     TOKEN_ALPHATOCOVERAGE = 341,
-     TOKEN_INDEPENDANTBLEND = 342,
-     TOKEN_TARGET = 343,
-     TOKEN_INDEX = 344,
-     TOKEN_BLEND = 345,
-     TOKEN_COLOR = 346,
-     TOKEN_ALPHA = 347,
-     TOKEN_WRITEMASK = 348,
-     TOKEN_SOURCE = 349,
-     TOKEN_DEST = 350,
-     TOKEN_OP = 351,
-     TOKEN_ADDRMODE = 352,
-     TOKEN_MINFILTER = 353,
-     TOKEN_MAGFILTER = 354,
-     TOKEN_MIPFILTER = 355,
-     TOKEN_MAXANISO = 356,
-     TOKEN_MIPBIAS = 357,
-     TOKEN_MIPMIN = 358,
-     TOKEN_MIPMAX = 359,
-     TOKEN_BORDERCOLOR = 360,
-     TOKEN_U = 361,
-     TOKEN_V = 362,
-     TOKEN_W = 363
+     TOKEN_STENCILREF = 323,
+     TOKEN_FILLMODE = 324,
+     TOKEN_CULLMODE = 325,
+     TOKEN_DEPTHBIAS = 326,
+     TOKEN_SDEPTHBIAS = 327,
+     TOKEN_DEPTHCLIP = 328,
+     TOKEN_SCISSOR = 329,
+     TOKEN_MULTISAMPLE = 330,
+     TOKEN_AALINE = 331,
+     TOKEN_DEPTHREAD = 332,
+     TOKEN_DEPTHWRITE = 333,
+     TOKEN_COMPAREFUNC = 334,
+     TOKEN_STENCIL = 335,
+     TOKEN_STENCILREADMASK = 336,
+     TOKEN_STENCILWRITEMASK = 337,
+     TOKEN_STENCILOPFRONT = 338,
+     TOKEN_STENCILOPBACK = 339,
+     TOKEN_FAIL = 340,
+     TOKEN_ZFAIL = 341,
+     TOKEN_ALPHATOCOVERAGE = 342,
+     TOKEN_INDEPENDANTBLEND = 343,
+     TOKEN_TARGET = 344,
+     TOKEN_INDEX = 345,
+     TOKEN_BLEND = 346,
+     TOKEN_COLOR = 347,
+     TOKEN_ALPHA = 348,
+     TOKEN_WRITEMASK = 349,
+     TOKEN_SOURCE = 350,
+     TOKEN_DEST = 351,
+     TOKEN_OP = 352,
+     TOKEN_ADDRMODE = 353,
+     TOKEN_MINFILTER = 354,
+     TOKEN_MAGFILTER = 355,
+     TOKEN_MIPFILTER = 356,
+     TOKEN_MAXANISO = 357,
+     TOKEN_MIPBIAS = 358,
+     TOKEN_MIPMIN = 359,
+     TOKEN_MIPMAX = 360,
+     TOKEN_BORDERCOLOR = 361,
+     TOKEN_U = 362,
+     TOKEN_V = 363,
+     TOKEN_W = 364
    };
 #endif
 
@@ -190,7 +191,7 @@ extern int yydebug;
 typedef union YYSTYPE
 {
 /* Line 2579 of glr.c  */
-#line 46 "BsParserFX.y"
+#line 45 "BsParserFX.y"
 
 	int intValue;
 	float floatValue;
@@ -201,7 +202,7 @@ typedef union YYSTYPE
 
 
 /* Line 2579 of glr.c  */
-#line 205 "BsParserFX.h"
+#line 206 "BsParserFX.h"
 } YYSTYPE;
 # define YYSTYPE_IS_TRIVIAL 1
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */

+ 60 - 3
BansheeSL/BsParserFX.y

@@ -36,7 +36,6 @@ void yyerror(YYLTYPE *locp, ParseState* parse_state, yyscan_t scanner, const cha
 %defines "BsParserFX.h"
 
 %define api.pure
-%debug
 %locations
 %lex-param { yyscan_t scanner }
 %parse-param { ParseState* parse_state }
@@ -120,6 +119,7 @@ void yyerror(YYLTYPE *locp, ParseState* parse_state, yyscan_t scanner, const cha
 
 	/* Pass keywords */
 %token	TOKEN_VERTEX TOKEN_FRAGMENT TOKEN_GEOMETRY TOKEN_HULL TOKEN_DOMAIN TOKEN_COMPUTE
+%token	TOKEN_STENCILREF
 
 %token	TOKEN_FILLMODE TOKEN_CULLMODE TOKEN_DEPTHBIAS TOKEN_SDEPTHBIAS
 %token	TOKEN_DEPTHCLIP TOKEN_SCISSOR TOKEN_MULTISAMPLE TOKEN_AALINE
@@ -151,6 +151,9 @@ void yyerror(YYLTYPE *locp, ParseState* parse_state, yyscan_t scanner, const cha
 %type <nodeOption>	pass_statement;
 %type <nodeOption>	pass_option;
 
+%type <nodePtr>		code;
+%type <nodePtr>		code_header;
+
 %type <nodePtr>		stencil_op_front_header;
 %type <nodePtr>		stencil_op_back_header;
 %type <nodeOption>	stencil_op_option;
@@ -290,6 +293,7 @@ pass_body
 
 pass_statement
 	: pass_option
+	| code				{ $$.type = OT_Code; $$.value.nodePtr = $1; }
 	;
 
 pass_option
@@ -312,6 +316,56 @@ pass_option
 	| TOKEN_ALPHATOCOVERAGE '=' TOKEN_BOOLEAN ';'			{ $$.type = OT_AlphaToCoverage; $$.value.intValue = $3; }
 	| TOKEN_INDEPENDANTBLEND '=' TOKEN_BOOLEAN ';'			{ $$.type = OT_IndependantBlend; $$.value.intValue = $3; }
 	| target												{ $$.type = OT_Target; $$.value.nodePtr = $1; }
+	| TOKEN_STENCILREF '=' TOKEN_INTEGER ';'				{ $$.type = OT_StencilRef; $$.value.intValue = $3; }
+	;
+
+	/* Code blocks */
+
+code
+	: code_header '{' TOKEN_INDEX '=' TOKEN_INTEGER ';' '}' ';'
+	{
+		NodeOption index;
+		index.type = OT_Index; 
+		index.value.intValue = $5;
+
+		nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &index);
+
+		nodePop(parse_state); 
+		$$ = $1;
+	}
+	;
+
+code_header
+	: TOKEN_VERTEX '='
+		{ 
+			$$ = nodeCreate(parse_state->memContext, NT_Code); 
+			nodePush(parse_state, $$);
+		}
+	| TOKEN_FRAGMENT '='
+		{ 
+			$$ = nodeCreate(parse_state->memContext, NT_Code); 
+			nodePush(parse_state, $$);
+		}
+	| TOKEN_GEOMETRY '='
+		{ 
+			$$ = nodeCreate(parse_state->memContext, NT_Code); 
+			nodePush(parse_state, $$);
+		}
+	| TOKEN_HULL '='
+		{ 
+			$$ = nodeCreate(parse_state->memContext, NT_Code); 
+			nodePush(parse_state, $$);
+		}
+	| TOKEN_DOMAIN '='
+		{ 
+			$$ = nodeCreate(parse_state->memContext, NT_Code); 
+			nodePush(parse_state, $$);
+		}
+	| TOKEN_COMPUTE '='
+		{ 
+			$$ = nodeCreate(parse_state->memContext, NT_Code); 
+			nodePush(parse_state, $$);
+		}
 	;
 
 	/* Stencil op */
@@ -371,7 +425,7 @@ target_option
 	| TOKEN_BLEND '=' TOKEN_BOOLEAN ';'					{ $$.type = OT_Blend; $$.value.intValue = $3; }
 	| blend_color_header '{' blenddef_body '}' ';'		{ nodePop(parse_state); $$.type = OT_Color; $$.value.nodePtr = $1; }
 	| blend_alpha_header '{' blenddef_body '}' ';'		{ nodePop(parse_state); $$.type = OT_Alpha; $$.value.nodePtr = $1; }
-	| TOKEN_WRITEMASK '=' TOKEN_COLORMASK ';'			{ $$.type = OT_Index; $$.value.intValue = $3; }
+	| TOKEN_WRITEMASK '=' TOKEN_COLORMASK ';'			{ $$.type = OT_WriteMask; $$.value.intValue = $3; }
 	;
 
 	/* Blend definition */
@@ -748,5 +802,8 @@ qualifier
 
 void yyerror(YYLTYPE *locp, ParseState* parse_state, yyscan_t scanner, const char *msg) 
 { 
-	fprintf (stderr, "%s -- Line: %i Column: %i\n", msg, locp->first_line, locp->first_column);
+	parse_state->hasError = 1;
+	parse_state->errorLine = locp->first_line;
+	parse_state->errorColumn = locp->first_column;
+	parse_state->errorMessage = mmalloc_strdup(parse_state->memContext, msg);
 }

+ 66 - 3
BansheeSL/Include/BsASTFX.h

@@ -15,6 +15,14 @@ typedef struct tagNodeOptions NodeOptions;
 typedef struct tagNodeOption NodeOption;
 typedef struct tagASTFXNode ASTFXNode;
 typedef struct tagNodeLink NodeLink;
+typedef enum tagFillModeValue FillModeValue;
+typedef enum tagCullModeValue CullModeValue;
+typedef enum tagCompFuncValue CompFuncValue;
+typedef enum tagOpValue OpValue;
+typedef enum tagBlendOpValue BlendOpValue;
+typedef enum tagAddrModeValue AddrModeValue;
+typedef enum tagFilterValue FilterValue;
+typedef enum tagBufferUsageValue BufferUsageValue;
 
 enum tagNodeType
 {
@@ -29,7 +37,8 @@ enum tagNodeType
 	NT_SamplerState,
 	NT_AddrMode,
 	NT_Parameter,
-	NT_Block
+	NT_Block,
+	NT_Code
 };
 
 enum tagOptionType
@@ -96,7 +105,9 @@ enum tagOptionType
 	OT_Blocks,
 	OT_Parameter,
 	OT_Block,
-	OT_SamplerState
+	OT_SamplerState,
+	OT_Code,
+	OT_StencilRef
 };
 
 enum tagOptionDataType
@@ -118,7 +129,54 @@ enum tagParamType
 	PT_Sampler1D, PT_Sampler2D, PT_Sampler3D, PT_SamplerCUBE, PT_Sampler2DMS,
 	PT_Texture1D, PT_Texture2D, PT_Texture3D, PT_TextureCUBE, PT_Texture2DMS,
 	PT_ByteBuffer, PT_StructBuffer, PT_ByteBufferRW, PT_StructBufferRW,
-	PT_TypedBufferRW, PT_AppendBuffer, PT_ConsumeBuffer
+	PT_TypedBufferRW, PT_AppendBuffer, PT_ConsumeBuffer,
+	PT_Count // Keep at end
+};
+
+enum tagFillModeValue 
+{ 
+	FMV_Wire, FMV_Solid 
+};
+
+enum tagCullModeValue 
+{ 
+	CMV_None, CMV_CW, CMV_CCW 
+};
+
+enum tagCompFuncValue
+{ 
+	CFV_Fail, CFV_Pass, CFV_LT, CFV_LTE, 
+	CFV_EQ, CFV_NEQ, CFV_GTE, CFV_GT
+};
+
+enum tagOpValue 
+{ 
+	OV_Keep, OV_Zero, OV_Replace, OV_Incr, OV_Decr, 
+	OV_IncrWrap, OV_DecrWrap, OV_Invert, OV_One, OV_DestColor, 
+	OV_SrcColor, OV_InvDestColor, OV_InvSrcColor, OV_DestAlpha, 
+	OV_SrcAlpha, OV_InvDestAlpha, OV_InvSrcAlpha
+};
+
+enum tagBlendOpValue 
+{ 
+	BOV_Add, BOV_Subtract, BOV_RevSubtract, 
+	BOV_Min, BOV_Max 
+};
+
+enum tagAddrModeValue
+{
+	AMV_Wrap, AMV_Mirror, AMV_Clamp, AMV_Border
+};
+
+enum tagFilterValue 
+{ 
+	FV_None, FV_Point, FV_Linear, FV_Anisotropic, 
+	FV_PointCmp, FV_LinearCmp, FV_AnisotropicCmp 
+};
+
+enum tagBufferUsageValue 
+{ 
+	BUV_Static, BUV_Dynamic 
 };
 
 struct tagNodeLink
@@ -133,6 +191,11 @@ struct tagParseState
 	ASTFXNode* topNode;
 	void* memContext;
 
+	int hasError;
+	int errorLine;
+	int errorColumn;
+	const char* errorMessage;
+
 	NodeLink* nodeStack;
 };
 

+ 1 - 1
BansheeSL/Include/BsMMAlloc.h

@@ -5,6 +5,6 @@ void* mmalloc_new_context();
 void mmalloc_free_context(void* context);
 void* mmalloc(void* context, int size);
 void mmfree(void* ptr);
-char* mmalloc_strdup(void* context, char* input);
+char* mmalloc_strdup(void* context, const char* input);
 
 #endif

+ 2 - 2
BansheeSL/Source/BSMMAlloc.c

@@ -23,7 +23,7 @@ void mmalloc_free_context(void* context)
 {
 	MMAllocHeader* header = (MMAllocHeader*)context;
 	while (header->next != 0)
-		mmfree(header->next);
+		mmfree((char*)header->next + sizeof(MMAllocHeader));
 
 	free(header);
 }
@@ -59,7 +59,7 @@ void mmfree(void* ptr)
 	free(buffer);
 }
 
-char* mmalloc_strdup(void* context, char* input)
+char* mmalloc_strdup(void* context, const char* input)
 {
 	size_t length = strlen(input);
 	char* output = mmalloc(context, (int)(sizeof(char) * (length + 1)));

+ 5 - 0
BansheeSL/Source/BsASTFX.c

@@ -199,6 +199,11 @@ ParseState* parseStateCreate()
 	parseState->topNode = 0;
 	parseState->nodeStack = 0;
 
+	parseState->hasError = 0;
+	parseState->errorLine = 0;
+	parseState->errorColumn = 0;
+	parseState->errorMessage = 0;
+
 	nodePush(parseState, parseState->rootNode);
 
 	return parseState;

File diff suppressed because it is too large
+ 1048 - 0
BansheeSL/Source/BsSLPlugin.cpp


+ 2 - 0
BansheeUtility/BansheeUtility.vcxproj

@@ -257,6 +257,7 @@
     <ClCompile Include="Source\BsLineSegment3.cpp" />
     <ClCompile Include="Source\BsMessageHandler.cpp" />
     <ClCompile Include="Source\BsRect3.cpp" />
+    <ClCompile Include="Source\BsStringID.cpp" />
     <ClCompile Include="Source\BsTaskScheduler.cpp" />
     <ClCompile Include="Source\BsTestOutput.cpp" />
     <ClCompile Include="Source\BsTestSuite.cpp" />
@@ -296,6 +297,7 @@
     <ClInclude Include="Include\BsServiceLocator.h" />
     <ClInclude Include="Include\BsSpinLock.h" />
     <ClInclude Include="Include\BsStringFormat.h" />
+    <ClInclude Include="Include\BsStringID.h" />
     <ClInclude Include="Include\BsTaskScheduler.h" />
     <ClInclude Include="Include\BsTestOutput.h" />
     <ClInclude Include="Include\BsTestSuite.h" />

+ 6 - 0
BansheeUtility/BansheeUtility.vcxproj.filters

@@ -281,6 +281,9 @@
     <ClInclude Include="Include\ThirdParty\md5.h">
       <Filter>Header Files\ThirdParty</Filter>
     </ClInclude>
+    <ClInclude Include="Include\BsStringID.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsThreadPool.cpp">
@@ -451,5 +454,8 @@
     <ClCompile Include="Source\BsUtil.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="Source\BsStringID.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 1 - 0
BansheeUtility/Include/BsFwdDeclUtil.h

@@ -88,5 +88,6 @@ namespace BansheeEngine
 		TID_UnorderedMap = 55,
 		TID_Pair = 56,
 		TID_Set = 57,
+		TID_StringID = 58
 	};
 }

+ 2 - 1
BansheeUtility/Include/BsPrerequisitesUtil.h

@@ -63,4 +63,5 @@
 #include "BsString.h"
 #include "BsMessageHandlerFwd.h"
 #include "BsUtil.h"
-#include "BsPath.h"
+#include "BsPath.h"
+#include "BsStringID.h"

+ 205 - 0
BansheeUtility/Include/BsStringID.h

@@ -0,0 +1,205 @@
+#pragma once
+
+#include "BsPrerequisitesUtil.h"
+#include "BsSpinLock.h"
+
+namespace BansheeEngine
+{
+	/**
+	 * @brief	A string identifier that provides very fast comparisons
+	 *			to other string ids.
+	 *
+	 * @note	Essentially a unique ID is generated for each string and then
+	 *			the ID is used for comparisons as if you were using an integer
+	 *			or an enum.
+	 *
+	 *			Thread safe.
+	 */
+	class BS_UTILITY_EXPORT StringID
+	{
+		static const int HASH_TABLE_SIZE = 4096;
+		static const int MAX_CHUNK_COUNT = 50;
+		static const int ELEMENTS_PER_CHUNK = 256;
+		static const int STRING_SIZE = 256;
+
+		/**
+		 * @brief	Helper class that performs string actions on both null terminated character
+		 *			arrays and standard strings.
+		 */
+		template<class T>
+		class StringIDUtil
+		{
+		public:
+			static UINT32 size(T const& input) { return 0; }
+			static void copy(T const& input, char* dest) { }
+			static bool compare(T const& a, char* b) { return 0; }
+		};
+
+		/**
+		 * @brief	Internal data that is shared by all instances for a specific string.
+		 */
+		struct InternalData
+		{
+			UINT32 id;
+			InternalData* next;
+			char chars[STRING_SIZE];
+		};
+
+		/**
+		 * @brief	Performs initialization of static members as soon as the library is loaded.
+		 */
+		struct InitStatics
+		{
+			InitStatics();
+		};
+
+	public:
+		StringID();
+
+		StringID(const char* name)
+			:mData(nullptr)
+		{
+			construct(name);
+		}
+
+		StringID(const String& name)
+			:mData(nullptr)
+		{
+			construct(name);
+		}
+
+		template<int N>
+		StringID(const char name[N])
+			:mData(nullptr)
+		{
+			construct((const char*)name);
+		}
+
+		/**
+		 * @brief	Compare to string ids for equality. Uses fast integer comparison.
+		 */
+		bool operator== (const StringID& rhs) const
+		{
+			return mData == rhs.mData;
+		}
+
+		/**
+		 * @brief	Compare to string ids for inequality. Uses fast integer comparison.
+		 */
+		bool operator!= (const StringID& rhs) const
+		{
+			return mData != rhs.mData;
+		}
+
+		/**
+		 * @brief	Returns true if the string id has no value assigned.
+		 */
+		bool empty() const
+		{
+			return mData == nullptr;
+		}
+
+		/**
+		 * @brief	Returns the null-terminated name of the string id.
+		 */
+		const char* cstr() const
+		{
+			if (mData == nullptr)
+				return nullptr;
+
+			return mData->chars;
+		}
+
+		static const StringID NONE;
+
+	private:
+		/**
+		 * @brief	Constructs a StringID object in a way that works for pointers to character arrays
+		 *			and standard strings.
+		 */
+		template<class T>
+		void construct(T const& name);
+
+		/**
+		 * @brief	Calculates a hash value for the provided null-terminated string. 
+		 */
+		template<class T>
+		UINT32 calcHash(T const& input);
+
+		/**
+		 * @brief	Allocates a new string entry and assigns it a unique ID. 
+		 *			Optionally expands the chunks buffer if the new entry doesn't fit.
+		 */
+		InternalData* allocEntry();
+
+		InternalData* mData;
+
+		static volatile InitStatics mInitStatics;
+		static InternalData* mStringHashTable[HASH_TABLE_SIZE];
+		static InternalData* mChunks[MAX_CHUNK_COUNT];
+
+		static UINT32 mNextId;
+		static UINT32 mNumChunks;
+		static SpinLock mSync;
+	};
+
+	template<> struct RTTIPlainType <StringID>
+	{
+		enum { id = TID_StringID }; enum { hasDynamicSize = 1 };
+
+		static void toMemory(const StringID& data, char* memory)
+		{
+			UINT32 size = getDynamicSize(data);
+
+			UINT32 curSize = sizeof(UINT32);
+			memcpy(memory, &size, curSize);
+			memory += curSize;
+
+			bool isEmpty = data.empty();
+			memory = rttiWriteElem(isEmpty, memory);
+
+			if (!isEmpty)
+			{
+				UINT32 length = (UINT32)strlen(data.cstr());
+				memcpy(memory, data.cstr(), length * sizeof(char));
+			}
+		}
+
+		static UINT32 fromMemory(StringID& data, char* memory)
+		{
+			UINT32 size;
+			memcpy(&size, memory, sizeof(UINT32));
+			memory += sizeof(UINT32);
+
+			bool empty = false;
+			memory = rttiReadElem(empty, memory);
+
+			if (!empty)
+			{
+				UINT32 length = (size - sizeof(UINT32) - sizeof(bool)) / sizeof(char);
+
+				char* name = (char*)bs_alloc(length + 1);
+				memcpy(name, memory, length);
+				name[length] = '\0';
+
+				data = StringID(name);
+			}
+
+			return size;
+		}
+
+		static UINT32 getDynamicSize(const StringID& data)
+		{
+			UINT32 dataSize = sizeof(bool) + sizeof(UINT32);
+
+			bool isEmpty = data.empty();
+			if (!isEmpty)
+			{
+				UINT32 length = (UINT32)strlen(data.cstr());
+				dataSize += length * sizeof(char);
+			}
+
+			return (UINT32)dataSize;
+		}
+	};
+}

+ 146 - 0
BansheeUtility/Source/BsStringID.cpp

@@ -0,0 +1,146 @@
+#include "BsStringID.h"
+
+namespace BansheeEngine
+{
+	const StringID StringID::NONE = StringID();
+
+	volatile StringID::InitStatics StringID::mInitStatics = StringID::InitStatics();
+
+	StringID::InternalData* StringID::mStringHashTable[HASH_TABLE_SIZE];
+	StringID::InternalData* StringID::mChunks[MAX_CHUNK_COUNT];
+
+	UINT32 StringID::mNextId = 0;
+	UINT32 StringID::mNumChunks = 0;
+	SpinLock StringID::mSync = SpinLock();
+
+	StringID::InitStatics::InitStatics()
+	{
+		ScopedSpinLock lock(mSync);
+
+		memset(mStringHashTable, 0, sizeof(mStringHashTable));
+		memset(mChunks, 0, sizeof(mChunks));
+
+		mChunks[0] = (InternalData*)bs_alloc(sizeof(InternalData) * ELEMENTS_PER_CHUNK);
+		memset(mChunks[0], 0, sizeof(InternalData) * ELEMENTS_PER_CHUNK);
+
+		mNumChunks++;
+	}
+
+	StringID::StringID()
+		:mData(nullptr)
+	{ }
+
+	template<class T>
+	void StringID::construct(T const& name)
+	{
+		assert(StringIDUtil<T>::size(name) <= STRING_SIZE);
+
+		UINT32 hash = calcHash(name) & (sizeof(mStringHashTable) / sizeof(mStringHashTable[0]) - 1);
+		InternalData* existingEntry = mStringHashTable[hash];
+		
+		while (existingEntry != nullptr)
+		{
+			if (StringIDUtil<T>::compare(name, existingEntry->chars))
+			{
+				mData = existingEntry;
+				return;
+			}
+
+			existingEntry = existingEntry->next;
+		}
+
+		ScopedSpinLock lock(mSync);
+
+		// Search for the value again in case other thread just added it
+		existingEntry = mStringHashTable[hash];
+		InternalData* lastEntry = nullptr;
+		while (existingEntry != nullptr)
+		{
+			if (StringIDUtil<T>::compare(name, existingEntry->chars))
+			{
+				mData = existingEntry;
+				return;
+			}
+
+			lastEntry = existingEntry;
+			existingEntry = existingEntry->next;
+		}
+
+		mData = allocEntry();
+		StringIDUtil<T>::copy(name, mData->chars);
+
+		if (lastEntry == nullptr)
+			mStringHashTable[hash] = mData;
+		else
+			lastEntry->next = mData;
+	}
+
+	template<class T>
+	UINT32 StringID::calcHash(T const& input)
+	{
+		UINT32 size = StringIDUtil<T>::size(input);
+
+		UINT32 hash = 0;
+		for (UINT32 i = 0; i < size; i++)
+			hash = hash * 101 + input[i];
+
+		return hash;
+	}
+
+	StringID::InternalData* StringID::allocEntry()
+	{
+		UINT32 chunkIdx = mNextId / ELEMENTS_PER_CHUNK;
+
+		assert(chunkIdx < MAX_CHUNK_COUNT);
+		assert(chunkIdx <= mNumChunks); // Can only increment sequentially
+
+		if (chunkIdx >= mNumChunks)
+		{
+			mChunks[chunkIdx] = (InternalData*)bs_alloc(sizeof(InternalData) * ELEMENTS_PER_CHUNK);
+			memset(mChunks[chunkIdx], 0, sizeof(InternalData) * ELEMENTS_PER_CHUNK);
+
+			mNumChunks++;
+		}
+
+		InternalData* chunk = mChunks[chunkIdx];
+		UINT32 chunkSpecificIndex = mNextId % ELEMENTS_PER_CHUNK;
+
+		InternalData* newEntry = &chunk[chunkSpecificIndex];
+		newEntry->id = mNextId++;
+		newEntry->next = nullptr;
+
+		return newEntry;
+	}
+
+	template<>
+	class StringID::StringIDUtil<const char*>
+	{
+	public:
+		static UINT32 size(const char* const& input) { return (UINT32)strlen(input); }
+		static void copy(const char* const& input, char* dest) { memcpy(dest, input, strlen(input) + 1); }
+		static bool compare(const char* const& a, char* b) { return strcmp(a, b) == 0; }
+	};
+
+	template<>
+	class StringID::StringIDUtil <String>
+	{
+	public:
+		static UINT32 size(String const& input) { return (UINT32)input.length(); }
+		static void copy(String const& input, char* dest)
+		{ 
+			UINT32 len = (UINT32)input.length();
+			input.copy(dest, len);
+			dest[len] = '\0';
+		}
+		static bool compare(String const& a, char* b) { return a.compare(b) == 0; }
+	};
+
+	template class StringID::StringIDUtil <const char*>;
+	template class StringID::StringIDUtil <String>;
+
+	template BS_UTILITY_EXPORT void StringID::construct(const char* const&);
+	template BS_UTILITY_EXPORT void StringID::construct(String const&);
+	
+	template BS_UTILITY_EXPORT UINT32 StringID::calcHash(const char* const&);
+	template BS_UTILITY_EXPORT UINT32 StringID::calcHash(String const&);
+}

+ 41 - 133
TODO.txt

@@ -109,146 +109,54 @@ C# material interface:
 
 --------
 
-Questions:
- - How to deal with sampler states? Allow default ones in shader?
-   - Yes, allow default ones. Plus allow sampler states to be tweaked from Material directly (without separate SamplerState class)
- - PRoblem where DX9 requires sampler to have the same name as texture, but DX11 has them separate. For now go with DX11 approach
-   where you need to define the sampler separately, potentially allow "alias()" attribute so the system knows to look for other names.
-
-Check D:\ExampleBFX.txt for an example effects file
-
-How to deal with includes?
- - You can do Include = "Path/to/CommonShader"
-   - Path is relative to executable
- - CommonShader might not contain any techniques or passes, but instead just code.
-  - It can use special Include & Code {} tags that allow it to specify various code
-    for some language
- - How does the runtime resolve those shaders?
-  - They are only resolved during import, after which just resource references are kept (i.e. its GUIDs)
-  - The runtime should then be able to resolve the GUIDs easily
-
-VALID KEYWORDS:
-<<RasterizerState>>
-Fill = Wire/Solid
-Cull = None/CW/CCW
-DepthBias = float
-ScaledDepthBias = float
-DepthClip = bool
-Scissor = bool
-Multisample = bool
-AALine = bool
-
-<<DepthStencilState>>
-DepthRead = bool
-DepthWrite = bool
-CompareFunc = Fail/Pass/Less/LessEqual/Equal/NotEqual/GreaterEqual/Greater
-Stencil = bool
-StencilReadMask = byte
-StencilWriteMask = byte
-StencilOpFront = <StencilOp>
-StencilOpBack = <StencilOp>
-
-<<StencilOp>>
-Fail = Keep/Zero/Replace/Increment/Decrement/IncrementWrap/DecrementWrap/Invert,
-ZFail = Keep/Zero/Replace/Increment/Decrement/IncrementWrap/DecrementWrap/Invert,
-Pass = Keep/Zero/Replace/Increment/Decrement/IncrementWrap/DecrementWrap/Invert,
-CompFunc = Fail/Pass/Less/LessEqual/Equal/NotEqual/GreaterEqual/Greater
-
-<<BlendState>>
-AlphaToCoverage = bool
-IndependantBlend = bool
-PerTarget = <TargetBlendState>
-
-<<TargetBlendState>>
-Index = int (0 to 7)
-Blend = bool
-Color = <BlendDefinition>
-Alpha = <BlendDefinition>
-WriteMask = R/G/B/A/RG/RB/RA/GB/GA/BA/RGB/RGA/RBA/GBA/RGBA;
-
-<<BlendDefinition>>
-Source = One/Zero/DestColor/SrcColor/InvDestColor/InvSourceColor/DestAlpha/SrcAlpha/InvDestAlpha/InvSrcAlpha
-Dest  = One/Zero/DestColor/SrcColor/InvDestColor/InvSourceColor/DestAlpha/SrcAlpha/InvDestAlpha/InvSrcAlpha
-Op = Add/Subtract/RevereSubtract/Min/Max
-
-<<SamplerState>>
-AddressingMode =
-{ u = Wrap/Mirror/Clamp/Border,
-  v = Wrap/Mirror/Clamp/Border,
-  w = Wrap/Mirror/Clamp/Border
-}
-MinFilter = None/Point/Linear/Anisotropic/PointComp/LinearComp/AnisotropicComp
-MagFilter = None/Point/Linear/Anisotropic/PointComp/LinearComp/AnisotropicComp
-MipFilter = None/Point/Linear/Anisotropic/PointComp/LinearComp/AnisotropicComp
-MaxAniso = int
-MipmapBias = float
-MipMin = float
-MipMax = float
-BorderColor = <Color>
-ComparisonFunc = Fail/Pass/Less/LessEqual/Equal/NotEqual/GreaterEqual/Greater
-
-<<Color>>
-R = float
-G = float
-B = float
-A = float
-
-Other types
-float, int, bool, float2, float3, float4, mat2x2, mat2x3, mat2x4, mat3x2, mat3x3, mat3x4, mat4x2, mat4x3, mat4x4
-
-FX types:
-<<Shader>>
-Separable = bool
-Queue = int
-Priority = int
-Parameters = <ParamDef>
-Blocks = <BlockDef>
-Technique = <TechniqueDef>
-
-<<ParamDef>>
-Type name (: option)* (= block | literal);
-
-<<BlockDef>>
-Block name (: option)*;
-
-<<TechniqueDef>>
-Renderer = string (default strings recognized: "Any", "Default")
-Language = string (default strings recognized: "HLSL9", "HLSL11", "GLSL", "HLSL"(11))
-Include = string
-Pass = <PassDef> 
-
-<<PassDef>>
-Rasterizer/DepthStencil/Blend state options as above
-Vertex = code
-Fragment = code
-Geometry = code
-Hull = code
-Domain = code
-Compute = code
+Include files:
+ - Remove references to HGpuProgInclude when creating a GpuProgram
+  - Keep using HGpuProgInclude since I need a special resource for includes (I don't want the importer to think 
+     they're Shaders, plus I can avoid making a special case for them in the parser)
+ - Instead try to find and load included shader files in BansheeSL by calling Resources
+  - If resource cannot be found ignore it, but still register it as a dependency
+ - All includes should be registered in ShaderManager
+  - Whenever a shader is loaded this should be notified so it may recompile all shaders
+ - GpuProgram::recompile(newSource)
+   - TODO - Need info
+
+ShaderManager will also be needed when I'm changing shader defines
+ - TODO - Test shaders and ensure #defines work
+  - DX11 might need to call D3DPreprocess and include a list of defines
+ - GLSL - Need to manually specify #defines as separate lines
+
+ShaderManager will also be needed when switching render APIs during runtime (if that will be possible)
+ - It can also serve as a place where we perform shader caching
 
 -------------------
 
-TODO:
- - Test the example shader and ensure parameters/blocks/qualifiers/default values and nested nodes work properly
- - Stencil read and write masks don't accept binary masks but instead raw integers
- - Code blocks (e.g. vertex/fragment/etc)
- - In lexer I use numbers to identify different values, but use enums instead so I can use the same ones when parsing AST
- - Generate Shader from parsed AST
- - Make sure includes are handled properly
- - Make sure default values are handled properly
- - POssible way to handle code blocks: http://flex.sourceforge.net/manual/Start-Conditions.html
- - When replacing code blocks make sure to replace them with empty lines so that line numbers stay valid when reporting errors
- -----
+TODO STAGE 1:
+ - Testing:
+   - If there are any new problems due to semantic and techniques using StringID
+
+TODO STAGE 2:
+ - Handle include files (include files should just be plain text files with no additional parsing)
+  - When includes that shaders depend on are imported/changes I need to recompile those shaders
+    - Whenever a GPU program is created it registers itself with a manager and sets up the includes it relies on
+	- Whenever .shader import is called, it scans through all includes and finds out if any shaders depend on them
+	  - If so, it performs a recompile on those shaders
+  - Currently I handle includes on a pretty low level. Maybe I should handle them in BansheeSL instead? (Directly injecting the include code into the source code)
+  - How to handle parsing of include .shader files? They don't need techniques or passes.
+ - Handle default values (ignore default values for shared param blocks for now)
+   - additional argument in Shader::addParameter, copy values to buffers when initializing Material
+ - Make sure shader saving works and optionally make GpuProgram a non-resource
+  - Make sure GPU programs and states are saved with the Shader
+
+TODO STAGE 3:
  - Move all builtin shaders to the new .shader file model
- - Optionally change how GpuPrograms are saved
- - Save the test shader somewhere so I can use it as a unit test
-  - test shader is missing code blocks
- - Need a decent way to report syntax errors (at minimum a line and column where it happened)
-  - Later on I'd like a better system that actually tells the user something about the problem, other than just "syntax error"
- -----
+ - Store example shader somewhere in Banshee data so I can use it for easy testing.
+
+TODO LATER:
  - Add GpuProgram caching (e.g. save compiled programs somewhere for later use)
  - Consider adding restrictions on parameter ranges (probably via an additional qualifier)
  - Parameter definitions don't support arrays (Leave this for a later iteration)
+ - Parameter definitions don't support structs
+ - Better error reporting instead of just "syntax error" that better informs the user what the error is
 
 ----------------------------------------------------------------------
 Scene View

Some files were not shown because too many files changed in this diff