Explorar el Código

GL push constants work

Panagiotis Christopoulos Charitos hace 7 años
padre
commit
93fcca9cb0

+ 1 - 1
src/anki/gr/ShaderCompiler.cpp

@@ -296,7 +296,7 @@ Error ShaderCompiler::compile(CString source, const ShaderCompilerOptions& optio
 		MAX_STORAGE_BUFFER_BINDINGS,
 		MAX_TEXTURE_BINDINGS,
 		MAX_IMAGE_BINDINGS,
-		MAX_TEXTURE_BINDINGS, // Push constant location
+		MAX_TEXTURE_BINDINGS * MAX_DESCRIPTOR_SETS, // Push constant location
 		// VK bindings
 		0,
 		MAX_TEXTURE_BINDINGS,

+ 6 - 7
src/anki/gr/gl/CommandBuffer.cpp

@@ -1509,30 +1509,29 @@ void CommandBuffer::setPushConstants(const void* data, U32 dataSize)
 
 			for(const ShaderProgramImplReflection::Uniform& uni : refl.m_uniforms)
 			{
-				ANKI_ASSERT(U(uni.m_location) >= MAX_TEXTURE_BINDINGS);
-				const U idx = uni.m_location - MAX_TEXTURE_BINDINGS;
+				const U8* data = reinterpret_cast<const U8*>(&m_data[0]) + uni.m_pushConstantOffset;
 				const U count = uni.m_arrSize;
 				const GLint loc = uni.m_location;
 
 				switch(uni.m_type)
 				{
 				case ShaderVariableDataType::VEC4:
-					glUniform4fv(loc, count, reinterpret_cast<const GLfloat*>(&m_data[idx]));
+					glUniform4fv(loc, count, reinterpret_cast<const GLfloat*>(data));
 					break;
 				case ShaderVariableDataType::IVEC4:
-					glUniform4iv(loc, count, reinterpret_cast<const GLint*>(&m_data[idx]));
+					glUniform4iv(loc, count, reinterpret_cast<const GLint*>(data));
 					break;
 				case ShaderVariableDataType::UVEC4:
-					glUniform4uiv(loc, count, reinterpret_cast<const GLuint*>(&m_data[idx]));
+					glUniform4uiv(loc, count, reinterpret_cast<const GLuint*>(data));
 					break;
 				case ShaderVariableDataType::MAT4:
-					glUniformMatrix4fv(loc, count, false, reinterpret_cast<const GLfloat*>(&m_data[idx]));
+					glUniformMatrix4fv(loc, count, false, reinterpret_cast<const GLfloat*>(data));
 					break;
 				case ShaderVariableDataType::MAT3:
 				{
 					// Remove the padding
 					ANKI_ASSERT(count == 1 && "TODO");
-					const Mat3x4* m34 = reinterpret_cast<const Mat3x4*>(&m_data[idx][0]);
+					const Mat3x4* m34 = reinterpret_cast<const Mat3x4*>(data);
 					Mat3 m3(m34->getRotationPart());
 					glUniformMatrix3fv(loc, count, false, reinterpret_cast<const GLfloat*>(&m3));
 					break;

+ 44 - 7
src/anki/gr/gl/ShaderProgramImpl.cpp

@@ -114,34 +114,39 @@ const ShaderProgramImplReflection& ShaderProgramImpl::getReflection()
 			GLint size;
 			Array<char, 128> name;
 			glGetActiveUniform(getGlName(), i, sizeof(name), &len, &size, &type, &name[0]);
-
 			name[len] = '\0';
+
+			if(CString(&name[0]).find("gl_") == 0)
+			{
+				// Builtin, skip
+				continue;
+			}
+
 			GLint location = glGetUniformLocation(getGlName(), &name[0]);
+			if(location < I(MAX_TEXTURE_BINDINGS * MAX_DESCRIPTOR_SETS))
+			{
+				// It must be a sampled image, skip it
+				continue;
+			}
 
 			// Store those info
 			ShaderVariableDataType akType = ShaderVariableDataType::NONE;
-			U32 dataSize = 0;
 			switch(type)
 			{
 			case GL_FLOAT_VEC4:
 				akType = ShaderVariableDataType::VEC4;
-				dataSize = 16;
 				break;
 			case GL_INT_VEC4:
 				akType = ShaderVariableDataType::IVEC4;
-				dataSize = 16;
 				break;
 			case GL_UNSIGNED_INT_VEC4:
 				akType = ShaderVariableDataType::UVEC4;
-				dataSize = 16;
 				break;
 			case GL_FLOAT_MAT4:
 				akType = ShaderVariableDataType::MAT4;
-				dataSize = 16 * 4;
 				break;
 			case GL_FLOAT_MAT3:
 				akType = ShaderVariableDataType::MAT3;
-				dataSize = 16 * 3;
 				break;
 			default:
 				ANKI_ASSERT(!"Unsupported type");
@@ -153,6 +158,38 @@ const ShaderProgramImplReflection& ShaderProgramImpl::getReflection()
 			uni.m_arrSize = size;
 
 			m_refl.m_uniforms.emplaceBack(getAllocator(), uni);
+		}
+
+		// Sort the uniforms
+		std::sort(m_refl.m_uniforms.getBegin(),
+			m_refl.m_uniforms.getEnd(),
+			[](const ShaderProgramImplReflection::Uniform& a, const ShaderProgramImplReflection::Uniform& b) {
+				return a.m_location < b.m_location;
+			});
+
+		// Now calculate the offset inside the push constant buffer
+		m_refl.m_uniformDataSize = 0;
+		for(ShaderProgramImplReflection::Uniform& uni : m_refl.m_uniforms)
+		{
+			U32 dataSize = 0;
+			switch(uni.m_type)
+			{
+			case ShaderVariableDataType::VEC4:
+			case ShaderVariableDataType::IVEC4:
+			case ShaderVariableDataType::UVEC4:
+				dataSize = sizeof(F32) * 4;
+				break;
+			case ShaderVariableDataType::MAT4:
+				dataSize = sizeof(F32) * 16;
+				break;
+			case ShaderVariableDataType::MAT3:
+				dataSize = sizeof(F32) * 12;
+				break;
+			default:
+				ANKI_ASSERT(!"Unsupported type");
+			}
+
+			uni.m_pushConstantOffset = m_refl.m_uniformDataSize;
 			m_refl.m_uniformDataSize += dataSize * uni.m_arrSize;
 		}
 	}

+ 1 - 0
src/anki/gr/gl/ShaderProgramImpl.h

@@ -20,6 +20,7 @@ public:
 	struct Uniform
 	{
 		I32 m_location;
+		U32 m_pushConstantOffset;
 		ShaderVariableDataType m_type;
 		U8 m_arrSize;
 	};