[Bf-blender-cvs] [abd1934be6e] blender2.8: Gawain: use ShaderInterface to manage vertex attribs

Mike Erwin noreply at git.blender.org
Sun Apr 16 00:07:53 CEST 2017


Commit: abd1934be6ebba0a5dbf0a1354d4badcb49cf192
Author: Mike Erwin
Date:   Sat Apr 15 18:06:54 2017 -0400
Branches: blender2.8
https://developer.blender.org/rBabd1934be6ebba0a5dbf0a1354d4badcb49cf192

Gawain: use ShaderInterface to manage vertex attribs

This eliminates tons of glGetAttribLocation calls from the drawing loop. Vast majority of code can keep making the same function calls. They're just faster now!

===================================================================

M	intern/gawain/gawain/attrib_binding.h
M	intern/gawain/gawain/shader_interface.h
M	intern/gawain/src/attrib_binding.c
M	intern/gawain/src/batch.c
M	intern/gawain/src/immediate.c
M	intern/gawain/src/shader_interface.c
M	source/blender/gpu/intern/gpu_shader.c

===================================================================

diff --git a/intern/gawain/gawain/attrib_binding.h b/intern/gawain/gawain/attrib_binding.h
index f1378bff8cc..0642492882a 100644
--- a/intern/gawain/gawain/attrib_binding.h
+++ b/intern/gawain/gawain/attrib_binding.h
@@ -12,6 +12,7 @@
 #pragma once
 
 #include "vertex_format.h"
+#include "shader_interface.h"
 
 typedef struct {
 	uint64_t loc_bits; // store 4 bits for each of the 16 attribs
@@ -20,5 +21,5 @@ typedef struct {
 
 void AttribBinding_clear(AttribBinding*);
 
-void get_attrib_locations(const VertexFormat*, AttribBinding*, GLuint program);
+void get_attrib_locations(const VertexFormat*, AttribBinding*, const ShaderInterface*);
 unsigned read_attrib_location(const AttribBinding*, unsigned a_idx);
diff --git a/intern/gawain/gawain/shader_interface.h b/intern/gawain/gawain/shader_interface.h
index effa4aca90f..32b5098ad80 100644
--- a/intern/gawain/gawain/shader_interface.h
+++ b/intern/gawain/gawain/shader_interface.h
@@ -48,3 +48,4 @@ void ShaderInterface_discard(ShaderInterface*);
 
 const ShaderInput* ShaderInterface_uniform(const ShaderInterface*, const char* name);
 const ShaderInput* ShaderInterface_builtin_uniform(const ShaderInterface*, BuiltinUniform);
+const ShaderInput* ShaderInterface_attrib(const ShaderInterface*, const char* name);
diff --git a/intern/gawain/src/attrib_binding.c b/intern/gawain/src/attrib_binding.c
index c510de497d8..b174bc04f06 100644
--- a/intern/gawain/src/attrib_binding.c
+++ b/intern/gawain/src/attrib_binding.c
@@ -46,24 +46,20 @@ static void write_attrib_location(AttribBinding* binding, unsigned a_idx, unsign
 	binding->enabled_bits |= 1 << a_idx;
 	}
 
-void get_attrib_locations(const VertexFormat* format, AttribBinding* binding, GLuint program)
+void get_attrib_locations(const VertexFormat* format, AttribBinding* binding, const ShaderInterface* shaderface)
 	{
-#if TRUST_NO_ONE
-	assert(glIsProgram(program));
-#endif
-
 	AttribBinding_clear(binding);
 
 	for (unsigned a_idx = 0; a_idx < format->attrib_ct; ++a_idx)
 		{
 		const Attrib* a = format->attribs + a_idx;
-		GLint loc = glGetAttribLocation(program, a->name);
+		const ShaderInput* input = ShaderInterface_attrib(shaderface, a->name);
 
 #if TRUST_NO_ONE
-		assert(loc != -1);
+		assert(input != NULL);
 		// TODO: make this a recoverable runtime error? indicates mismatch between vertex format and program
 #endif
 
-		write_attrib_location(binding, a_idx, loc);
+		write_attrib_location(binding, a_idx, input->location);
 		}
 	}
diff --git a/intern/gawain/src/batch.c b/intern/gawain/src/batch.c
index d4465c7809a..c2aa0f07773 100644
--- a/intern/gawain/src/batch.c
+++ b/intern/gawain/src/batch.c
@@ -127,23 +127,23 @@ static void Batch_update_program_bindings(Batch* batch)
 
 			const GLvoid* pointer = (const GLubyte*)0 + a->offset;
 
-			const GLint loc = glGetAttribLocation(batch->program, a->name);
+			const ShaderInput* input = ShaderInterface_attrib(batch->interface, a->name);
 
-			if (loc == -1) continue;
+			if (input == NULL) continue;
 
-			glEnableVertexAttribArray(loc);
+			glEnableVertexAttribArray(input->location);
 
 			switch (a->fetch_mode)
 				{
 				case KEEP_FLOAT:
 				case CONVERT_INT_TO_FLOAT:
-					glVertexAttribPointer(loc, a->comp_ct, a->gl_comp_type, GL_FALSE, stride, pointer);
+					glVertexAttribPointer(input->location, a->comp_ct, a->gl_comp_type, GL_FALSE, stride, pointer);
 					break;
 				case NORMALIZE_INT_TO_FLOAT:
-					glVertexAttribPointer(loc, a->comp_ct, a->gl_comp_type, GL_TRUE, stride, pointer);
+					glVertexAttribPointer(input->location, a->comp_ct, a->gl_comp_type, GL_TRUE, stride, pointer);
 					break;
 				case KEEP_INT:
-					glVertexAttribIPointer(loc, a->comp_ct, a->gl_comp_type, stride, pointer);
+					glVertexAttribIPointer(input->location, a->comp_ct, a->gl_comp_type, stride, pointer);
 				}
 			}
 		}
diff --git a/intern/gawain/src/immediate.c b/intern/gawain/src/immediate.c
index 3ec4c8ac79e..95414021091 100644
--- a/intern/gawain/src/immediate.c
+++ b/intern/gawain/src/immediate.c
@@ -133,7 +133,7 @@ void immBindProgram(GLuint program, const ShaderInterface* shaderface)
 		VertexFormat_pack(&imm.vertex_format);
 
 	glUseProgram(program);
-	get_attrib_locations(&imm.vertex_format, &imm.attrib_binding, program);
+	get_attrib_locations(&imm.vertex_format, &imm.attrib_binding, shaderface);
 	gpuBindMatrices(shaderface);
 	}
 
diff --git a/intern/gawain/src/shader_interface.c b/intern/gawain/src/shader_interface.c
index d1f6031c480..5e55ceed992 100644
--- a/intern/gawain/src/shader_interface.c
+++ b/intern/gawain/src/shader_interface.c
@@ -181,3 +181,21 @@ const ShaderInput* ShaderInterface_builtin_uniform(const ShaderInterface* shader
 	// TODO: look up by enum, not name (fix setup_builtin_uniform first)
 	return ShaderInterface_uniform(shaderface, BuiltinUniform_name(builtin));
 	}
+
+const ShaderInput* ShaderInterface_attrib(const ShaderInterface* shaderface, const char* name)
+	{
+	// attribs are stored after uniforms
+	const uint32_t input_ct = shaderface->uniform_ct + shaderface->attrib_ct;
+	for (uint32_t i = shaderface->uniform_ct; i < input_ct; ++i)
+		{
+		const ShaderInput* attrib = shaderface->inputs + i;
+
+#if SUPPORT_LEGACY_GLSL
+		if (attrib->name == NULL) continue;
+#endif
+
+		if (strcmp(attrib->name, name) == 0)
+			return attrib;
+		}
+	return NULL; // not found
+	}
diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c
index 2a0e434537f..a3668eb156b 100644
--- a/source/blender/gpu/intern/gpu_shader.c
+++ b/source/blender/gpu/intern/gpu_shader.c
@@ -632,8 +632,8 @@ void GPU_shader_uniform_texture(GPUShader *UNUSED(shader), int location, GPUText
 int GPU_shader_get_attribute(GPUShader *shader, const char *name)
 {
 	BLI_assert(shader && shader->program);
-
-	return glGetAttribLocation(shader->program, name);
+	const ShaderInput *attrib = ShaderInterface_attrib(shader->interface, name);
+	return attrib ? attrib->location : -1;
 }
 
 GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)




More information about the Bf-blender-cvs mailing list