Browse Source

Refactoring the shader pre-processor

Panagiotis Christopoulos Charitos 10 years ago
parent
commit
d8c2c15bfc
48 changed files with 285 additions and 314 deletions
  1. 7 0
      include/anki/resource/Common.h
  2. 1 1
      include/anki/resource/Material.h
  3. 7 19
      include/anki/resource/ShaderLoader.h
  4. 1 2
      shaders/Blit.frag.glsl
  5. 1 1
      shaders/Clusterer.glsl
  6. 1 2
      shaders/Dbg.frag.glsl
  7. 1 2
      shaders/Dbg.vert.glsl
  8. 2 4
      shaders/Final.frag.glsl
  9. 6 7
      shaders/FsCommonFrag.glsl
  10. 2 2
      shaders/FsCommonVert.glsl
  11. 6 5
      shaders/GaussianBlurGeneric.glsl
  12. 1 1
      shaders/ImageReflections.glsl
  13. 4 5
      shaders/IsLp.frag.glsl
  14. 1 3
      shaders/IsLp.vert.glsl
  15. 4 6
      shaders/IsRejectLights.glsl
  16. 7 9
      shaders/IsUpdateTiles.glsl
  17. 1 2
      shaders/LfOcclusion.frag.glsl
  18. 1 2
      shaders/LfOcclusion.vert.glsl
  19. 1 2
      shaders/LfSpritePass.frag.glsl
  20. 1 2
      shaders/LfSpritePass.vert.glsl
  21. 1 1
      shaders/LightFunctions.glsl
  22. 1 1
      shaders/LightResources.glsl
  23. 3 3
      shaders/MsCommonFrag.glsl
  24. 8 8
      shaders/MsCommonTessc.glsl
  25. 1 1
      shaders/MsCommonVert.glsl
  26. 1 1
      shaders/MsFsCommon.glsl
  27. 2 3
      shaders/NearDepthUpscale.frag.glsl
  28. 1 2
      shaders/NearDepthUpscale.vert.glsl
  29. 1 1
      shaders/Pack.glsl
  30. 3 4
      shaders/Pps.frag.glsl
  31. 4 5
      shaders/PpsBloom.frag.glsl
  32. 3 4
      shaders/PpsSsao.frag.glsl
  33. 1 2
      shaders/PpsSslf.frag.glsl
  34. 2 3
      shaders/PpsTmAverageLuminance.comp.glsl
  35. 1 2
      shaders/Quad.vert.glsl
  36. 3 4
      shaders/Refl.frag.glsl
  37. 3 3
      shaders/Sslr.glsl
  38. 1 2
      shaders/TilerMinMax.comp.glsl
  39. 1 1
      shaders/Tonemapping.glsl
  40. 1 2
      shaders/UiLines.frag.glsl
  41. 1 2
      shaders/UiLines.vert.glsl
  42. 1 3
      shaders/VariableSamplingBlurGeneric.frag.glsl
  43. 65 0
      src/resource/Common.cpp
  44. 3 3
      src/resource/Material.cpp
  45. 2 3
      src/resource/MaterialLoader.cpp
  46. 0 170
      src/resource/ProgramPrePreprocessor.cpp
  47. 107 0
      src/resource/ShaderLoader.cpp
  48. 8 3
      src/resource/ShaderResource.cpp

+ 7 - 0
include/anki/resource/Common.h

@@ -9,6 +9,7 @@
 #include <anki/util/DArray.h>
 #include <anki/util/String.h>
 #include <anki/util/Ptr.h>
+#include <anki/gr/Enums.h>
 
 namespace anki
 {
@@ -80,6 +81,12 @@ using TempResourceAllocator = StackAllocator<T>;
 
 /// An alias that denotes a ResourceFilesystem path.
 using ResourceFilename = CString;
+
+/// Given a shader type return the appropriate file extension.
+const CString& shaderTypeToFileExtension(ShaderType type);
+
+/// Given a filename return the shader type.
+Error fileExtensionToShaderType(const CString& filename, ShaderType& type);
 /// @}
 
 } // end namespace anki

+ 1 - 1
include/anki/resource/Material.h

@@ -350,7 +350,7 @@ private:
 
 	/// Create a unique shader source in chache. If already exists do nothing
 	ANKI_USE_RESULT Error createProgramSourceToCache(
-		const String& source, StringAuto& out);
+		const String& source, ShaderType type, StringAuto& out);
 };
 
 //==============================================================================

+ 7 - 19
include/anki/resource/ProgramPrePreprocessor.h → include/anki/resource/ShaderLoader.h

@@ -13,29 +13,20 @@
 namespace anki
 {
 
-/// Helper class used for shader program loading
-///
-/// The class fills some of the GLSL spec deficiencies. It adds the include
-/// preprocessor directive and the support to have all the shaders in the same
-/// file. The file that includes all the shaders is called
-/// PrePreprocessor-compatible.
-///
-/// The preprocessor pragmas are:
-///
-/// - #pragma anki type <vert | tesc | tese | geom | frag | comp>
-/// - #pragma anki include "<filename>"
-class ProgramPrePreprocessor
+/// Helper class used for shader program loading. The class adds the include
+/// preprocessor directive.
+class ShaderLoader
 {
 public:
 	/// It loads a file and parses it
 	/// @param[in] filename The file to load
-	ProgramPrePreprocessor(ResourceManager* manager)
+	ShaderLoader(ResourceManager* manager)
 		: m_alloc(manager->getTempAllocator())
 		, m_manager(manager)
 	{
 	}
 
-	~ProgramPrePreprocessor()
+	~ShaderLoader()
 	{
 		m_shaderSource.destroy(m_alloc);
 		m_sourceLines.destroy(m_alloc);
@@ -74,18 +65,15 @@ protected:
 	/// Keep the manager for some path conversions.
 	ResourceManager* m_manager;
 
-	/// A recursive function that parses a file for pragmas and updates the
+	/// A recursive function that parses a file for #include and updates the
 	/// output
 	///
 	/// @param filename The file to parse
 	/// @param depth The #line in GLSL does not support filename so an
 	///              depth it being used. It also tracks the includance depth
-	ANKI_USE_RESULT Error parseFileForPragmas(
+	ANKI_USE_RESULT Error parseFileIncludes(
 		ResourceFilename filename, U32 depth);
 
-	/// Parse the type
-	ANKI_USE_RESULT Error parseType(const String& line, Bool& found);
-
 	void printSourceLines() const; ///< For debugging
 };
 

+ 1 - 2
shaders/Blit.frag.glsl

@@ -3,8 +3,7 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
-#pragma anki type frag
-#pragma anki include "shaders/Common.glsl"
+#include "shaders/Common.glsl"
 
 layout(binding = 0) uniform lowp sampler2D uTex;
 

+ 1 - 1
shaders/Clusterer.glsl

@@ -8,7 +8,7 @@
 #ifndef ANKI_SHADERS_CLUSTERER_GLSL
 #define ANKI_SHADERS_CLUSTERER_GLSL
 
-#pragma anki include "shaders/Common.glsl"
+#include "shaders/Common.glsl"
 
 //==============================================================================
 // Compute the cluster index using the tile index.

+ 1 - 2
shaders/Dbg.frag.glsl

@@ -3,8 +3,7 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
-#pragma anki type frag
-#pragma anki include "shaders/Common.glsl"
+#include "shaders/Common.glsl"
 
 layout(location = 0) in vec3 inColor;
 

+ 1 - 2
shaders/Dbg.vert.glsl

@@ -3,8 +3,7 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
-#pragma anki type vert
-#pragma anki include "shaders/Common.glsl"
+#include "shaders/Common.glsl"
 
 layout(location = 0) in vec4 in_position;
 layout(location = 1) in vec4 in_color;

+ 2 - 4
shaders/Final.frag.glsl

@@ -5,10 +5,8 @@
 
 // The final pass
 
-#pragma anki type frag
-
-#pragma anki include "shaders/Common.glsl"
-#pragma anki include "shaders/Pack.glsl"
+#include "shaders/Common.glsl"
+#include "shaders/Pack.glsl"
 
 layout(binding = 0) uniform sampler2D u_tex;
 

+ 6 - 7
shaders/FsCommonFrag.glsl

@@ -1,20 +1,19 @@
-// Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos.
 // All rights reserved.
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
 // Common code for all fragment shaders of BS
-#pragma anki include "shaders/Common.glsl"
-#pragma anki include "shaders/MsFsCommon.glsl"
-#pragma anki include "shaders/LinearDepth.glsl"
-#pragma anki include "shaders/Clusterer.glsl"
+#include "shaders/Common.glsl"
+#include "shaders/MsFsCommon.glsl"
+#include "shaders/LinearDepth.glsl"
+#include "shaders/Clusterer.glsl"
 
 // Global resources
 layout(TEX_BINDING(1, 0)) uniform sampler2D anki_msDepthRt;
 #define LIGHT_SET 1
 #define LIGHT_SS_BINDING 0
 #define LIGHT_TEX_BINDING 1
-#pragma anki include "shaders/LightResources.glsl"
+#include "shaders/LightResources.glsl"
 #undef LIGHT_SET
 #undef LIGHT_SS_BINDING
 #undef LIGHT_TEX_BINDING
@@ -26,7 +25,7 @@ layout(location = 1) flat in float in_alpha;
 
 layout(location = 0) out vec4 out_color;
 
-#pragma anki include "shaders/LightFunctions.glsl"
+#include "shaders/LightFunctions.glsl"
 
 //==============================================================================
 #if PASS == COLOR

+ 2 - 2
shaders/FsCommonVert.glsl

@@ -4,13 +4,13 @@
 // http://www.anki3d.org/LICENSE
 
 // Common code for all vertex shaders of FS
-#pragma anki include "shaders/MsFsCommon.glsl"
+#include "shaders/MsFsCommon.glsl"
 
 // Global resources
 #define LIGHT_SET 1
 #define LIGHT_SS_BINDING 0
 #define LIGHT_TEX_BINDING 1
-#pragma anki include "shaders/LightResources.glsl"
+#include "shaders/LightResources.glsl"
 #undef LIGHT_SET
 #undef LIGHT_SS_BINDING
 #undef LIGHT_TEX_BINDING

+ 6 - 5
shaders/GaussianBlurGeneric.glsl

@@ -13,10 +13,9 @@
 ///
 /// This is an optimized version. See the clean one at r213
 
-#pragma anki start vertexShader
-#pragma anki include "shaders/SimpleVert.glsl"
+#if 0
 
-#pragma anki start fragmentShader
+#include "shaders/SimpleVert.glsl"
 
 precision mediump float;
 
@@ -62,7 +61,7 @@ in vec2 vTexCoords;
 // Weights
 const float first_weight = 0.2270270270;
 const float weights[4] = float[](
-	0.3162162162, 0.0702702703, 
+	0.3162162162, 0.0702702703,
 	0.3162162162, 0.0702702703);
 
 // Calc the kernel
@@ -97,7 +96,9 @@ void main()
 	// side pixels
 	for(int i = 0; i < KERNEL_SIZE; i++)
 	{
-		fFragColor += 
+		fFragColor +=
 			texture(img, vTexCoords + kernel[i]).TEX_FETCH * weights[i];
 	}
 }
+
+#endif

+ 1 - 1
shaders/ImageReflections.glsl

@@ -8,7 +8,7 @@
 #ifndef ANKI_SHADERS_IMAGE_REFLECTIONS_GLSL
 #define ANKI_SHADERS_IMAGE_REFLECTIONS_GLSL
 
-#pragma anki include "shaders/Clusterer.glsl"
+#include "shaders/Clusterer.glsl"
 
 #define ACCURATE_RAYS 0
 

+ 4 - 5
shaders/IsLp.frag.glsl

@@ -3,14 +3,13 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
-#pragma anki type frag
-#pragma anki include "shaders/Pack.glsl"
-#pragma anki include "shaders/Clusterer.glsl"
+#include "shaders/Pack.glsl"
+#include "shaders/Clusterer.glsl"
 
 #define LIGHT_SET 0
 #define LIGHT_SS_BINDING 0
 #define LIGHT_TEX_BINDING 4
-#pragma anki include "shaders/LightResources.glsl"
+#include "shaders/LightResources.glsl"
 #undef LIGHT_SET
 #undef LIGHT_SS_BINDING
 #undef LIGHT_TEX_BINDING
@@ -26,7 +25,7 @@ layout(location = 2) in vec2 in_projectionParams;
 
 layout(location = 0) out vec3 out_color;
 
-#pragma anki include "shaders/LightFunctions.glsl"
+#include "shaders/LightFunctions.glsl"
 
 const uint TILE_COUNT = TILE_COUNT_X * TILE_COUNT_Y;
 

+ 1 - 3
shaders/IsLp.vert.glsl

@@ -3,11 +3,9 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
-#pragma anki type vert
-
 #define LIGHT_SET 0
 #define LIGHT_SS_BINDING 0
-#pragma anki include "shaders/LightResources.glsl"
+#include "shaders/LightResources.glsl"
 #undef LIGHT_SET
 #undef LIGHT_SS_BINDING
 

+ 4 - 6
shaders/IsRejectLights.glsl

@@ -5,11 +5,9 @@
 
 // This compute shader rejects lights
 
-#pragma anki start computeShader
-
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 
-#pragma anki include "shaders/IsCommon.glsl"
+#include "shaders/IsCommon.glsl"
 
 #define TILE_W (DEPTHMAP_WIDTH / TILES_X_COUNT)
 #define TILE_H (DEPTHMAP_HEIGHT / TILES_Y_COUNT)
@@ -49,7 +47,7 @@ void main()
 	//
 	vec2 minMaxDepth = vec2(10000.0, -10000.0); // max depth of tile
 
-	const vec2 COORD = vec2(tileX, tileY) 
+	const vec2 COORD = vec2(tileX, tileY)
 		* (vec2(1.0) / vec2(float(TILES_X_COUNT), float(TILES_Y_COUNT)));
 
 	vec2 coord = COORD;
@@ -86,7 +84,7 @@ void main()
 		vec4 posRadius = pointLights[lightId].posRadius;
 		vec3 pos = posRadius.xyz;
 		float radius = -1.0 / posRadius.w;
-		
+
 		// Should reject?
 		if((pos.z + radius) >= z[1] && (pos.z - radius) <= z[0])
 		{
@@ -99,7 +97,7 @@ void main()
 	// Copy back
 	for(uint i = 0U; i < newPointLightsCount; i++)
 	{
-		tiles[tileIndex].pointLightIndices[i / 4U][i % 4U] = 
+		tiles[tileIndex].pointLightIndices[i / 4U][i % 4U] =
 			newPointLightIndices[i];
 	}
 	tiles[tileIndex].lightsCount[0] = newPointLightsCount;

+ 7 - 9
shaders/IsUpdateTiles.glsl

@@ -5,12 +5,10 @@
 
 // Compute shader that bins lights to the tiles
 
-#pragma anki start computeShader
-
 // Set number of work items
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 
-#pragma anki include "shaders/IsCommon.glsl"
+#include "shaders/IsCommon.glsl"
 
 //
 // Data
@@ -26,7 +24,7 @@ layout(std140, binding = 0) buffer tilegridBuffer
 layout(std140, binding = 1) buffer lightsBuffer
 {
 	Lights lights;
-}; 
+};
 
 // The output buffer
 layout(std430, binding = 2) buffer tilesBuffer
@@ -54,9 +52,9 @@ layout(std430, binding = 3) buffer spotTexLightsCountBuffer
 
 // Return true if spere is in the half space defined by the plane
 bool pointLightInsidePlane(in PointLight light, in Plane plane)
-{	
-	// Result of the plane test. Distance of 
-	float dist = dot(plane.normalOffset.xyz, light.posRadius.xyz) 
+{
+	// Result of the plane test. Distance of
+	float dist = dot(plane.normalOffset.xyz, light.posRadius.xyz)
 		- plane.normalOffset.w;
 
 	return dist >= 0.0;
@@ -72,7 +70,7 @@ bool spotLightInsidePlane(in SpotLight light, in Plane plane)
 
 	for(uint i = 0U; i < 4; i++)
 	{
-		float dist = dot(plane.normalOffset.xyz, light.extendPoints[i].xyz) 
+		float dist = dot(plane.normalOffset.xyz, light.extendPoints[i].xyz)
 			- plane.normalOffset.w;
 
 		if(dist >= 0.0)
@@ -95,6 +93,6 @@ void main()
 	// First the point lights
 	for(uint i = 0U; i < lights.count.x; i++)
 	{
-		
+
 	}
 }

+ 1 - 2
shaders/LfOcclusion.frag.glsl

@@ -5,8 +5,7 @@
 
 // LF occlusion frag shader
 
-#pragma anki type frag
-#pragma anki include "shaders/Common.glsl"
+#include "shaders/Common.glsl"
 
 void main()
 {}

+ 1 - 2
shaders/LfOcclusion.vert.glsl

@@ -5,8 +5,7 @@
 
 // LF occlusion vert shader
 
-#pragma anki type vert
-#pragma anki include "shaders/Common.glsl"
+#include "shaders/Common.glsl"
 
 layout(UBO_BINDING(0, 0), std140, row_major) uniform _block
 {

+ 1 - 2
shaders/LfSpritePass.frag.glsl

@@ -5,8 +5,7 @@
 
 // LF sprites frag shader
 
-#pragma anki type frag
-#pragma anki include "shaders/Common.glsl"
+#include "shaders/Common.glsl"
 
 layout(UBO_BINDING(0, 0)) uniform sampler2DArray u_tex;
 

+ 1 - 2
shaders/LfSpritePass.vert.glsl

@@ -5,8 +5,7 @@
 
 // LF sprites vert shader
 
-#pragma anki type vert
-#pragma anki include "shaders/Common.glsl"
+#include "shaders/Common.glsl"
 
 // Per flare information
 struct Sprite

+ 1 - 1
shaders/LightFunctions.glsl

@@ -8,7 +8,7 @@
 #ifndef ANKI_SHADERS_LIGHT_FUNCTIONS_GLSL
 #define ANKI_SHADERS_LIGHT_FUNCTIONS_GLSL
 
-#pragma anki include "shaders/Common.glsl"
+#include "shaders/Common.glsl"
 
 const float ATTENUATION_BOOST = 0.05;
 const float OMNI_LIGHT_FRUSTUM_NEAR_PLANE = 0.1 / 4.0;

+ 1 - 1
shaders/LightResources.glsl

@@ -6,7 +6,7 @@
 #ifndef ANKI_SHADERS_LIGHT_RESOURCES_GLSL
 #define ANKI_SHADERS_LIGHT_RESOURCES_GLSL
 
-#pragma anki include "shaders/Common.glsl"
+#include "shaders/Common.glsl"
 
 // Common uniforms between lights
 struct LightingUniforms

+ 3 - 3
shaders/MsCommonFrag.glsl

@@ -3,14 +3,14 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
-#pragma anki include "shaders/Common.glsl"
+#include "shaders/Common.glsl"
 
 #if !GL_ES && __VERSION__ > 400
 layout(early_fragment_tests) in;
 #endif
 
-#pragma anki include "shaders/Pack.glsl"
-#pragma anki include "shaders/MsFsCommon.glsl"
+#include "shaders/Pack.glsl"
+#include "shaders/MsFsCommon.glsl"
 
 //==============================================================================
 // Variables                                                                   =

+ 8 - 8
shaders/MsCommonTessc.glsl

@@ -3,7 +3,7 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
-#pragma anki include "shaders/MsBsCommon.glsl"
+#include "shaders/MsBsCommon.glsl"
 
 layout(vertices = 3) out;
 
@@ -81,7 +81,7 @@ vec3 projectToPlane(vec3 point, vec3 planePoint, vec3 planeNormal)
 	float pen = dot(v, planeNormal);
 	vec3 d = pen * planeNormal;
 	return (point - d);
-} 
+}
 
 // Calculate control points
 void calcPositions()
@@ -126,7 +126,7 @@ void calcPositions()
 	pnPatch.pos111 = (pnPatch.pos021 + pnPatch.pos012 + pnPatch.pos102 +
 		pnPatch.pos201 + pnPatch.pos210 + pnPatch.pos120) / 6.0;
 	pnPatch.pos111 += (pnPatch.pos111 - center) / 2.0;
-} 
+}
 
 vec3 calcFaceNormal(in vec3 v0, in vec3 v1, in vec3 v2)
 {
@@ -167,8 +167,8 @@ bool posOutsideClipSpace(in vec2 posNdc)
 bool isFaceOutsideClipSpace(in vec2 posNdc[3])
 {
 	return any(bvec3(
-		posOutsideClipSpace(posNdc[0]), 
-		posOutsideClipSpace(posNdc[1]), 
+		posOutsideClipSpace(posNdc[0]),
+		posOutsideClipSpace(posNdc[1]),
 		posOutsideClipSpace(posNdc[2])));
 }
 
@@ -177,7 +177,7 @@ bool isFaceVisible(in mat4 mvp)
 {
 	// Calculate clip positions
 	vec2 clip[3];
-	for(int i = 0 ; i < 3 ; i++) 
+	for(int i = 0 ; i < 3 ; i++)
 	{
 		vec4 v = mvp * IN_POS4(i);
 		clip[i] = v.xy / (v.w * 0.5 + 0.5);
@@ -243,8 +243,8 @@ void tessellatePNPositionNormalTangentTexCoord(
 	{
 		// The face is front facing
 
-		for(int i = 0 ; i < 3 ; i++) 
-		{		
+		for(int i = 0 ; i < 3 ; i++)
+		{
 			outTexCoord[i] = inTexCoords[i];
 			outNormal[i] = inNormal[i];
 #if PASS == COLOR

+ 1 - 1
shaders/MsCommonVert.glsl

@@ -3,7 +3,7 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
-#pragma anki include "shaders/MsFsCommon.glsl"
+#include "shaders/MsFsCommon.glsl"
 
 //
 // Attributes

+ 1 - 1
shaders/MsFsCommon.glsl

@@ -3,7 +3,7 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
-#pragma anki include "shaders/Common.glsl"
+#include "shaders/Common.glsl"
 
 // Misc
 #define COLOR 0

+ 2 - 3
shaders/NearDepthUpscale.frag.glsl

@@ -3,9 +3,8 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
-#pragma anki type frag
-#pragma anki include "shaders/Common.glsl"
-#pragma anki include "shaders/LinearDepth.glsl"
+#include "shaders/Common.glsl"
+#include "shaders/LinearDepth.glsl"
 
 layout(location = 0) in vec2 in_uvLow;
 layout(location = 1) in vec2 in_uvHigh;

+ 1 - 2
shaders/NearDepthUpscale.vert.glsl

@@ -3,8 +3,7 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
-#pragma anki type vert
-#pragma anki include "shaders/Common.glsl"
+#include "shaders/Common.glsl"
 
 out gl_PerVertex
 {

+ 1 - 1
shaders/Pack.glsl

@@ -6,7 +6,7 @@
 #ifndef ANKI_SHADERS_PACK_GLSL
 #define ANKI_SHADERS_PACK_GLSL
 
-#pragma anki include "shaders/Common.glsl"
+#include "shaders/Common.glsl"
 
 /// Pack 3D normal to 2D vector
 /// See the clean code in comments in revision < r467

+ 3 - 4
shaders/Pps.frag.glsl

@@ -3,10 +3,9 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
-#pragma anki type frag
-#pragma anki include "shaders/Common.glsl"
-#pragma anki include "shaders/Tonemapping.glsl"
-#pragma anki include "shaders/LinearDepth.glsl"
+#include "shaders/Common.glsl"
+#include "shaders/Tonemapping.glsl"
+#include "shaders/LinearDepth.glsl"
 
 layout(binding = 0) uniform sampler2D u_isRt;
 layout(binding = 1) uniform sampler2D u_ppsSsaoRt;

+ 4 - 5
shaders/PpsBloom.frag.glsl

@@ -3,9 +3,8 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
-#pragma anki type frag
-#pragma anki include "shaders/Common.glsl"
-#pragma anki include "shaders/Tonemapping.glsl"
+#include "shaders/Common.glsl"
+#include "shaders/Tonemapping.glsl"
 
 // Vars
 layout(binding = 0) uniform lowp sampler2D u_tex; ///< Its the IS RT
@@ -45,8 +44,8 @@ void main()
 	out_color = readTexture(MIPMAP);
 	out_color += readTexture(MIPMAP - 1);
 	out_color += readTexture(MIPMAP - 2);
-	
+
 	out_color /= 3.0;
-	out_color = tonemap(out_color, u_averageLuminancePad3.x, 
+	out_color = tonemap(out_color, u_averageLuminancePad3.x,
 		u_thresholdScalePad2.x) * u_thresholdScalePad2.y;
 }

+ 3 - 4
shaders/PpsSsao.frag.glsl

@@ -4,10 +4,9 @@
 // http://www.anki3d.org/LICENSE
 
 // SSAO fragment shader
-#pragma anki type frag
-#pragma anki include "shaders/Common.glsl"
-#pragma anki include "shaders/Pack.glsl"
-#pragma anki include "shaders/LinearDepth.glsl"
+#include "shaders/Common.glsl"
+#include "shaders/Pack.glsl"
+#include "shaders/LinearDepth.glsl"
 
 const vec3 KERNEL[KERNEL_SIZE] = KERNEL_ARRAY; // This will be appended in C++
 

+ 1 - 2
shaders/PpsSslf.frag.glsl

@@ -6,8 +6,7 @@
 // Screen space lens flare. Used the technique from here
 // http://john-chapman-graphics.blogspot.no/2013/02/pseudo-lens-flare.html
 
-#pragma anki type frag
-#pragma anki include "shaders/Common.glsl"
+#include "shaders/Common.glsl"
 
 #define MAX_GHOSTS 4
 #define GHOST_DISPERSAL (0.7)

+ 2 - 3
shaders/PpsTmAverageLuminance.comp.glsl

@@ -3,9 +3,8 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
-#pragma anki type comp
-#pragma anki include "shaders/Common.glsl"
-#pragma anki include "shaders/Tonemapping.glsl"
+#include "shaders/Common.glsl"
+#include "shaders/Tonemapping.glsl"
 
 #if IS_RT_MIPMAP == 0
 #	error Wrong mipmap

+ 1 - 2
shaders/Quad.vert.glsl

@@ -3,8 +3,7 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
-#pragma anki type vert
-#pragma anki include "shaders/Common.glsl"
+#include "shaders/Common.glsl"
 
 out gl_PerVertex
 {

+ 3 - 4
shaders/Refl.frag.glsl

@@ -3,8 +3,7 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
-#pragma anki type frag
-#pragma anki include "shaders/Pack.glsl"
+#include "shaders/Pack.glsl"
 
 // Common
 layout(TEX_BINDING(0, 0)) uniform sampler2D u_depthRt;
@@ -21,7 +20,7 @@ layout(std140, UBO_BINDING(0, 0)) uniform u0_
 #define IMAGE_REFLECTIONS_SET 0
 #define IMAGE_REFLECTIONS_FIRST_SS_BINDING 0
 #define IMAGE_REFLECTIONS_TEX_BINDING 4
-#pragma anki include "shaders/ImageReflections.glsl"
+#include "shaders/ImageReflections.glsl"
 #undef IMAGE_REFLECTIONS_SET
 #undef IMAGE_REFLECTIONS_FIRST_SS_BINDING
 #endif
@@ -30,7 +29,7 @@ layout(std140, UBO_BINDING(0, 0)) uniform u0_
 #if SSLR_ENABLED
 layout(TEX_BINDING(0, 3)) uniform sampler2D u_isRt;
 
-#pragma anki include "shaders/Sslr.glsl"
+#include "shaders/Sslr.glsl"
 #endif
 
 // In/out

+ 3 - 3
shaders/Sslr.glsl

@@ -4,9 +4,9 @@
 // http://www.anki3d.org/LICENSE
 
 // SSLR functions and data
-#pragma anki include "shaders/Common.glsl"
-#pragma anki include "shaders/LinearDepth.glsl"
-#pragma anki include "shaders/Pack.glsl"
+#include "shaders/Common.glsl"
+#include "shaders/LinearDepth.glsl"
+#include "shaders/Pack.glsl"
 
 const float ONE = 0.9;
 

+ 1 - 2
shaders/TilerMinMax.comp.glsl

@@ -3,8 +3,7 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
-#pragma anki type comp
-#pragma anki include "shaders/Common.glsl"
+#include "shaders/Common.glsl"
 
 const uint U32_MAX = 0xFFFFFFFFU;
 

+ 1 - 1
shaders/Tonemapping.glsl

@@ -6,7 +6,7 @@
 #ifndef ANKI_SHADERS_TONEMAP_GLSL
 #define ANKI_SHADERS_TONEMAP_GLSL
 
-#pragma anki include "shaders/Common.glsl"
+#include "shaders/Common.glsl"
 
 // A tick to compute log of base 10
 float log10(in float x)

+ 1 - 2
shaders/UiLines.frag.glsl

@@ -3,8 +3,7 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
-#pragma anki type frag
-#pragma anki include "shaders/Common.glsl"
+#include "shaders/Common.glsl"
 
 layout(location = 0) in mediump vec4 in_color;
 

+ 1 - 2
shaders/UiLines.vert.glsl

@@ -3,8 +3,7 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
-#pragma anki type vert
-#pragma anki include "shaders/Common.glsl"
+#include "shaders/Common.glsl"
 
 out gl_PerVertex
 {

+ 1 - 3
shaders/VariableSamplingBlurGeneric.frag.glsl

@@ -9,9 +9,7 @@
 /// - SAMPLES is a number of 3 or 5 or 7 or 9
 /// - BLURRING_DIST is optional and it's extra pixels to move the blurring
 
-#pragma anki type frag
-
-#pragma anki include "shaders/Common.glsl"
+#include "shaders/Common.glsl"
 
 // Preprocessor switches sanity checks
 #if !defined(VPASS) && !defined(HPASS)

+ 65 - 0
src/resource/Common.cpp

@@ -0,0 +1,65 @@
+// Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <anki/resource/Common.h>
+
+namespace anki
+{
+
+//==============================================================================
+static const Array<CString, U(ShaderType::COUNT)> mapping = {{".vert.glsl",
+	".tc.glsl",
+	".te.glsl",
+	".geom.glsl",
+	".frag.glsl",
+	".comp.glsl"}};
+
+//==============================================================================
+const CString& shaderTypeToFileExtension(ShaderType type)
+{
+	return mapping[type];
+}
+
+//==============================================================================
+Error fileExtensionToShaderType(const CString& filename, ShaderType& type)
+{
+	type = ShaderType::COUNT;
+	Error err = ErrorCode::NONE;
+
+	// Find the shader type
+	if(filename.find(".vert.glsl") != ResourceFilename::NPOS)
+	{
+		type = ShaderType::VERTEX;
+	}
+	else if(filename.find(".tc.glsl") != ResourceFilename::NPOS)
+	{
+		type = ShaderType::TESSELLATION_CONTROL;
+	}
+	else if(filename.find(".te.glsl") != ResourceFilename::NPOS)
+	{
+		type = ShaderType::TESSELLATION_EVALUATION;
+	}
+	else if(filename.find(".geom.glsl") != ResourceFilename::NPOS)
+	{
+		type = ShaderType::GEOMETRY;
+	}
+	else if(filename.find(".frag.glsl") != ResourceFilename::NPOS)
+	{
+		type = ShaderType::FRAGMENT;
+	}
+	else if(filename.find(".comp.glsl") != ResourceFilename::NPOS)
+	{
+		type = ShaderType::COMPUTE;
+	}
+	else
+	{
+		ANKI_LOGE("Wrong shader file format: %s", &filename[0]);
+		err = ErrorCode::USER_DATA;
+	}
+
+	return err;
+}
+
+} // end namespace anki

+ 3 - 3
src/resource/Material.cpp

@@ -215,7 +215,7 @@ Error MaterialVariant::init(
 		const String& src = loader.getShaderSource(stype);
 
 		StringAuto filename(mtl.getTempAllocator());
-		ANKI_CHECK(mtl.createProgramSourceToCache(src, filename));
+		ANKI_CHECK(mtl.createProgramSourceToCache(src, stype, filename));
 
 		ShaderResourcePtr& shader = m_shaders[U(stype)];
 
@@ -411,7 +411,7 @@ Error Material::createVariants(MaterialLoader& loader)
 
 //==============================================================================
 Error Material::createProgramSourceToCache(
-	const String& source, StringAuto& out)
+	const String& source, ShaderType type, StringAuto& out)
 {
 	auto alloc = getTempAllocator();
 
@@ -419,7 +419,7 @@ Error Material::createProgramSourceToCache(
 	U64 h = computeHash(&source[0], source.getLength());
 
 	// Create out
-	out.sprintf("mtl_%llu.glsl", h);
+	out.sprintf("mtl_%llu%s", h, &shaderTypeToFileExtension(type)[0]);
 
 	// Create path
 	StringAuto fullFname(alloc);

+ 2 - 3
src/resource/MaterialLoader.cpp

@@ -405,7 +405,6 @@ Error MaterialLoader::parseProgramTag(const XmlElement& programEl)
 	ANKI_CHECK(getShaderInfo(type, glshader, glshaderbit, shaderidx));
 
 	auto& lines = m_source[shaderidx];
-	lines.pushBackSprintf(m_alloc, "#pragma anki type %s", &type[0]);
 
 	if(glshader == ShaderType::TESSELLATION_CONTROL
 		|| glshader == ShaderType::TESSELLATION_EVALUATION)
@@ -434,7 +433,7 @@ Error MaterialLoader::parseProgramTag(const XmlElement& programEl)
 	{
 		CString tmp;
 		ANKI_CHECK(includeEl.getText(tmp));
-		lines.pushBackSprintf(m_alloc, "#pragma anki include \"%s\"", &tmp[0]);
+		lines.pushBackSprintf(m_alloc, "#include \"%s\"", &tmp[0]);
 
 		ANKI_CHECK(includeEl.getNextSiblingElement("include", includeEl));
 	} while(includeEl);
@@ -446,7 +445,7 @@ Error MaterialLoader::parseProgramTag(const XmlElement& programEl)
 	{
 		lines.pushBackSprintf(m_alloc,
 			"\nlayout(UBO_BINDING(0, 0), std140, row_major) "
-			"uniform _ublk00\n{");
+			"uniform u00_\n{");
 
 		for(Input& in : m_inputs)
 		{

+ 0 - 170
src/resource/ProgramPrePreprocessor.cpp

@@ -1,170 +0,0 @@
-// Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include <anki/resource/ProgramPrePreprocessor.h>
-#include <anki/resource/ResourceManager.h>
-#include <anki/resource/ResourceFilesystem.h>
-#include <anki/util/Functions.h>
-#include <anki/util/File.h>
-#include <anki/util/Array.h>
-#include <iomanip>
-#include <cstring>
-
-namespace anki
-{
-
-//==============================================================================
-// Keep the strings in that order so that the start pragmas will match to the
-// ShaderType enums
-static Array<const char*, 7> commands = {{"#pragma anki type vert",
-	"#pragma anki type tesc",
-	"#pragma anki type tese",
-	"#pragma anki type geom",
-	"#pragma anki type frag",
-	"#pragma anki type comp",
-	"#pragma anki include \""}};
-
-const U32 MAX_DEPTH = 8;
-
-//==============================================================================
-void ProgramPrePreprocessor::printSourceLines() const
-{
-	U i = 1;
-	auto it = m_sourceLines.getBegin();
-	auto end = m_sourceLines.getEnd();
-	for(; it != end; ++it)
-	{
-		printf("%4d %s\n", int(i++), &(*it)[0]);
-	}
-}
-
-//==============================================================================
-Error ProgramPrePreprocessor::parseFile(const ResourceFilename& filename)
-{
-	// Parse files recursively
-	Error err = parseFileForPragmas(filename, 0);
-
-	if(!err)
-	{
-		m_sourceLines.join(m_alloc, "\n", m_shaderSource);
-	}
-
-	return err;
-}
-
-//==============================================================================
-Error ProgramPrePreprocessor::parseFileForPragmas(
-	ResourceFilename filename, U32 depth)
-{
-	// first check the depth
-	if(depth > MAX_DEPTH)
-	{
-		ANKI_LOGE("The include depth is too high. "
-				  "Probably circular includance");
-		return ErrorCode::USER_DATA;
-	}
-
-	// load file in lines
-	StringAuto txt(m_alloc);
-	StringListAuto lines(m_alloc);
-
-	ResourceFilePtr file;
-	ANKI_CHECK(m_manager->getFilesystem().openFile(filename, file));
-	ANKI_CHECK(file->readAllText(TempResourceAllocator<char>(m_alloc), txt));
-	lines.splitString(txt.toCString(), '\n');
-	if(lines.getSize() < 1)
-	{
-		ANKI_LOGE("File is empty: %s", &filename[0]);
-		return ErrorCode::USER_DATA;
-	}
-
-	for(const String& line : lines)
-	{
-		PtrSize npos = 0;
-
-		if(line.find("#pragma anki") == 0)
-		{
-			Bool malformed = true;
-
-			Bool found;
-			ANKI_CHECK(parseType(line, found));
-			if(found)
-			{
-				malformed = false; // All OK
-			}
-			else if((npos = line.find(commands[6])) == 0)
-			{
-				// Include
-
-				if(line.getLength() >= std::strlen(commands[6]) + 2)
-				{
-					StringAuto filen(m_alloc);
-
-					filen.create(line.begin() + std::strlen(commands[6]),
-						line.end() - 1);
-
-					StringAuto filenFixed(m_alloc);
-
-					ANKI_CHECK(
-						parseFileForPragmas(filen.toCString(), depth + 1));
-
-					malformed = false; // All OK
-				}
-			}
-
-			if(malformed)
-			{
-				ANKI_LOGE("Malformed pragma anki: %s", &line[0]);
-				return ErrorCode::USER_DATA;
-			}
-		}
-		else
-		{
-			m_sourceLines.pushBackSprintf(m_alloc, "%s", &line[0]);
-		}
-	}
-
-	// Sanity checks
-	if(m_type == ShaderType::COUNT)
-	{
-		ANKI_LOGE("Shader is missing the type");
-		return ErrorCode::USER_DATA;
-	}
-
-	return ErrorCode::NONE;
-}
-
-//==============================================================================
-Error ProgramPrePreprocessor::parseType(const String& line, Bool& found)
-{
-	U i;
-	found = false;
-
-	for(i = 0; i < static_cast<U>(ShaderType::COUNT); i++)
-	{
-		if(line.find(commands[i]) == 0)
-		{
-			found = true;
-			break;
-		}
-	}
-
-	if(found)
-	{
-		if(m_type != ShaderType::COUNT)
-		{
-			ANKI_LOGE("The shader type is already set. Line %s", &line[0]);
-			return ErrorCode::USER_DATA;
-		}
-		else
-		{
-			m_type = static_cast<ShaderType>(i);
-		}
-	}
-
-	return ErrorCode::NONE;
-}
-
-} // end namespace anki

+ 107 - 0
src/resource/ShaderLoader.cpp

@@ -0,0 +1,107 @@
+// Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <anki/resource/ShaderLoader.h>
+#include <anki/resource/ResourceManager.h>
+#include <anki/resource/ResourceFilesystem.h>
+#include <anki/util/Functions.h>
+#include <anki/util/File.h>
+#include <anki/util/Array.h>
+#include <iomanip>
+#include <cstring>
+
+namespace anki
+{
+
+//==============================================================================
+
+const U32 MAX_INCLUDE_DEPTH = 8;
+
+//==============================================================================
+void ShaderLoader::printSourceLines() const
+{
+	U i = 1;
+	auto it = m_sourceLines.getBegin();
+	auto end = m_sourceLines.getEnd();
+	for(; it != end; ++it)
+	{
+		printf("%4d %s\n", int(i++), &(*it)[0]);
+	}
+}
+
+//==============================================================================
+Error ShaderLoader::parseFile(const ResourceFilename& filename)
+{
+	// Find the shader type
+	ANKI_CHECK(fileExtensionToShaderType(filename, m_type));
+
+	// Parse files recursively
+	Error err = parseFileIncludes(filename, 0);
+
+	if(!err)
+	{
+		m_sourceLines.join(m_alloc, "\n", m_shaderSource);
+	}
+
+	return err;
+}
+
+//==============================================================================
+Error ShaderLoader::parseFileIncludes(ResourceFilename filename, U32 depth)
+{
+	// first check the depth
+	if(depth > MAX_INCLUDE_DEPTH)
+	{
+		ANKI_LOGE("The include depth is too high. "
+				  "Probably circular includance");
+		return ErrorCode::USER_DATA;
+	}
+
+	// load file in lines
+	StringAuto txt(m_alloc);
+	StringListAuto lines(m_alloc);
+
+	ResourceFilePtr file;
+	ANKI_CHECK(m_manager->getFilesystem().openFile(filename, file));
+	ANKI_CHECK(file->readAllText(TempResourceAllocator<char>(m_alloc), txt));
+	lines.splitString(txt.toCString(), '\n');
+	if(lines.getSize() < 1)
+	{
+		ANKI_LOGE("File is empty: %s", &filename[0]);
+		return ErrorCode::USER_DATA;
+	}
+
+	for(const String& line : lines)
+	{
+		static const CString token = "#include \"";
+
+		if(line.find(token) == 0)
+		{
+			// - Expect something between the quotes
+			// - Expect the last char to be a quote
+			if(line.getLength() >= token.getLength() + 2
+				&& line[line.getLength() - 1] == '\"')
+			{
+				StringAuto filen(m_alloc);
+				filen.create(line.begin() + token.getLength(), line.end() - 1);
+
+				ANKI_CHECK(parseFileIncludes(filen.toCString(), depth + 1));
+			}
+			else
+			{
+				ANKI_LOGE("Malformed #include: %s", &line[0]);
+				return ErrorCode::USER_DATA;
+			}
+		}
+		else
+		{
+			m_sourceLines.pushBackSprintf(m_alloc, "%s", &line[0]);
+		}
+	}
+
+	return ErrorCode::NONE;
+}
+
+} // end namespace anki

+ 8 - 3
src/resource/ShaderResource.cpp

@@ -4,7 +4,7 @@
 // http://www.anki3d.org/LICENSE
 
 #include <anki/resource/ShaderResource.h>
-#include <anki/resource/ProgramPrePreprocessor.h>
+#include <anki/resource/ShaderLoader.h>
 #include <anki/resource/ResourceManager.h>
 #include <anki/core/App.h> // To get cache dir
 #include <anki/util/File.h>
@@ -38,7 +38,7 @@ Error ShaderResource::load(
 {
 	auto alloc = getTempAllocator();
 
-	ProgramPrePreprocessor pars(&getManager());
+	ShaderLoader pars(&getManager());
 	ANKI_CHECK(pars.parseFile(filename));
 
 	// Allocate new source
@@ -91,7 +91,12 @@ Error ShaderResource::createToCache(const ResourceFilename& filename,
 
 	// Create out
 	out = StringAuto(alloc);
-	out.sprintf("%s%s.glsl", &filenamePrefix[0], &suffix[0]);
+	ShaderType inShaderType;
+	ANKI_CHECK(fileExtensionToShaderType(filename, inShaderType));
+	out.sprintf("%s%s%s",
+		&filenamePrefix[0],
+		&suffix[0],
+		&shaderTypeToFileExtension(inShaderType)[0]);
 
 	// Compose cached filename
 	StringAuto newFilename(alloc);