Jelajahi Sumber

Refactor ShaderVariableDataType

Panagiotis Christopoulos Charitos 5 tahun lalu
induk
melakukan
edc473e308

+ 44 - 6
shaders/RtShadows.ankiprog

@@ -3,7 +3,7 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
-#pragma anki mutator DIFFUSE_TEXTURE 0 1
+#pragma anki mutator ALPHA_TEXTURE 0 1
 
 #include <shaders/Common.glsl>
 #include <shaders/glsl_cpp_common/Model.h>
@@ -13,16 +13,54 @@ struct Payload
 	F32 m_shadowFactor;
 };
 
-layout(location = 0) rayPayloadInEXT Payload p_payload;
+#if defined(ALPHA_TEXTURE)
+layout(set = 0, binding = 0, scalar) buffer b_ankiModelInstances
+{
+	ModelInstance u_ankiModelInstances[];
+};
 
-#pragma anki start ahit
+layout(set = 0, binding = 1) uniform texture2D u_diffTex;
+layout(set = 0, binding = 2) uniform sampler u_ankiGlobalSampler;
 
-#if defined(DIFFUSE_TEXTURE)
-layout(set = 0, binding = 0) uniform texture2D u_diffTex;
-layout(set = 0, binding = 1) uniform sampler u_ankiGlobalSampler;
+ANKI_BINDLESS_SET(1);
 #endif
 
+#pragma anki start ahit
+
+layout(location = 0) rayPayloadInEXT Payload p_payload;
+
+hitAttributeEXT vec2 g_attribs;
+
+ANKI_REF(U16Vec3, 2);
+ANKI_REF(Vertex, 4);
+
 void main()
 {
+#if defined(ALPHA_TEXTURE)
+	const Mesh mesh = u_ankiModelInstances[nonuniformEXT(gl_InstanceID)].m_mesh;
+
+	const U32 offset = gl_PrimitiveID * ANKI_SIZEOF(U16Vec3);
+	const U16Vec3 indices = U16Vec3Ref(nonuniformEXT(mesh.m_indexBufferPtr + offset)).m_value;
+
+	const Vertex vert0 = VertexRef(mesh.m_vertexBufferPtr + indices[0] * SIZEOF_VERTEX).m_value;
+	const Vertex vert1 = VertexRef(mesh.m_vertexBufferPtr + indices[1] * SIZEOF_VERTEX).m_value;
+	const Vertex vert2 = VertexRef(mesh.m_vertexBufferPtr + indices[2] * SIZEOF_VERTEX).m_value;
+
+	const Vec3 barycentrics = Vec3(1.0f - g_attribs.x - g_attribs.y, g_attribs.x, g_attribs.y);
+
+	const Vec2 uv = vert0.m_uvs[0] * barycentrics.x + vert1.m_uvs[0] * barycentrics.y + vert2.m_uvs[0] * barycentrics.z;
+
+	const F32 alpha = textureLod(u_diffTex, u_ankiGlobalSampler, uv, 2).a;
+
+	p_payload.m_shadowFactor += alpha;
+
+	if(p_payload.m_shadowFactor >= 1.0)
+	{
+		terminateRayEXT();
+	}
+#else
+	p_payload.m_shadowFactor = 1.0;
+	terminateRayEXT();
+#endif
 }
 #pragma anki end

+ 3 - 1
shaders/glsl_cpp_common/Model.h

@@ -15,9 +15,11 @@ struct Vertex
 {
 	U32 m_normal; // Packed in R10G10B10A2SNorm
 	U32 m_tangent; // Packed in R10G10B10A2SNorm
-	F16 m_uvs[UV_CHANNEL_COUNT];
+	HVec2 m_uvs[UV_CHANNEL_COUNT];
 };
 
+const U32 SIZEOF_VERTEX = 4 * 4;
+
 struct Mesh
 {
 	U64 m_indexBufferPtr; // Points to a buffer of U16

+ 6 - 6
src/anki/gr/Enums.h

@@ -494,19 +494,19 @@ enum class ShaderVariableDataType : U8
 {
 	NONE,
 
-#define ANKI_SVDT_MACRO(x, y) x,
-#define ANKI_SVDT_MACRO_2(x, y) x,
+#define ANKI_SVDT_MACRO(capital, type, baseType, rowCount, columnCount) capital,
+#define ANKI_SVDT_MACRO_OPAQUE(capital, type) capital,
 #include <anki/gr/ShaderVariableDataTypeDefs.h>
 #undef ANKI_SVDT_MACRO
-#undef ANKI_SVDT_MACRO_2
+#undef ANKI_SVDT_MACRO_OPAQUE
 
 	// Derived
 
-	NUMERICS_FIRST = INT,
+	NUMERICS_FIRST = I32,
 	NUMERICS_LAST = MAT4,
 
-	NUMERIC_1_COMPONENT_FIRST = INT,
-	NUMERIC_1_COMPONENT_LAST = FLOAT,
+	NUMERIC_1_COMPONENT_FIRST = I32,
+	NUMERIC_1_COMPONENT_LAST = F32,
 	NUMERIC_2_COMPONENT_FIRST = IVEC2,
 	NUMERIC_2_COMPONENT_LAST = VEC2,
 	NUMERIC_3_COMPONENT_FIRST = IVEC3,

+ 3 - 3
src/anki/gr/Shader.h

@@ -37,19 +37,19 @@ public:
 
 	explicit ShaderSpecializationConstValue(F32 f)
 		: m_float(f)
-		, m_dataType(ShaderVariableDataType::FLOAT)
+		, m_dataType(ShaderVariableDataType::F32)
 	{
 	}
 
 	explicit ShaderSpecializationConstValue(I32 i)
 		: m_int(i)
-		, m_dataType(ShaderVariableDataType::INT)
+		, m_dataType(ShaderVariableDataType::I32)
 	{
 	}
 
 	explicit ShaderSpecializationConstValue(U32 i)
 		: m_int(i)
-		, m_dataType(ShaderVariableDataType::UINT)
+		, m_dataType(ShaderVariableDataType::U32)
 	{
 	}
 

+ 34 - 33
src/anki/gr/ShaderVariableDataTypeDefs.h

@@ -5,44 +5,45 @@
 
 // ShaderVariableDataType defines
 
+// ANKI_SVDT_MACRO(capital, varType, baseType, rowCount, columnCount)
 #if defined(ANKI_SVDT_MACRO)
-ANKI_SVDT_MACRO(INT, I32)
-ANKI_SVDT_MACRO(UINT, U32)
-ANKI_SVDT_MACRO(FLOAT, F32)
+ANKI_SVDT_MACRO(I32, I32, I32, 1, 1)
+ANKI_SVDT_MACRO(U32, U32, U32, 1, 1)
+ANKI_SVDT_MACRO(F32, F32, F32, 1, 1)
 
-ANKI_SVDT_MACRO(IVEC2, IVec2)
-ANKI_SVDT_MACRO(UVEC2, UVec2)
-ANKI_SVDT_MACRO(VEC2, Vec2)
+ANKI_SVDT_MACRO(IVEC2, IVec2, I32, 2, 1)
+ANKI_SVDT_MACRO(UVEC2, UVec2, U32, 2, 1)
+ANKI_SVDT_MACRO(VEC2, Vec2, F32, 2, 1)
 
-ANKI_SVDT_MACRO(IVEC3, IVec3)
-ANKI_SVDT_MACRO(UVEC3, UVec3)
-ANKI_SVDT_MACRO(VEC3, Vec3)
+ANKI_SVDT_MACRO(IVEC3, IVec3, I32, 3, 1)
+ANKI_SVDT_MACRO(UVEC3, UVec3, U32, 3, 1)
+ANKI_SVDT_MACRO(VEC3, Vec3, F32, 3, 1)
 
-ANKI_SVDT_MACRO(IVEC4, IVec4)
-ANKI_SVDT_MACRO(UVEC4, UVec4)
-ANKI_SVDT_MACRO(VEC4, Vec4)
+ANKI_SVDT_MACRO(IVEC4, IVec4, I32, 4, 1)
+ANKI_SVDT_MACRO(UVEC4, UVec4, U32, 4, 1)
+ANKI_SVDT_MACRO(VEC4, Vec4, F32, 4, 1)
 
-ANKI_SVDT_MACRO(MAT3, Mat3)
-ANKI_SVDT_MACRO(MAT3X4, Mat3x4)
-ANKI_SVDT_MACRO(MAT4, Mat4)
+ANKI_SVDT_MACRO(MAT3, Mat3, F32, 3, 3)
+ANKI_SVDT_MACRO(MAT3X4, Mat3x4, F32, 3, 4)
+ANKI_SVDT_MACRO(MAT4, Mat4, F32, 4, 4)
 #endif
 
-#if defined(ANKI_SVDT_MACRO_2)
-ANKI_SVDT_MACRO_2(TEXTURE_1D, texture1D)
-ANKI_SVDT_MACRO_2(TEXTURE_1D_ARRAY, texture1DArray)
-ANKI_SVDT_MACRO_2(TEXTURE_2D, texture2D)
-ANKI_SVDT_MACRO_2(TEXTURE_2D_ARRAY, texture2DArray)
-ANKI_SVDT_MACRO_2(TEXTURE_3D, texture3D)
-ANKI_SVDT_MACRO_2(TEXTURE_CUBE, textureCube)
-ANKI_SVDT_MACRO_2(TEXTURE_CUBE_ARRAY, textureCubeArray)
-
-ANKI_SVDT_MACRO_2(IMAGE_1D, image1D)
-ANKI_SVDT_MACRO_2(IMAGE_1D_ARRAY, image1DArray)
-ANKI_SVDT_MACRO_2(IMAGE_2D, image2D)
-ANKI_SVDT_MACRO_2(IMAGE_2D_ARRAY, image2DArray)
-ANKI_SVDT_MACRO_2(IMAGE_3D, image3D)
-ANKI_SVDT_MACRO_2(IMAGE_CUBE, imageCube)
-ANKI_SVDT_MACRO_2(IMAGE_CUBE_ARRAY, imageCubeArray)
-
-ANKI_SVDT_MACRO_2(SAMPLER, sampler)
+#if defined(ANKI_SVDT_MACRO_OPAQUE)
+ANKI_SVDT_MACRO_OPAQUE(TEXTURE_1D, texture1D)
+ANKI_SVDT_MACRO_OPAQUE(TEXTURE_1D_ARRAY, texture1DArray)
+ANKI_SVDT_MACRO_OPAQUE(TEXTURE_2D, texture2D)
+ANKI_SVDT_MACRO_OPAQUE(TEXTURE_2D_ARRAY, texture2DArray)
+ANKI_SVDT_MACRO_OPAQUE(TEXTURE_3D, texture3D)
+ANKI_SVDT_MACRO_OPAQUE(TEXTURE_CUBE, textureCube)
+ANKI_SVDT_MACRO_OPAQUE(TEXTURE_CUBE_ARRAY, textureCubeArray)
+
+ANKI_SVDT_MACRO_OPAQUE(IMAGE_1D, image1D)
+ANKI_SVDT_MACRO_OPAQUE(IMAGE_1D_ARRAY, image1DArray)
+ANKI_SVDT_MACRO_OPAQUE(IMAGE_2D, image2D)
+ANKI_SVDT_MACRO_OPAQUE(IMAGE_2D_ARRAY, image2DArray)
+ANKI_SVDT_MACRO_OPAQUE(IMAGE_3D, image3D)
+ANKI_SVDT_MACRO_OPAQUE(IMAGE_CUBE, imageCube)
+ANKI_SVDT_MACRO_OPAQUE(IMAGE_CUBE_ARRAY, imageCubeArray)
+
+ANKI_SVDT_MACRO_OPAQUE(SAMPLER, sampler)
 #endif

+ 60 - 50
src/anki/gr/utils/Functions.cpp

@@ -76,53 +76,64 @@ static void writeShaderBlockMemoryMatrix(const ShaderVariableBlockInfo& varBlkIn
 	}
 }
 
+// This is some trickery to select calling between writeShaderBlockMemoryMatrix and writeShaderBlockMemorySimple
+namespace
+{
+
+template<typename T>
+class IsShaderVarDataTypeAMatrix
+{
+public:
+	static constexpr Bool VALUE = false;
+};
+
+#define ANKI_SVDT_MACRO(capital, type, baseType, rowCount, columnCount) \
+	template<> \
+	class IsShaderVarDataTypeAMatrix<type> \
+	{ \
+	public: \
+		static constexpr Bool VALUE = rowCount * columnCount > 4; \
+	};
+#include <anki/gr/ShaderVariableDataTypeDefs.h>
+#undef ANKI_SVDT_MACRO
+
+template<typename T, Bool isMatrix = IsShaderVarDataTypeAMatrix<T>::VALUE>
+class WriteShaderBlockMemory
+{
+public:
+	void operator()(const ShaderVariableBlockInfo& varBlkInfo, const void* elements, U32 elementsCount, void* buffBegin,
+					const void* buffEnd)
+	{
+		using RowVec = typename T::RowVec;
+		writeShaderBlockMemoryMatrix<T, RowVec>(varBlkInfo, elements, elementsCount, buffBegin, buffEnd);
+	}
+};
+
+template<typename T>
+class WriteShaderBlockMemory<T, false>
+{
+public:
+	void operator()(const ShaderVariableBlockInfo& varBlkInfo, const void* elements, U32 elementsCount, void* buffBegin,
+					const void* buffEnd)
+	{
+		writeShaderBlockMemorySimple<T>(varBlkInfo, elements, elementsCount, buffBegin, buffEnd);
+	}
+};
+
+} // namespace
+
 void writeShaderBlockMemory(ShaderVariableDataType type, const ShaderVariableBlockInfo& varBlkInfo,
 							const void* elements, U32 elementsCount, void* buffBegin, const void* buffEnd)
 {
 	switch(type)
 	{
-	case ShaderVariableDataType::INT:
-		writeShaderBlockMemorySimple<I32>(varBlkInfo, elements, elementsCount, buffBegin, buffEnd);
-		break;
-	case ShaderVariableDataType::UINT:
-		writeShaderBlockMemorySimple<U32>(varBlkInfo, elements, elementsCount, buffBegin, buffEnd);
-		break;
-	case ShaderVariableDataType::FLOAT:
-		writeShaderBlockMemorySimple<F32>(varBlkInfo, elements, elementsCount, buffBegin, buffEnd);
-		break;
-	case ShaderVariableDataType::IVEC2:
-		writeShaderBlockMemorySimple<IVec2>(varBlkInfo, elements, elementsCount, buffBegin, buffEnd);
-		break;
-	case ShaderVariableDataType::UVEC2:
-		writeShaderBlockMemorySimple<UVec2>(varBlkInfo, elements, elementsCount, buffBegin, buffEnd);
-		break;
-	case ShaderVariableDataType::VEC2:
-		writeShaderBlockMemorySimple<Vec2>(varBlkInfo, elements, elementsCount, buffBegin, buffEnd);
-		break;
-	case ShaderVariableDataType::IVEC3:
-		writeShaderBlockMemorySimple<IVec3>(varBlkInfo, elements, elementsCount, buffBegin, buffEnd);
-		break;
-	case ShaderVariableDataType::UVEC3:
-		writeShaderBlockMemorySimple<UVec3>(varBlkInfo, elements, elementsCount, buffBegin, buffEnd);
-		break;
-	case ShaderVariableDataType::VEC3:
-		writeShaderBlockMemorySimple<Vec3>(varBlkInfo, elements, elementsCount, buffBegin, buffEnd);
-		break;
-	case ShaderVariableDataType::IVEC4:
-		writeShaderBlockMemorySimple<IVec4>(varBlkInfo, elements, elementsCount, buffBegin, buffEnd);
-		break;
-	case ShaderVariableDataType::UVEC4:
-		writeShaderBlockMemorySimple<UVec4>(varBlkInfo, elements, elementsCount, buffBegin, buffEnd);
-		break;
-	case ShaderVariableDataType::VEC4:
-		writeShaderBlockMemorySimple<Vec4>(varBlkInfo, elements, elementsCount, buffBegin, buffEnd);
-		break;
-	case ShaderVariableDataType::MAT3:
-		writeShaderBlockMemoryMatrix<Mat3, Vec3>(varBlkInfo, elements, elementsCount, buffBegin, buffEnd);
-		break;
-	case ShaderVariableDataType::MAT4:
-		writeShaderBlockMemoryMatrix<Mat4, Vec4>(varBlkInfo, elements, elementsCount, buffBegin, buffEnd);
+#define ANKI_SVDT_MACRO(capital, type, baseType, rowCount, columnCount) \
+	case ShaderVariableDataType::capital: \
+		WriteShaderBlockMemory<type>()(varBlkInfo, elements, elementsCount, buffBegin, buffEnd); \
 		break;
+#include <anki/gr/ShaderVariableDataTypeDefs.h>
+#undef ANKI_SVDT_MACRO
+
 	default:
 		ANKI_ASSERT(0);
 	}
@@ -130,24 +141,23 @@ void writeShaderBlockMemory(ShaderVariableDataType type, const ShaderVariableBlo
 
 const CString shaderVariableDataTypeToString(ShaderVariableDataType t)
 {
-#define ANKI_SVDT_MACRO(svdt, akType) \
-	case ShaderVariableDataType::svdt: \
-		return ANKI_STRINGIZE(akType);
-
-#define ANKI_SVDT_MACRO_2(svdt, akType) ANKI_SVDT_MACRO(svdt, akType)
-
 	switch(t)
 	{
 	case ShaderVariableDataType::NONE:
 		return "NONE";
+
+#define ANKI_SVDT_MACRO(capital, type, baseType, rowCount, columnCount) \
+	case ShaderVariableDataType::capital: \
+		return ANKI_STRINGIZE(type);
+#define ANKI_SVDT_MACRO_OPAQUE(capital, type) ANKI_SVDT_MACRO(capital, type, 0, 0, 0)
 #include <anki/gr/ShaderVariableDataTypeDefs.h>
+#undef ANKI_SVDT_MACRO
+#undef ANKI_SVDT_MACRO_OPAQUE
+
 	default:
 		ANKI_ASSERT(0);
 	}
 
-#undef ANKI_SVDT_MACRO
-#undef ANKI_SVDT_MACRO_2
-
 	ANKI_ASSERT(0);
 	return "";
 }

+ 3 - 3
src/anki/gr/utils/Functions.h

@@ -32,11 +32,11 @@ inline Bool blendingDisabled(BlendFactor srcFactorRgb, BlendFactor dstFactorRgb,
 template<typename T>
 ShaderVariableDataType getShaderVariableTypeFromTypename();
 
-#define ANKI_SVDT_MACRO(svdt, akType) \
+#define ANKI_SVDT_MACRO(capital, type, baseType, rowCount, columnCount) \
 	template<> \
-	inline ShaderVariableDataType getShaderVariableTypeFromTypename<akType>() \
+	inline ShaderVariableDataType getShaderVariableTypeFromTypename<type>() \
 	{ \
-		return ShaderVariableDataType::svdt; \
+		return ShaderVariableDataType::capital; \
 	}
 
 #include <anki/gr/ShaderVariableDataTypeDefs.h>

+ 66 - 105
src/anki/resource/MaterialResource.cpp

@@ -79,10 +79,52 @@ static ANKI_USE_RESULT Error checkBuiltin(CString name, ShaderVariableDataType d
 	return Error::NONE;
 }
 
+// This is some trickery to select calling between XmlElement::getAttributeNumber and XmlElement::getAttributeNumbers
+namespace
+{
+
+template<typename T>
+class IsShaderVarDataTypeAnArray
+{
+public:
+	static constexpr Bool VALUE = false;
+};
+
+#define ANKI_SVDT_MACRO(capital, type, baseType, rowCount, columnCount) \
+	template<> \
+	class IsShaderVarDataTypeAnArray<type> \
+	{ \
+	public: \
+		static constexpr Bool VALUE = rowCount * columnCount > 1; \
+	};
+#include <anki/gr/ShaderVariableDataTypeDefs.h>
+#undef ANKI_SVDT_MACRO
+
+template<typename T, Bool isArray = IsShaderVarDataTypeAnArray<T>::VALUE>
+class GetAttribute
+{
+public:
+	Error operator()(const XmlElement& el, T& out)
+	{
+		return el.getAttributeNumbers("value", out);
+	}
+};
+
+template<typename T>
+class GetAttribute<T, false>
+{
+public:
+	Error operator()(const XmlElement& el, T& out)
+	{
+		return el.getAttributeNumber("value", out);
+	}
+};
+
+} // namespace
+
 MaterialVariable::MaterialVariable()
 {
-	m_mat4 = Mat4::getZero();
-	m_mat4(3, 3) = NO_VALUE; // Add a random value
+	m_Mat4 = Mat4::getZero();
 }
 
 MaterialVariable::~MaterialVariable()
@@ -657,7 +699,7 @@ Error MaterialResource::parseInputs(XmlElement inputsEl, Bool async)
 		}
 
 		// A value will be set
-		foundVar->m_mat4(3, 3) = 0.0f;
+		foundVar->m_numericValueIsSet = true;
 
 		// Process var
 		if(foundVar->isConstant())
@@ -666,42 +708,13 @@ Error MaterialResource::parseInputs(XmlElement inputsEl, Bool async)
 
 			switch(foundVar->getDataType())
 			{
-			case ShaderVariableDataType::INT:
-				ANKI_CHECK(inputEl.getAttributeNumber("value", foundVar->m_int));
-				break;
-			case ShaderVariableDataType::IVEC2:
-				ANKI_CHECK(inputEl.getAttributeNumbers("value", foundVar->m_ivec2));
-				break;
-			case ShaderVariableDataType::IVEC3:
-				ANKI_CHECK(inputEl.getAttributeNumbers("value", foundVar->m_ivec3));
-				break;
-			case ShaderVariableDataType::IVEC4:
-				ANKI_CHECK(inputEl.getAttributeNumbers("value", foundVar->m_ivec4));
-				break;
-			case ShaderVariableDataType::UINT:
-				ANKI_CHECK(inputEl.getAttributeNumber("value", foundVar->m_uint));
-				break;
-			case ShaderVariableDataType::UVEC2:
-				ANKI_CHECK(inputEl.getAttributeNumbers("value", foundVar->m_uvec2));
-				break;
-			case ShaderVariableDataType::UVEC3:
-				ANKI_CHECK(inputEl.getAttributeNumbers("value", foundVar->m_uvec3));
-				break;
-			case ShaderVariableDataType::UVEC4:
-				ANKI_CHECK(inputEl.getAttributeNumbers("value", foundVar->m_uvec4));
-				break;
-			case ShaderVariableDataType::FLOAT:
-				ANKI_CHECK(inputEl.getAttributeNumber("value", foundVar->m_float));
-				break;
-			case ShaderVariableDataType::VEC2:
-				ANKI_CHECK(inputEl.getAttributeNumbers("value", foundVar->m_vec2));
-				break;
-			case ShaderVariableDataType::VEC3:
-				ANKI_CHECK(inputEl.getAttributeNumbers("value", foundVar->m_vec3));
-				break;
-			case ShaderVariableDataType::VEC4:
-				ANKI_CHECK(inputEl.getAttributeNumbers("value", foundVar->m_vec4));
-				break;
+#define ANKI_SVDT_MACRO(capital, type, baseType, rowCount, columnCount) \
+	case ShaderVariableDataType::capital: \
+		ANKI_CHECK(GetAttribute<type>()(inputEl, foundVar->ANKI_CONCATENATE(m_, type))); \
+		break;
+#include <anki/gr/ShaderVariableDataTypeDefs.h>
+#undef ANKI_SVDT_MACRO
+
 			default:
 				ANKI_ASSERT(0);
 				break;
@@ -719,48 +732,13 @@ Error MaterialResource::parseInputs(XmlElement inputsEl, Bool async)
 
 			switch(foundVar->getDataType())
 			{
-			case ShaderVariableDataType::INT:
-				ANKI_CHECK(inputEl.getAttributeNumber("value", foundVar->m_int));
-				break;
-			case ShaderVariableDataType::IVEC2:
-				ANKI_CHECK(inputEl.getAttributeNumbers("value", foundVar->m_ivec2));
-				break;
-			case ShaderVariableDataType::IVEC3:
-				ANKI_CHECK(inputEl.getAttributeNumbers("value", foundVar->m_ivec3));
-				break;
-			case ShaderVariableDataType::IVEC4:
-				ANKI_CHECK(inputEl.getAttributeNumbers("value", foundVar->m_ivec4));
-				break;
-			case ShaderVariableDataType::UINT:
-				ANKI_CHECK(inputEl.getAttributeNumber("value", foundVar->m_uint));
-				break;
-			case ShaderVariableDataType::UVEC2:
-				ANKI_CHECK(inputEl.getAttributeNumbers("value", foundVar->m_uvec2));
-				break;
-			case ShaderVariableDataType::UVEC3:
-				ANKI_CHECK(inputEl.getAttributeNumbers("value", foundVar->m_uvec3));
-				break;
-			case ShaderVariableDataType::UVEC4:
-				ANKI_CHECK(inputEl.getAttributeNumbers("value", foundVar->m_uvec4));
-				break;
-			case ShaderVariableDataType::FLOAT:
-				ANKI_CHECK(inputEl.getAttributeNumber("value", foundVar->m_float));
-				break;
-			case ShaderVariableDataType::VEC2:
-				ANKI_CHECK(inputEl.getAttributeNumbers("value", foundVar->m_vec2));
-				break;
-			case ShaderVariableDataType::VEC3:
-				ANKI_CHECK(inputEl.getAttributeNumbers("value", foundVar->m_vec3));
-				break;
-			case ShaderVariableDataType::VEC4:
-				ANKI_CHECK(inputEl.getAttributeNumbers("value", foundVar->m_vec4));
-				break;
-			case ShaderVariableDataType::MAT3:
-				ANKI_CHECK(inputEl.getAttributeNumbers("value", foundVar->m_mat3));
-				break;
-			case ShaderVariableDataType::MAT4:
-				ANKI_CHECK(inputEl.getAttributeNumbers("value", foundVar->m_mat4));
-				break;
+#define ANKI_SVDT_MACRO(capital, type, baseType, rowCount, columnCount) \
+	case ShaderVariableDataType::capital: \
+		ANKI_CHECK(GetAttribute<type>()(inputEl, foundVar->ANKI_CONCATENATE(m_, type))); \
+		break;
+#include <anki/gr/ShaderVariableDataTypeDefs.h>
+#undef ANKI_SVDT_MACRO
+
 			case ShaderVariableDataType::TEXTURE_2D:
 			case ShaderVariableDataType::TEXTURE_2D_ARRAY:
 			case ShaderVariableDataType::TEXTURE_3D:
@@ -867,30 +845,13 @@ const MaterialVariant& MaterialResource::getOrCreateVariant(const RenderingKey&
 
 		switch(var.m_dataType)
 		{
-		case ShaderVariableDataType::INT:
-			initInfo.addConstant(var.getName(), var.getValue<I32>());
-			break;
-		case ShaderVariableDataType::IVEC2:
-			initInfo.addConstant(var.getName(), var.getValue<IVec2>());
-			break;
-		case ShaderVariableDataType::IVEC3:
-			initInfo.addConstant(var.getName(), var.getValue<IVec3>());
-			break;
-		case ShaderVariableDataType::IVEC4:
-			initInfo.addConstant(var.getName(), var.getValue<IVec4>());
-			break;
-		case ShaderVariableDataType::FLOAT:
-			initInfo.addConstant(var.getName(), var.getValue<F32>());
-			break;
-		case ShaderVariableDataType::VEC2:
-			initInfo.addConstant(var.getName(), var.getValue<Vec2>());
-			break;
-		case ShaderVariableDataType::VEC3:
-			initInfo.addConstant(var.getName(), var.getValue<Vec3>());
-			break;
-		case ShaderVariableDataType::VEC4:
-			initInfo.addConstant(var.getName(), var.getValue<Vec4>());
-			break;
+#define ANKI_SVDT_MACRO(capital, type, baseType, rowCount, columnCount) \
+	case ShaderVariableDataType::capital: \
+		initInfo.addConstant(var.getName(), var.getValue<type>()); \
+		break;
+#include <anki/gr/ShaderVariableDataTypeDefs.h>
+#undef ANKI_SVDT_MACRO
+
 		default:
 			ANKI_ASSERT(0);
 		}

+ 13 - 34
src/anki/resource/MaterialResource.h

@@ -82,9 +82,10 @@ public:
 		m_indexInBinary2ndElement = b.m_indexInBinary2ndElement;
 		m_constant = b.m_constant;
 		m_instanced = b.m_instanced;
+		m_numericValueIsSet = b.m_numericValueIsSet;
 		m_dataType = b.m_dataType;
 		m_builtin = b.m_builtin;
-		m_mat4 = b.m_mat4;
+		m_Mat4 = b.m_Mat4;
 		m_tex = std::move(b.m_tex);
 		return *this;
 	}
@@ -141,14 +142,13 @@ public:
 	}
 
 protected:
-	static constexpr F32 NO_VALUE = 1234.5678f;
-
 	String m_name;
 	U32 m_index = MAX_U32;
 	U32 m_indexInBinary = MAX_U32;
 	U32 m_indexInBinary2ndElement = MAX_U32;
 	Bool m_constant = false;
 	Bool m_instanced = false;
+	Bool m_numericValueIsSet = false; ///< The unamed union bellow is set
 	ShaderVariableDataType m_dataType = ShaderVariableDataType::NONE;
 	BuiltinMaterialVariableId m_builtin = BuiltinMaterialVariableId::NONE;
 
@@ -156,20 +156,9 @@ protected:
 	/// @{
 	union
 	{
-		I32 m_int;
-		IVec2 m_ivec2;
-		IVec3 m_ivec3;
-		IVec4 m_ivec4;
-		U32 m_uint;
-		UVec2 m_uvec2;
-		UVec3 m_uvec3;
-		UVec4 m_uvec4;
-		F32 m_float;
-		Vec2 m_vec2;
-		Vec3 m_vec3;
-		Vec4 m_vec4;
-		Mat3 m_mat3;
-		Mat4 m_mat4;
+#define ANKI_SVDT_MACRO(capital, type, baseType, rowCount, columnCount) type ANKI_CONCATENATE(m_, type);
+#include <anki/gr/ShaderVariableDataTypeDefs.h>
+#undef ANKI_SVDT_MACRO
 	};
 
 	TextureResourcePtr m_tex;
@@ -177,7 +166,7 @@ protected:
 
 	Bool valueSetByMaterial() const
 	{
-		return m_tex.isCreated() || m_mat4(3, 3) != NO_VALUE;
+		return m_tex.isCreated() || m_numericValueIsSet;
 	}
 };
 
@@ -191,20 +180,12 @@ protected:
 		return var_; \
 	}
 
-ANKI_SPECIALIZE_GET_VALUE(I32, m_int, INT)
-ANKI_SPECIALIZE_GET_VALUE(IVec2, m_ivec2, IVEC2)
-ANKI_SPECIALIZE_GET_VALUE(IVec3, m_ivec3, IVEC3)
-ANKI_SPECIALIZE_GET_VALUE(IVec4, m_ivec4, IVEC4)
-ANKI_SPECIALIZE_GET_VALUE(U32, m_uint, UINT)
-ANKI_SPECIALIZE_GET_VALUE(UVec2, m_uvec2, UVEC2)
-ANKI_SPECIALIZE_GET_VALUE(UVec3, m_uvec3, UVEC3)
-ANKI_SPECIALIZE_GET_VALUE(UVec4, m_uvec4, UVEC4)
-ANKI_SPECIALIZE_GET_VALUE(F32, m_float, FLOAT)
-ANKI_SPECIALIZE_GET_VALUE(Vec2, m_vec2, VEC2)
-ANKI_SPECIALIZE_GET_VALUE(Vec3, m_vec3, VEC3)
-ANKI_SPECIALIZE_GET_VALUE(Vec4, m_vec4, VEC4)
-ANKI_SPECIALIZE_GET_VALUE(Mat3, m_mat3, MAT3)
-ANKI_SPECIALIZE_GET_VALUE(Mat4, m_mat4, MAT4)
+#define ANKI_SVDT_MACRO(capital, type, baseType, rowCount, columnCount) \
+	ANKI_SPECIALIZE_GET_VALUE(type, ANKI_CONCATENATE(m_, type), capital)
+#include <anki/gr/ShaderVariableDataTypeDefs.h>
+#undef ANKI_SVDT_MACRO
+
+#undef ANKI_SPECIALIZE_GET_VALUE
 
 template<>
 inline const TextureResourcePtr& MaterialVariable::getValue() const
@@ -214,8 +195,6 @@ inline const TextureResourcePtr& MaterialVariable::getValue() const
 	return m_tex;
 }
 
-#undef ANKI_SPECIALIZE_GET_VALUE
-
 /// Material variant.
 class MaterialVariant : public NonCopyable
 {

+ 12 - 12
src/anki/resource/ShaderProgramResource.cpp

@@ -110,49 +110,49 @@ Error ShaderProgramResource::load(const ResourceFilename& filename, Bool async)
 		}
 		else if(componentCount == 2)
 		{
-			if(c.m_type == ShaderVariableDataType::UINT)
+			if(c.m_type == ShaderVariableDataType::U32)
 			{
 				in.m_dataType = ShaderVariableDataType::UVEC2;
 			}
-			else if(c.m_type == ShaderVariableDataType::INT)
+			else if(c.m_type == ShaderVariableDataType::I32)
 			{
 				in.m_dataType = ShaderVariableDataType::IVEC2;
 			}
 			else
 			{
-				ANKI_ASSERT(c.m_type == ShaderVariableDataType::FLOAT);
+				ANKI_ASSERT(c.m_type == ShaderVariableDataType::F32);
 				in.m_dataType = ShaderVariableDataType::VEC2;
 			}
 		}
 		else if(componentCount == 3)
 		{
-			if(c.m_type == ShaderVariableDataType::UINT)
+			if(c.m_type == ShaderVariableDataType::U32)
 			{
 				in.m_dataType = ShaderVariableDataType::UVEC3;
 			}
-			else if(c.m_type == ShaderVariableDataType::INT)
+			else if(c.m_type == ShaderVariableDataType::I32)
 			{
 				in.m_dataType = ShaderVariableDataType::IVEC3;
 			}
 			else
 			{
-				ANKI_ASSERT(c.m_type == ShaderVariableDataType::FLOAT);
+				ANKI_ASSERT(c.m_type == ShaderVariableDataType::F32);
 				in.m_dataType = ShaderVariableDataType::VEC3;
 			}
 		}
 		else if(componentCount == 4)
 		{
-			if(c.m_type == ShaderVariableDataType::UINT)
+			if(c.m_type == ShaderVariableDataType::U32)
 			{
 				in.m_dataType = ShaderVariableDataType::UVEC4;
 			}
-			else if(c.m_type == ShaderVariableDataType::INT)
+			else if(c.m_type == ShaderVariableDataType::I32)
 			{
 				in.m_dataType = ShaderVariableDataType::IVEC4;
 			}
 			else
 			{
-				ANKI_ASSERT(c.m_type == ShaderVariableDataType::FLOAT);
+				ANKI_ASSERT(c.m_type == ShaderVariableDataType::F32);
 				in.m_dataType = ShaderVariableDataType::VEC4;
 			}
 		}
@@ -325,9 +325,9 @@ void ShaderProgramResource::initVariant(const ShaderProgramResourceVariantInitIn
 				const U32 component = m_constBinaryMapping[binaryConstIdx].m_component;
 				const Const& c = m_consts[constIdx];
 				(void)c;
-				ANKI_ASSERT(
-					c.m_dataType == ShaderVariableDataType::UINT || c.m_dataType == ShaderVariableDataType::UVEC2
-					|| c.m_dataType == ShaderVariableDataType::UVEC3 || c.m_dataType == ShaderVariableDataType::UVEC4);
+				ANKI_ASSERT(c.m_dataType == ShaderVariableDataType::U32 || c.m_dataType == ShaderVariableDataType::UVEC2
+							|| c.m_dataType == ShaderVariableDataType::UVEC3
+							|| c.m_dataType == ShaderVariableDataType::UVEC4);
 
 				// Find the value
 				for(U32 i = 0; i < m_consts.getSize(); ++i)

+ 1 - 1
src/anki/scene/components/RenderComponent.cpp

@@ -69,7 +69,7 @@ void MaterialRenderComponent::allocateAndSetupUniforms(const RenderQueueDrawCont
 
 		switch(mvar.getDataType())
 		{
-		case ShaderVariableDataType::FLOAT:
+		case ShaderVariableDataType::F32:
 		{
 			const F32 val = mvar.getValue<F32>();
 			variant.writeShaderBlockMemory(mvar, &val, 1, uniformsBegin, uniformsEnd);

+ 11 - 12
src/anki/shader_compiler/ShaderProgramParser.cpp

@@ -24,6 +24,7 @@ static const char* SHADER_HEADER = R"(#version 460 core
 #define ANKI_BACKEND_MINOR %u
 #define ANKI_BACKEND_MAJOR %u
 #define ANKI_VENDOR_%s 1
+#define ANKI_%s_SHADER 1
 
 #define gl_VertexID gl_VertexIndex
 
@@ -60,7 +61,7 @@ static const char* SHADER_HEADER = R"(#version 460 core
 #define ANKI_MAX_BINDLESS_TEXTURES %u
 #define ANKI_MAX_BINDLESS_IMAGES %u
 
-#if %u
+#if %u || defined(ANKI_RAY_GEN_SHADER) || defined(ANKI_ANY_HIT_SHADER) || defined(ANKI_CLOSEST_HIT_SHADER) || defined(ANKI_MISS_SHADER) || defined(ANKI_INTERSECTION_SHADER) || defined(ANKI_CALLABLE_SHADER)
 #	extension GL_EXT_ray_tracing : enable
 #endif
 
@@ -70,7 +71,7 @@ static const char* SHADER_HEADER = R"(#version 460 core
 	layout(set = set_, binding = 0) uniform texture2D u_bindlessTextures2dF32[ANKI_MAX_BINDLESS_TEXTURES]; \
 	layout(set = set_, binding = 1) uniform readonly uimage2D u_bindlessImages2dU32[ANKI_MAX_BINDLESS_IMAGES]; \
 	layout(set = set_, binding = 1) uniform readonly iimage2D u_bindlessImages2dI32[ANKI_MAX_BINDLESS_IMAGES]; \
-	layout(set = set_, binding = 1) uniform readonly image2D u_bindlessImages2dF32[ANKI_MAX_BINDLESS_IMAGES];
+	layout(set = set_, binding = 1) uniform readonly image2D u_bindlessImages2dF32[ANKI_MAX_BINDLESS_IMAGES]
 
 #define F32 float
 #define _ANKI_SIZEOF_float 4
@@ -847,12 +848,12 @@ Error ShaderProgramParser::parse()
 	return Error::NONE;
 }
 
-void ShaderProgramParser::generateAnkiShaderHeader(const GpuDeviceCapabilities& caps, const BindlessLimits& limits,
-												   StringAuto& header)
+void ShaderProgramParser::generateAnkiShaderHeader(ShaderType shaderType, const GpuDeviceCapabilities& caps,
+												   const BindlessLimits& limits, StringAuto& header)
 {
 	header.sprintf(SHADER_HEADER, caps.m_minorApiVersion, caps.m_majorApiVersion,
-				   GPU_VENDOR_STR[caps.m_gpuVendor].cstr(), limits.m_bindlessTextureCount, limits.m_bindlessImageCount,
-				   U(caps.m_rayTracingEnabled));
+				   GPU_VENDOR_STR[caps.m_gpuVendor].cstr(), SHADER_STAGE_NAMES[shaderType].cstr(),
+				   limits.m_bindlessTextureCount, limits.m_bindlessImageCount, U(caps.m_rayTracingEnabled));
 }
 
 Error ShaderProgramParser::generateVariant(ConstWeakArray<MutatorValue> mutation,
@@ -877,10 +878,6 @@ Error ShaderProgramParser::generateVariant(ConstWeakArray<MutatorValue> mutation
 		mutatorDefines.append(StringAuto(m_alloc).sprintf("#define %s %d\n", m_mutators[i].m_name.cstr(), mutation[i]));
 	}
 
-	// Create the header
-	StringAuto header(m_alloc);
-	generateAnkiShaderHeader(m_gpuCapabilities, m_bindlessLimits, header);
-
 	// Generate souce per stage
 	for(ShaderType shaderType : EnumIterable<ShaderType>())
 	{
@@ -889,12 +886,14 @@ Error ShaderProgramParser::generateVariant(ConstWeakArray<MutatorValue> mutation
 			continue;
 		}
 
+		// Create the header
+		StringAuto header(m_alloc);
+		generateAnkiShaderHeader(shaderType, m_gpuCapabilities, m_bindlessLimits, header);
+
 		// Create the final source without the bindings
 		StringAuto finalSource(m_alloc);
 		finalSource.append(header);
 		finalSource.append(mutatorDefines);
-		finalSource.append(
-			StringAuto(m_alloc).sprintf("#define ANKI_%s_SHADER 1\n", SHADER_STAGE_NAMES[shaderType].cstr()));
 		finalSource.append(m_codeSource);
 
 		// Move the source

+ 2 - 2
src/anki/shader_compiler/ShaderProgramParser.h

@@ -121,8 +121,8 @@ public:
 	}
 
 	/// Generates the common header that will be used by all AnKi shaders.
-	static void generateAnkiShaderHeader(const GpuDeviceCapabilities& caps, const BindlessLimits& limits,
-										 StringAuto& header);
+	static void generateAnkiShaderHeader(ShaderType shaderType, const GpuDeviceCapabilities& caps,
+										 const BindlessLimits& limits, StringAuto& header);
 
 private:
 	using Mutator = ShaderProgramParserMutator;

+ 53 - 65
src/anki/shader_compiler/ShaderProgramReflection.cpp

@@ -10,6 +10,28 @@
 namespace anki
 {
 
+static ShaderVariableDataType spirvcrossBaseTypeToAnki(spirv_cross::SPIRType::BaseType cross)
+{
+	ShaderVariableDataType out = ShaderVariableDataType::NONE;
+
+	switch(cross)
+	{
+	case spirv_cross::SPIRType::Int:
+		out = ShaderVariableDataType::I32;
+		break;
+	case spirv_cross::SPIRType::UInt:
+		out = ShaderVariableDataType::U32;
+		break;
+	case spirv_cross::SPIRType::Float:
+		out = ShaderVariableDataType::F32;
+		break;
+	default:
+		break;
+	}
+
+	return out;
+}
+
 /// Populates the reflection info.
 class SpirvReflector : public spirv_cross::Compiler
 {
@@ -206,27 +228,8 @@ Error SpirvReflector::blockVariableReflection(const spirv_cross::SPIRType& type,
 			var.m_blockInfo.m_arrayStride = I16(get_decoration(type.member_types[i], spv::DecorationArrayStride));
 		}
 
-		// Type
-		auto func = [&](const Array<ShaderVariableDataType, 3>& arr) {
-			switch(memberType.basetype)
-			{
-			case spirv_cross::SPIRType::UInt:
-				var.m_type = arr[0];
-				break;
-			case spirv_cross::SPIRType::Int:
-				var.m_type = arr[1];
-				break;
-			case spirv_cross::SPIRType::Float:
-				var.m_type = arr[2];
-				break;
-			default:
-				ANKI_ASSERT(0);
-			}
-		};
-
-		const Bool isNumeric = memberType.basetype == spirv_cross::SPIRType::UInt
-							   || memberType.basetype == spirv_cross::SPIRType::Int
-							   || memberType.basetype == spirv_cross::SPIRType::Float;
+		const ShaderVariableDataType baseType = spirvcrossBaseTypeToAnki(memberType.basetype);
+		const Bool isNumeric = baseType != ShaderVariableDataType::NONE;
 
 		if(memberType.basetype == spirv_cross::SPIRType::Struct)
 		{
@@ -245,47 +248,32 @@ Error SpirvReflector::blockVariableReflection(const spirv_cross::SPIRType& type,
 				}
 			}
 		}
-		else if(memberType.vecsize == 1 && memberType.columns == 1 && isNumeric)
-		{
-			static const Array<ShaderVariableDataType, 3> arr = {
-				{ShaderVariableDataType::UINT, ShaderVariableDataType::INT, ShaderVariableDataType::FLOAT}};
-			func(arr);
-		}
-		else if(memberType.vecsize == 2 && memberType.columns == 1 && isNumeric)
-		{
-			static const Array<ShaderVariableDataType, 3> arr = {
-				{ShaderVariableDataType::UVEC2, ShaderVariableDataType::IVEC2, ShaderVariableDataType::VEC2}};
-			func(arr);
-		}
-		else if(memberType.vecsize == 3 && memberType.columns == 1 && isNumeric)
-		{
-			static const Array<ShaderVariableDataType, 3> arr = {
-				{ShaderVariableDataType::UVEC3, ShaderVariableDataType::IVEC3, ShaderVariableDataType::VEC3}};
-			func(arr);
-		}
-		else if(memberType.vecsize == 4 && memberType.columns == 1 && isNumeric)
+		else if(isNumeric)
 		{
-			static const Array<ShaderVariableDataType, 3> arr = {
-				{ShaderVariableDataType::UVEC4, ShaderVariableDataType::IVEC4, ShaderVariableDataType::VEC4}};
-			func(arr);
-		}
-		else if(memberType.vecsize == 3 && memberType.columns == 3
-				&& memberType.basetype == spirv_cross::SPIRType::Float)
-		{
-			var.m_type = ShaderVariableDataType::MAT3;
-			var.m_blockInfo.m_matrixStride = 16;
-		}
-		else if(memberType.vecsize == 4 && memberType.columns == 3
-				&& memberType.basetype == spirv_cross::SPIRType::Float)
-		{
-			var.m_type = ShaderVariableDataType::MAT3X4;
-			var.m_blockInfo.m_matrixStride = 16;
-		}
-		else if(memberType.vecsize == 4 && memberType.columns == 4
-				&& memberType.basetype == spirv_cross::SPIRType::Float)
-		{
-			var.m_type = ShaderVariableDataType::MAT4;
-			var.m_blockInfo.m_matrixStride = 16;
+			const Bool isMatrix = memberType.columns > 1;
+
+			if(0)
+			{
+			}
+#define ANKI_SVDT_MACRO(capital, type, baseType_, rowCount, columnCount) \
+	else if(ShaderVariableDataType::baseType_ == baseType && isMatrix && memberType.vecsize == columnCount \
+			&& memberType.columns == rowCount) \
+	{ \
+		var.m_type = ShaderVariableDataType::capital; \
+		var.m_blockInfo.m_matrixStride = 16; \
+	} \
+	else if(ShaderVariableDataType::baseType_ == baseType && !isMatrix && memberType.vecsize == rowCount) \
+	{ \
+		var.m_type = ShaderVariableDataType::capital; \
+	}
+#include <anki/gr/ShaderVariableDataTypeDefs.h>
+#undef ANKI_SVDT_MACRO
+
+			if(var.m_type == ShaderVariableDataType::NONE)
+			{
+				ANKI_SHADER_COMPILER_LOGE("Unhandled numeric member: %s", var.m_name.cstr());
+				return Error::FUNCTION_FAILED;
+			}
 		}
 		else
 		{
@@ -301,7 +289,7 @@ Error SpirvReflector::blockVariableReflection(const spirv_cross::SPIRType& type,
 	}
 
 	return Error::NONE;
-}
+} // namespace anki
 
 Error SpirvReflector::blockReflection(const spirv_cross::Resource& res, Bool isStorage,
 									  DynamicArrayAuto<Block>& blocks) const
@@ -526,13 +514,13 @@ Error SpirvReflector::constsReflection(DynamicArrayAuto<Const>& consts, ShaderTy
 		switch(type.basetype)
 		{
 		case spirv_cross::SPIRType::UInt:
-			newConst.m_type = ShaderVariableDataType::UINT;
+			newConst.m_type = ShaderVariableDataType::U32;
 			break;
 		case spirv_cross::SPIRType::Int:
-			newConst.m_type = ShaderVariableDataType::INT;
+			newConst.m_type = ShaderVariableDataType::I32;
 			break;
 		case spirv_cross::SPIRType::Float:
-			newConst.m_type = ShaderVariableDataType::FLOAT;
+			newConst.m_type = ShaderVariableDataType::F32;
 			break;
 		default:
 			ANKI_SHADER_COMPILER_LOGE("Can't determine the type of the spec constant: %s", name.c_str());

+ 1 - 1
tests/gr/Gr.cpp

@@ -364,7 +364,7 @@ static ShaderPtr createShader(CString src, ShaderType type, GrManager& gr,
 {
 	HeapAllocator<U8> alloc(allocAligned, nullptr);
 	StringAuto header(alloc);
-	ShaderProgramParser::generateAnkiShaderHeader(gr.getDeviceCapabilities(), gr.getBindlessLimits(), header);
+	ShaderProgramParser::generateAnkiShaderHeader(type, gr.getDeviceCapabilities(), gr.getBindlessLimits(), header);
 	header.append(src);
 	DynamicArrayAuto<U8> spirv(alloc);
 	ANKI_TEST_EXPECT_NO_ERR(compilerGlslToSpirv(header, type, alloc, spirv));