浏览代码

Fixes. Convert the 1st program to the new format

Panagiotis Christopoulos Charitos 5 年之前
父节点
当前提交
4b199a739a

+ 1 - 1
shaders/Common.glsl

@@ -41,7 +41,7 @@ const U32 MAX_U32 = 0xFFFFFFFFu;
 
 const F32 PI = 3.14159265358979323846;
 const U32 UBO_MAX_SIZE = 16384u;
-#define MAX_SHARED_MEMORY (32u * 1024u)
+const U32 MAX_SHARED_MEMORY = 32u * 1024u;
 
 // Macros
 #define UV_TO_NDC(x_) ((x_)*2.0 - 1.0)

+ 0 - 68
shaders/Ui.glslp

@@ -1,68 +0,0 @@
-// Copyright (C) 2009-2020, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#pragma anki mutator TEXTURE_TYPE 0 1 // 0: no tex, 1: rgba tex
-
-#pragma anki start vert
-#include <shaders/Common.glsl>
-
-layout(location = 0) in Vec2 in_pos;
-layout(location = 1) in Vec4 in_col;
-#if TEXTURE_TYPE > 0
-layout(location = 2) in Vec2 in_uv;
-#endif
-
-#if TEXTURE_TYPE > 0
-layout(location = 0) out Vec2 out_uv;
-#endif
-layout(location = 1) out Vec4 out_col;
-
-out gl_PerVertex
-{
-	Vec4 gl_Position;
-};
-
-layout(push_constant) uniform u_
-{
-	Vec4 u_transform; // x: x scale, y: y scale, z: x transl, w: y transl
-};
-
-void main()
-{
-#if TEXTURE_TYPE > 0
-	out_uv = in_uv;
-#endif
-	out_col = in_col;
-
-	const Vec2 pos = u_transform.xy * in_pos + u_transform.zw;
-	gl_Position = Vec4(pos, 0.0, 1.0);
-}
-#pragma anki end
-
-#pragma anki start frag
-#include <shaders/Common.glsl>
-
-#if TEXTURE_TYPE > 0
-layout(location = 0) in Vec2 in_uv;
-#endif
-layout(location = 1) in Vec4 in_col;
-
-layout(location = 0) out Vec4 out_col;
-
-#if TEXTURE_TYPE > 0
-layout(set = 0, binding = 0) uniform sampler u_trilinearRepeatSampler;
-layout(set = 0, binding = 1) uniform texture2D u_tex;
-#endif
-
-void main()
-{
-#if TEXTURE_TYPE == 0
-	out_col = in_col;
-#elif TEXTURE_TYPE == 1
-	out_col = in_col * texture(u_tex, u_trilinearRepeatSampler, in_uv);
-#endif
-}
-
-#pragma anki end

+ 57 - 11
src/anki/core/App.cpp

@@ -711,20 +711,34 @@ void App::initMemoryCallbacks(AllocAlignedCallback allocCb, void* allocCbUserDat
 Error App::compileAllShaders()
 {
 	ANKI_CORE_LOGI("Compiling shaders");
+	U32 shadersCompileCount = 0;
 
 	ANKI_CHECK(m_resourceFs->iterateAllFilenames([&](CString fname) -> Error {
 		// Check file extension
 		StringAuto extension(m_heapAlloc);
 		getFilepathExtension(fname, extension);
-		if(extension.getLength() == 0 || extension != "ankiprog")
+		if(extension.getLength() != 8 || extension != "ankiprog")
 		{
 			return Error::NONE;
 		}
 
-		// TODO check if it's in the cache
+		// Get some filenames
+		StringAuto baseFname(m_heapAlloc);
+		getFilepathFilename(fname, baseFname);
+		StringAuto metaFname(m_heapAlloc);
+		metaFname.sprintf("%s/%smeta", m_cacheDir.cstr(), baseFname.cstr());
+
+		// Get the hash from the meta file
+		U64 metafileHash = 0;
+		if(fileExists(metaFname))
+		{
+			File metaFile;
+			ANKI_CHECK(metaFile.open(metaFname, FileOpenFlag::READ | FileOpenFlag::BINARY));
+			ANKI_CHECK(metaFile.read(&metafileHash, sizeof(metafileHash)));
+		}
 
 		// Load interface
-		class Interface : public ShaderProgramFilesystemInterface
+		class FSystem : public ShaderProgramFilesystemInterface
 		{
 		public:
 			ResourceFilesystem* m_fsystem = nullptr;
@@ -736,24 +750,56 @@ Error App::compileAllShaders()
 				ANKI_CHECK(file->readAllText(txt));
 				return Error::NONE;
 			}
-		} iface;
-		iface.m_fsystem = m_resourceFs;
+		} fsystem;
+		fsystem.m_fsystem = m_resourceFs;
+
+		class Skip : public ShaderProgramPostParseInterface
+		{
+		public:
+			U64 m_metafileHash;
+			U64 m_newHash;
+
+			Bool skipCompilation(U64 hash)
+			{
+				ANKI_ASSERT(hash != 0);
+				m_newHash = hash;
+				return hash == m_metafileHash;
+			};
+		} skip;
+		skip.m_metafileHash = metafileHash;
+		skip.m_newHash = 0;
 
 		// Compile
 		ShaderProgramBinaryWrapper binary(m_heapAlloc);
 		ANKI_CHECK(compileShaderProgram(
-			fname, iface, m_heapAlloc, m_gr->getDeviceCapabilities(), m_gr->getBindlessLimits(), binary));
+			fname, fsystem, &skip, m_heapAlloc, m_gr->getDeviceCapabilities(), m_gr->getBindlessLimits(), binary));
+
+		const Bool cachedBinIsUpToDate = metafileHash == skip.m_newHash;
+		if(!cachedBinIsUpToDate)
+		{
+			++shadersCompileCount;
+		}
+
+		// Update the meta file
+		if(!cachedBinIsUpToDate)
+		{
+			File metaFile;
+			ANKI_CHECK(metaFile.open(metaFname, FileOpenFlag::WRITE | FileOpenFlag::BINARY));
+			ANKI_CHECK(metaFile.write(&skip.m_newHash, sizeof(skip.m_newHash)));
+		}
 
 		// Save the binary to the cache
-		StringAuto baseFname(m_heapAlloc);
-		getFilepathFilename(fname, baseFname);
-		StringAuto storeFname(m_heapAlloc);
-		storeFname.sprintf("%s/%sbin", m_cacheDir.cstr(), baseFname.cstr());
-		ANKI_CHECK(binary.serializeToFile(storeFname));
+		if(!cachedBinIsUpToDate)
+		{
+			StringAuto storeFname(m_heapAlloc);
+			storeFname.sprintf("%s/%sbin", m_cacheDir.cstr(), baseFname.cstr());
+			ANKI_CHECK(binary.serializeToFile(storeFname));
+		}
 
 		return Error::NONE;
 	}));
 
+	ANKI_CORE_LOGI("Compiled %u programs", shadersCompileCount);
 	return Error::NONE;
 }
 

+ 4 - 0
src/anki/gr/Common.h

@@ -109,6 +109,7 @@ enum class GpuVendor : U8
 extern Array<CString, U(GpuVendor::COUNT)> GPU_VENDOR_STR;
 
 /// Device capabilities.
+ANKI_BEGIN_PACKED_STRUCT
 class GpuDeviceCapabilities
 {
 public:
@@ -142,6 +143,9 @@ public:
 	/// API version.
 	U8 m_majorApiVersion = 0;
 };
+ANKI_END_PACKED_STRUCT
+static_assert(
+	sizeof(GpuDeviceCapabilities) == sizeof(PtrSize) * 4 + sizeof(U32) * 3 + sizeof(U8) * 3, "Should be packed");
 
 /// Bindless related info.
 class BindlessLimits

+ 2 - 0
src/anki/gr/Shader.h

@@ -57,6 +57,8 @@ class ShaderInitInfo : public GrBaseInitInfo
 public:
 	ShaderType m_shaderType = ShaderType::COUNT;
 	ConstWeakArray<U8> m_binary = {};
+
+	/// @note It's OK to have entries in that array with consts that do not appear in the shader.
 	ConstWeakArray<ShaderSpecializationConstValue> m_constValues;
 
 	ShaderInitInfo()

+ 33 - 34
src/anki/resource/ShaderProgramResource2.cpp

@@ -30,7 +30,20 @@ ShaderProgramResource2::ShaderProgramResource2(ResourceManager* manager)
 ShaderProgramResource2::~ShaderProgramResource2()
 {
 	m_mutators.destroy(getAllocator());
+
+	for(ShaderProgramResourceConstant2& c : m_consts)
+	{
+		c.m_name.destroy(getAllocator());
+	}
 	m_consts.destroy(getAllocator());
+	m_constBinaryMapping.destroy(getAllocator());
+
+	for(auto it : m_variants)
+	{
+		ShaderProgramResourceVariant2* variant = &(*it);
+		getAllocator().deleteInstance(variant);
+	}
+	m_variants.destroy(getAllocator());
 }
 
 Error ShaderProgramResource2::load(const ResourceFilename& filename, Bool async)
@@ -39,7 +52,7 @@ Error ShaderProgramResource2::load(const ResourceFilename& filename, Bool async)
 	StringAuto baseFilename(getTempAllocator());
 	getFilepathFilename(filename, baseFilename);
 	StringAuto binaryFilename(getTempAllocator());
-	binaryFilename.sprintf("%s/%s.bin", getManager().getCacheDirectory().cstr(), binaryFilename.cstr());
+	binaryFilename.sprintf("%s/%sbin", getManager().getCacheDirectory().cstr(), baseFilename.cstr());
 	ANKI_CHECK(m_binary.deserializeFromFile(binaryFilename));
 	const ShaderProgramBinary& binary = m_binary.getBinary();
 
@@ -242,44 +255,30 @@ void ShaderProgramResource2::initVariant(
 	variant.m_binaryVariant = binaryVariant;
 
 	// Set the constannt values
-	Array2d<ShaderSpecializationConstValue, U(ShaderType::COUNT), 64> constValues;
-	Array<U32, U(ShaderType::COUNT)> constValueCounts;
-	for(ShaderType shaderType : EnumIterable<ShaderType>())
+	Array<ShaderSpecializationConstValue, 64> constValues;
+	U32 constValueCount = 0;
+	for(const ShaderProgramBinaryConstantInstance& instance : binaryVariant->m_constants)
 	{
-		if(!(shaderTypeToBit(shaderType) & m_shaderStages))
-		{
-			continue;
-		}
+		const ShaderProgramBinaryConstant& c = binary.m_constants[instance.m_index];
+		const U32 inputIdx = m_constBinaryMapping[instance.m_index].m_constsIdx;
+		const U32 component = m_constBinaryMapping[instance.m_index].m_component;
 
-		for(const ShaderProgramBinaryConstantInstance& instance : binaryVariant->m_constants)
+		// Get value
+		const ShaderProgramResourceConstantValue2* value = nullptr;
+		for(U32 i = 0; i < info.m_constantValueCount; ++i)
 		{
-			const ShaderProgramBinaryConstant& c = binary.m_constants[instance.m_index];
-			if(!(c.m_shaderStages & shaderTypeToBit(shaderType)))
+			if(info.m_constantValues[i].m_constantIndex == inputIdx)
 			{
-				continue;
-			}
-
-			const U32 inputIdx = m_constBinaryMapping[instance.m_index].m_constsIdx;
-			const U32 component = m_constBinaryMapping[instance.m_index].m_component;
-
-			// Get value
-			const ShaderProgramResourceConstantValue2* value = nullptr;
-			for(U32 i = 0; i < info.m_constantValueCount; ++i)
-			{
-				if(info.m_constantValues[i].m_constantIndex == inputIdx)
-				{
-					value = &info.m_constantValues[i];
-					break;
-				}
+				value = &info.m_constantValues[i];
+				break;
 			}
-			ANKI_ASSERT(value && "Forgot to set the value of a constant");
-
-			U32& count = constValueCounts[shaderType];
-			constValues[shaderType][count].m_constantId = c.m_constantId;
-			constValues[shaderType][count].m_dataType = c.m_type;
-			constValues[shaderType][count].m_int = value->m_ivec4[component];
-			++count;
 		}
+		ANKI_ASSERT(value && "Forgot to set the value of a constant");
+
+		constValues[constValueCount].m_constantId = c.m_constantId;
+		constValues[constValueCount].m_dataType = c.m_type;
+		constValues[constValueCount].m_int = value->m_ivec4[component];
+		++constValueCount;
 	}
 
 	// Create the program name
@@ -303,7 +302,7 @@ void ShaderProgramResource2::initVariant(
 		ShaderInitInfo inf(cprogName);
 		inf.m_shaderType = shaderType;
 		inf.m_binary = binary.m_codeBlocks[binaryVariant->m_codeBlockIndices[shaderType]].m_binary;
-		inf.m_constValues.setArray(&constValues[shaderType][0], constValueCounts[shaderType]);
+		inf.m_constValues.setArray((constValueCount) ? constValues.getBegin() : nullptr, constValueCount);
 
 		progInf.m_shaders[shaderType] = getManager().getGrManager().newShader(inf);
 	}

+ 4 - 3
src/anki/resource/ShaderProgramResource2.h

@@ -8,6 +8,7 @@
 #include <anki/resource/ResourceObject.h>
 #include <anki/shader_compiler/ShaderProgramCompiler.h>
 #include <anki/gr/utils/Functions.h>
+#include <anki/gr/ShaderProgram.h>
 #include <anki/util/BitSet.h>
 #include <anki/util/String.h>
 #include <anki/util/HashMap.h>
@@ -50,7 +51,7 @@ class ShaderProgramResourceConstant2
 public:
 	String m_name;
 	ShaderVariableDataType m_dataType = ShaderVariableDataType::NONE;
-	U32 m_index;
+	U32 m_index = MAX_U32;
 };
 
 /// Shader program resource variant.
@@ -98,7 +99,7 @@ public:
 	ANKI_USE_RESULT Error load(const ResourceFilename& filename, Bool async);
 
 	/// Get the array of constants.
-	const DynamicArray<ShaderProgramResourceConstant2>& getConstants() const
+	ConstWeakArray<ShaderProgramResourceConstant2> getConstants() const
 	{
 		return m_consts;
 	}
@@ -117,7 +118,7 @@ public:
 	}
 
 	/// Get the array of mutators.
-	const DynamicArray<ShaderProgramResourceMutator2>& getMutators() const
+	ConstWeakArray<ShaderProgramResourceMutator2> getMutators() const
 	{
 		return m_mutators;
 	}

+ 7 - 0
src/anki/shader_compiler/Common.h

@@ -30,6 +30,13 @@ class ShaderProgramFilesystemInterface
 public:
 	virtual ANKI_USE_RESULT Error readAllText(CString filename, StringAuto& txt) = 0;
 };
+
+/// This controls if the compilation will continue after the parsing stage.
+class ShaderProgramPostParseInterface
+{
+public:
+	virtual Bool skipCompilation(U64 programHash) = 0;
+};
 /// @}
 
 } // end namespace anki

+ 18 - 0
src/anki/shader_compiler/Glslang.cpp

@@ -5,6 +5,7 @@
 
 #include <anki/shader_compiler/Glslang.h>
 #include <anki/util/StringList.h>
+#include <anki/util/File.h>
 
 #if ANKI_COMPILER_GCC_COMPATIBLE
 #	pragma GCC diagnostic push
@@ -265,6 +266,23 @@ Error compilerGlslToSpirv(
 	spirv.resize(U32(glslangSpirv.size() * sizeof(unsigned int)));
 	memcpy(&spirv[0], &glslangSpirv[0], spirv.getSizeInBytes());
 
+#if 0
+	// Dump it
+	{
+		static U32 count = 0;
+		if(count == 0)
+		{
+			ANKI_SHADER_COMPILER_LOGW("SPIR-V dumping is enabled");
+		}
+
+		File file;
+		StringAuto fname(tmpAlloc);
+		fname.sprintf("/tmp/%u.spv", count++);
+		ANKI_CHECK(file.open(fname, FileOpenFlag::WRITE | FileOpenFlag::BINARY));
+		ANKI_CHECK(file.write(spirv.getBegin(), spirv.getSizeInBytes()));
+	}
+#endif
+
 	return Error::NONE;
 }
 

+ 0 - 2
src/anki/shader_compiler/ShaderProgramBinary.h

@@ -193,7 +193,6 @@ public:
 	Array<char, MAX_SHADER_BINARY_NAME_LENGTH + 1> m_name;
 	ShaderVariableDataType m_type = ShaderVariableDataType::NONE;
 	U32 m_constantId = MAX_U32;
-	ShaderTypeBit m_shaderStages = ShaderTypeBit::NONE;
 
 	template<typename TSerializer, typename TClass>
 	static void serializeCommon(TSerializer& s, TClass self)
@@ -201,7 +200,6 @@ public:
 		s.doArray("m_name", offsetof(ShaderProgramBinaryConstant, m_name), &self.m_name[0], self.m_name.getSize());
 		s.doValue("m_type", offsetof(ShaderProgramBinaryConstant, m_type), self.m_type);
 		s.doValue("m_constantId", offsetof(ShaderProgramBinaryConstant, m_constantId), self.m_constantId);
-		s.doValue("m_shaderStages", offsetof(ShaderProgramBinaryConstant, m_shaderStages), self.m_shaderStages);
 	}
 
 	template<typename TDeserializer>

+ 0 - 1
src/anki/shader_compiler/ShaderProgramBinary.xml

@@ -58,7 +58,6 @@
 				<member name="m_name" type="char" array_size="MAX_SHADER_BINARY_NAME_LENGTH + 1" />
 				<member name="m_type" type="ShaderVariableDataType" constructor="= ShaderVariableDataType::NONE" />
 				<member name="m_constantId" type="U32" constructor="= MAX_U32"/>
-				<member name="m_shaderStages" type="ShaderTypeBit" constructor="= ShaderTypeBit::NONE"/>
 			</members>
 		</class>
 

+ 10 - 7
src/anki/shader_compiler/ShaderProgramCompiler.cpp

@@ -353,15 +353,14 @@ public:
 		}
 
 		// Create the instance
-		ShaderProgramBinaryOpaqueInstance& instance = *m_opaqueInstances.emplaceBack();
+		ShaderProgramBinaryOpaqueInstance& instance = m_opaqueInstances[instanceIdx];
 		instance.m_index = opaqueIdx;
 		instance.m_arraySize = arraySize;
 
 		return Error::NONE;
 	}
 
-	Error visitConstant(
-		U32 instanceIdx, CString name, ShaderVariableDataType type, U32 constantId, ShaderTypeBit stages) final
+	Error visitConstant(U32 instanceIdx, CString name, ShaderVariableDataType type, U32 constantId) final
 	{
 		// Find const
 		U32 constIdx = MAX_U32;
@@ -369,8 +368,7 @@ public:
 		{
 			if(name == m_consts[i].m_name.getBegin())
 			{
-				if(type != m_consts[i].m_type || constantId != m_consts[i].m_constantId
-					|| m_consts[i].m_shaderStages != stages)
+				if(type != m_consts[i].m_type || constantId != m_consts[i].m_constantId)
 				{
 					ANKI_SHADER_COMPILER_LOGE(
 						"The type, constantId and stages can't difer between shader variants for const: %s",
@@ -390,13 +388,12 @@ public:
 			ANKI_CHECK(setName(name, c.m_name));
 			c.m_type = type;
 			c.m_constantId = constantId;
-			c.m_shaderStages = stages;
 
 			constIdx = m_consts.getSize() - 1;
 		}
 
 		// Create the instance
-		ShaderProgramBinaryConstantInstance& instance = *m_constInstances.emplaceBack();
+		ShaderProgramBinaryConstantInstance& instance = m_constInstances[instanceIdx];
 		instance.m_index = constIdx;
 
 		return Error::NONE;
@@ -653,6 +650,7 @@ static Error doReflection(
 
 Error compileShaderProgram(CString fname,
 	ShaderProgramFilesystemInterface& fsystem,
+	ShaderProgramPostParseInterface* postParseCallback,
 	GenericMemoryPoolAllocator<U8> tempAllocator,
 	const GpuDeviceCapabilities& gpuCapabilities,
 	const BindlessLimits& bindlessLimits,
@@ -671,6 +669,11 @@ Error compileShaderProgram(CString fname,
 	ShaderProgramParser parser(fname, &fsystem, tempAllocator, gpuCapabilities, bindlessLimits);
 	ANKI_CHECK(parser.parse());
 
+	if(postParseCallback && postParseCallback->skipCompilation(parser.getHash()))
+	{
+		return Error::NONE;
+	}
+
 	// Get mutators
 	U32 mutationCount = 0;
 	if(parser.getMutators().getSize() > 0)

+ 2 - 0
src/anki/shader_compiler/ShaderProgramCompiler.h

@@ -21,6 +21,7 @@ class ShaderProgramBinaryWrapper : public NonCopyable
 {
 	friend Error compileShaderProgram(CString fname,
 		ShaderProgramFilesystemInterface& fsystem,
+		ShaderProgramPostParseInterface* postParseCallback,
 		GenericMemoryPoolAllocator<U8> tempAllocator,
 		const GpuDeviceCapabilities& gpuCapabilities,
 		const BindlessLimits& bindlessLimits,
@@ -58,6 +59,7 @@ private:
 /// Takes an AnKi special shader program and spits a binary.
 ANKI_USE_RESULT Error compileShaderProgram(CString fname,
 	ShaderProgramFilesystemInterface& fsystem,
+	ShaderProgramPostParseInterface* postParseCallback,
 	GenericMemoryPoolAllocator<U8> tempAllocator,
 	const GpuDeviceCapabilities& gpuCapabilities,
 	const BindlessLimits& bindlessLimits,

+ 2 - 0
src/anki/shader_compiler/ShaderProgramParser.cpp

@@ -684,6 +684,8 @@ Error ShaderProgramParser::parse()
 	{
 		m_codeLines.join("\n", m_codeSource);
 		m_codeLines.destroy();
+
+		m_codeSourceHash = computeHash(m_codeSource.getBegin(), m_codeSource.getLength());
 	}
 
 	return Error::NONE;

+ 7 - 0
src/anki/shader_compiler/ShaderProgramParser.h

@@ -117,6 +117,12 @@ public:
 		return m_shaderTypes;
 	}
 
+	U64 getHash() const
+	{
+		ANKI_ASSERT(m_codeSourceHash != 0);
+		return m_codeSourceHash;
+	}
+
 private:
 	using Mutator = ShaderProgramParserMutator;
 
@@ -153,6 +159,7 @@ private:
 
 	StringListAuto m_codeLines = {m_alloc}; ///< The code.
 	StringAuto m_codeSource = {m_alloc};
+	U64 m_codeSourceHash = 0;
 
 	DynamicArrayAuto<Mutator> m_mutators = {m_alloc};
 	DynamicArrayAuto<MutationRewrite> m_mutationRewrites = {m_alloc};

+ 2 - 13
src/anki/shader_compiler/ShaderProgramReflection.cpp

@@ -75,7 +75,6 @@ private:
 		StringAuto m_name;
 		ShaderVariableDataType m_type = ShaderVariableDataType::NONE;
 		U32 m_constantId = MAX_U32;
-		ShaderTypeBit m_shaderStages = ShaderTypeBit::NONE;
 
 		Const(const GenericMemoryPoolAllocator<U8>& alloc)
 			: m_name(alloc)
@@ -306,15 +305,10 @@ Error SpirvReflector::blockReflection(
 	const spirv_cross::Bitset decorationMask = get_decoration_bitset(res.id);
 
 	const Bool isPushConstant = get_storage_class(res.id) == spv::StorageClassPushConstant;
-	const Bool isBlock = get_decoration_bitset(type.self).get(spv::DecorationBlock)
-						 || get_decoration_bitset(type.self).get(spv::DecorationBufferBlock);
-
-	const spirv_cross::ID fallbackId =
-		(!isPushConstant && isBlock) ? spirv_cross::ID(res.base_type_id) : spirv_cross::ID(res.id);
 
 	// Name
 	{
-		const std::string name = (!res.name.empty()) ? res.name : get_fallback_name(fallbackId);
+		const std::string name = (!res.name.empty()) ? res.name : to_name(res.base_type_id);
 		if(name.length() == 0)
 		{
 			ANKI_SHADER_COMPILER_LOGE("Can't accept zero name length");
@@ -566,11 +560,6 @@ Error SpirvReflector::constsReflection(DynamicArrayAuto<Const>& consts, ShaderTy
 		{
 			consts.emplaceBack(std::move(newConst));
 		}
-		else
-		{
-			ANKI_ASSERT(foundConst->m_shaderStages != ShaderTypeBit::NONE);
-			foundConst->m_shaderStages |= shaderTypeToBit(stage);
-		}
 	}
 
 	return Error::NONE;
@@ -694,7 +683,7 @@ Error SpirvReflector::performSpirvReflection(Array<ConstWeakArray<U8>, U32(Shade
 	for(U32 i = 0; i < specializationConstants.getSize(); ++i)
 	{
 		const Const& c = specializationConstants[i];
-		ANKI_CHECK(interface.visitConstant(i, c.m_name, c.m_type, c.m_constantId, c.m_shaderStages));
+		ANKI_CHECK(interface.visitConstant(i, c.m_name, c.m_type, c.m_constantId));
 	}
 
 	return Error::NONE;

+ 1 - 2
src/anki/shader_compiler/ShaderProgramReflection.h

@@ -43,8 +43,7 @@ public:
 	virtual ANKI_USE_RESULT Error visitOpaque(
 		U32 idx, CString name, ShaderVariableDataType type, U32 set, U32 binding, U32 arraySize) = 0;
 
-	virtual ANKI_USE_RESULT Error visitConstant(
-		U32 idx, CString name, ShaderVariableDataType type, U32 constantId, ShaderTypeBit stages) = 0;
+	virtual ANKI_USE_RESULT Error visitConstant(U32 idx, CString name, ShaderVariableDataType type, U32 constantId) = 0;
 };
 
 /// Does reflection using SPIR-V.

+ 7 - 5
src/anki/ui/Canvas.cpp

@@ -9,6 +9,8 @@
 #include <anki/resource/ResourceManager.h>
 #include <anki/core/StagingGpuMemoryManager.h>
 #include <anki/input/Input.h>
+#include <anki/gr/Sampler.h>
+#include <anki/gr/GrManager.h>
 
 namespace anki
 {
@@ -35,14 +37,14 @@ Error Canvas::init(FontPtr font, U32 fontHeight, U32 width, U32 height)
 	resize(width, height);
 
 	// Create program
-	ANKI_CHECK(m_manager->getResourceManager().loadResource("shaders/Ui.glslp", m_prog));
-	const ShaderProgramResourceVariant* variant;
+	ANKI_CHECK(m_manager->getResourceManager().loadResource("shaders/Ui.ankiprog", m_prog));
 
 	for(U32 i = 0; i < SHADER_COUNT; ++i)
 	{
-		ShaderProgramResourceMutationInitList<1> mutators(m_prog);
-		mutators.add("TEXTURE_TYPE", i);
-		m_prog->getOrCreateVariant(mutators.get(), variant);
+		const ShaderProgramResourceVariant2* variant;
+		ShaderProgramResourceVariantInitInfo2 variantInitInfo(m_prog);
+		variantInitInfo.addMutation("TEXTURE_TYPE", i);
+		m_prog->getOrCreateVariant(variantInitInfo, variant);
 		m_grProgs[i] = variant->getProgram();
 	}
 

+ 2 - 2
src/anki/ui/Canvas.h

@@ -7,7 +7,7 @@
 
 #include <anki/ui/UiObject.h>
 #include <anki/gr/CommandBuffer.h>
-#include <anki/resource/ShaderProgramResource.h>
+#include <anki/resource/ShaderProgramResource2.h>
 
 namespace anki
 {
@@ -81,7 +81,7 @@ private:
 		SHADER_COUNT
 	};
 
-	ShaderProgramResourcePtr m_prog;
+	ShaderProgramResource2Ptr m_prog;
 	Array<ShaderProgramPtr, SHADER_COUNT> m_grProgs;
 	SamplerPtr m_sampler;
 

+ 1 - 1
src/anki/util/WeakArray.h

@@ -334,7 +334,7 @@ public:
 	/// Set the array pointer and its size.
 	void setArray(Value* array, Size size)
 	{
-		ANKI_ASSERT(array && size > 0 || array == nullptr && size == 0);
+		ANKI_ASSERT((array && size > 0) || (array == nullptr && size == 0));
 		m_data = array;
 		m_size = size;
 	}

+ 3 - 3
tests/shader_compiler/ShaderProgramCompiler.cpp

@@ -25,7 +25,7 @@ struct Instanced
 	Foo m_foo[2];
 };
 
-layout(set = 0, binding = 0) uniform ankiMaterial
+layout(push_constant) uniform ankiMaterial
 {
 	Vec4 u_whatever;
 	Instanced u_ankiPerInstance[INSTANCE_COUNT];
@@ -78,7 +78,7 @@ void main()
 	BindlessLimits bindlessLimits;
 	GpuDeviceCapabilities gpuCapabilities;
 	ANKI_TEST_EXPECT_NO_ERR(
-		compileShaderProgram("test.glslp", fsystem, alloc, gpuCapabilities, bindlessLimits, binary));
+		compileShaderProgram("test.glslp", fsystem, nullptr, alloc, gpuCapabilities, bindlessLimits, binary));
 
 #if 1
 	StringAuto dis(alloc);
@@ -233,7 +233,7 @@ void main()
 	BindlessLimits bindlessLimits;
 	GpuDeviceCapabilities gpuCapabilities;
 	ANKI_TEST_EXPECT_NO_ERR(
-		compileShaderProgram("test.glslp", fsystem, alloc, gpuCapabilities, bindlessLimits, binary));
+		compileShaderProgram("test.glslp", fsystem, nullptr, alloc, gpuCapabilities, bindlessLimits, binary));
 
 #if 1
 	StringAuto dis(alloc);