[Bf-blender-cvs] [a5afe13e1c4] blender2.8: GWN: Add support for 4x4 Matrices and instancing attributes.

Clément Foucault noreply at git.blender.org
Wed Feb 14 19:02:28 CET 2018


Commit: a5afe13e1c42eedcd9b26e172292c3ba58640679
Author: Clément Foucault
Date:   Sun Feb 11 05:14:35 2018 +0100
Branches: blender2.8
https://developer.blender.org/rBa5afe13e1c42eedcd9b26e172292c3ba58640679

GWN: Add support for 4x4 Matrices and instancing attributes.

Only support float matrices specifically for code simplicity.

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

M	intern/gawain/gawain/gwn_vertex_format.h
M	intern/gawain/src/gwn_batch.c
M	intern/gawain/src/gwn_vertex_format.c

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

diff --git a/intern/gawain/gawain/gwn_vertex_format.h b/intern/gawain/gawain/gwn_vertex_format.h
index 348e6399afa..45c86498172 100644
--- a/intern/gawain/gawain/gwn_vertex_format.h
+++ b/intern/gawain/gawain/gwn_vertex_format.h
@@ -41,8 +41,8 @@ typedef enum {
 typedef struct Gwn_VertAttr {
 	Gwn_VertCompType comp_type;
 	unsigned gl_comp_type;
-	unsigned comp_ct; // 1 to 4
-	unsigned sz; // size in bytes, 1 to 16
+	unsigned comp_ct; // 1 to 4 or 16
+	unsigned sz; // size in bytes, 1 to 64
 	unsigned offset; // from beginning of vertex, in bytes
 	Gwn_VertFetchMode fetch_mode;
 	const char* name[MAX_ATTRIB_NAMES];
diff --git a/intern/gawain/src/gwn_batch.c b/intern/gawain/src/gwn_batch.c
index 3b7cdd1fa8d..c15591abc79 100644
--- a/intern/gawain/src/gwn_batch.c
+++ b/intern/gawain/src/gwn_batch.c
@@ -118,13 +118,8 @@ void GWN_batch_program_unset(Gwn_Batch* batch)
 	batch->program_in_use = false;
 	}
 
-static void Batch_update_program_bindings(Gwn_Batch* batch, unsigned int v_first)
+static void create_bindings(Gwn_Batch* batch, const Gwn_ShaderInterface* interface, unsigned int v_first, const bool use_instancing)
 	{
-	// disable all as a precaution
-	// why are we not using prev_attrib_enabled_bits?? see immediate.c
-	for (unsigned a_idx = 0; a_idx < GWN_VERT_ATTR_MAX_LEN; ++a_idx)
-		glDisableVertexAttribArray(a_idx);
-
 	for (int v = 0; v < GWN_BATCH_VBO_MAX_LEN; ++v)
 		{
 		Gwn_VertBuf* verts = batch->verts[v];
@@ -146,27 +141,68 @@ static void Batch_update_program_bindings(Gwn_Batch* batch, unsigned int v_first
 
 			for (unsigned n_idx = 0; n_idx < a->name_ct; ++n_idx)
 				{
-				const Gwn_ShaderInput* input = GWN_shaderinterface_attr(batch->interface, a->name[n_idx]);
+				const Gwn_ShaderInput* input = GWN_shaderinterface_attr(interface, a->name[n_idx]);
 
 				if (input == NULL) continue;
 
-				glEnableVertexAttribArray(input->location);
-
-				switch (a->fetch_mode)
+				if (a->comp_ct == 16) // Mat4 case
 					{
-					case GWN_FETCH_FLOAT:
-					case GWN_FETCH_INT_TO_FLOAT:
-						glVertexAttribPointer(input->location, a->comp_ct, a->gl_comp_type, GL_FALSE, stride, pointer);
-						break;
-					case GWN_FETCH_INT_TO_FLOAT_UNIT:
-						glVertexAttribPointer(input->location, a->comp_ct, a->gl_comp_type, GL_TRUE, stride, pointer);
-						break;
-					case GWN_FETCH_INT:
-						glVertexAttribIPointer(input->location, a->comp_ct, a->gl_comp_type, stride, pointer);
+#if TRUST_NO_ONE
+					assert(a->fetch_mode == GWN_FETCH_FLOAT);
+					assert(a->gl_comp_type == GL_FLOAT);
+#endif
+					for (int i = 0; i < 4; ++i)
+						{
+						glEnableVertexAttribArray(input->location + i);
+						glVertexAttribDivisor(input->location + i, (use_instancing) ? 1 : 0);
+						glVertexAttribPointer(input->location + i, 4, a->gl_comp_type, GL_FALSE, stride,
+						                      (const GLubyte*)pointer + i * 16);
+						}
+					}
+				else
+					{
+					glEnableVertexAttribArray(input->location);
+					glVertexAttribDivisor(input->location, (use_instancing) ? 1 : 0);
+
+					switch (a->fetch_mode)
+						{
+						case GWN_FETCH_FLOAT:
+						case GWN_FETCH_INT_TO_FLOAT:
+							glVertexAttribPointer(input->location, a->comp_ct, a->gl_comp_type, GL_FALSE, stride, pointer);
+							break;
+						case GWN_FETCH_INT_TO_FLOAT_UNIT:
+							glVertexAttribPointer(input->location, a->comp_ct, a->gl_comp_type, GL_TRUE, stride, pointer);
+							break;
+						case GWN_FETCH_INT:
+							glVertexAttribIPointer(input->location, a->comp_ct, a->gl_comp_type, stride, pointer);
+						}
 					}
 				}
 			}
 		}
+	}
+
+static void Batch_update_program_bindings(Gwn_Batch* batch, unsigned int v_first)
+	{
+	// disable all as a precaution
+	// why are we not using prev_attrib_enabled_bits?? see immediate.c
+	for (unsigned a_idx = 0; a_idx < GWN_VERT_ATTR_MAX_LEN; ++a_idx)
+		glDisableVertexAttribArray(a_idx);
+
+	create_bindings(batch, batch->interface, v_first, false);
+
+	batch->program_dirty = false;
+	}
+
+static void Batch_update_program_bindings_instancing(Gwn_Batch* batch, Gwn_Batch* batch_instancing, unsigned int v_first)
+	{
+	// disable all as a precaution
+	// why are we not using prev_attrib_enabled_bits?? see immediate.c
+	for (unsigned a_idx = 0; a_idx < GWN_VERT_ATTR_MAX_LEN; ++a_idx)
+		glDisableVertexAttribArray(a_idx);
+
+	create_bindings(batch, batch->interface, v_first, false);
+	create_bindings(batch_instancing, batch->interface, v_first, true);
 
 	batch->program_dirty = false;
 	}
@@ -417,51 +453,10 @@ void GWN_batch_draw_stupid_instanced_with_batch(Gwn_Batch* batch_instanced, Gwn_
 		Batch_prime(batch_instanced);
 
 	if (batch_instanced->program_dirty)
-		Batch_update_program_bindings(batch_instanced, 0);
+		Batch_update_program_bindings_instancing(batch_instanced, batch_instancing, 0);
 
 	Gwn_VertBuf* verts = batch_instancing->verts[0];
 
-	const Gwn_VertFormat* format = &verts->format;
-
-	const unsigned attrib_ct = format->attrib_ct;
-	const unsigned stride = format->stride;
-
-	GWN_vertbuf_use(verts);
-
-	for (unsigned a_idx = 0; a_idx < attrib_ct; ++a_idx)
-		{
-		const Gwn_VertAttr* a = format->attribs + a_idx;
-
-		const GLvoid* pointer = (const GLubyte*)0 + a->offset;
-
-		for (unsigned n_idx = 0; n_idx < a->name_ct; ++n_idx)
-			{
-			const Gwn_ShaderInput* input = GWN_shaderinterface_attr(batch_instanced->interface, a->name[n_idx]);
-
-			if (input == NULL) continue;
-
-			glEnableVertexAttribArray(input->location);
-			glVertexAttribDivisor(input->location, 1);
-
-			switch (a->fetch_mode)
-				{
-				case GWN_FETCH_FLOAT:
-				case GWN_FETCH_INT_TO_FLOAT:
-					glVertexAttribPointer(input->location, a->comp_ct, a->gl_comp_type, GL_FALSE, stride, pointer);
-					break;
-				case GWN_FETCH_INT_TO_FLOAT_UNIT:
-					glVertexAttribPointer(input->location, a->comp_ct, a->gl_comp_type, GL_TRUE, stride, pointer);
-					break;
-				case GWN_FETCH_INT:
-					glVertexAttribIPointer(input->location, a->comp_ct, a->gl_comp_type, stride, pointer);
-				}
-			}
-		}
-
-	// GWN_batch_program_use_begin(batch);
-
-	//gpuBindMatrices(batch->program);
-
 	if (batch_instanced->elem)
 		{
 		const Gwn_IndexBuf* el = batch_instanced->elem;
@@ -475,10 +470,5 @@ void GWN_batch_draw_stupid_instanced_with_batch(Gwn_Batch* batch_instanced, Gwn_
 	else
 		glDrawArraysInstanced(batch_instanced->gl_prim_type, 0, batch_instanced->verts[0]->vertex_ct, verts->vertex_ct);
 
-	// Reset divisor to prevent messing the next draw
-	for (unsigned a_idx = 0; a_idx < GWN_VERT_ATTR_MAX_LEN; ++a_idx)
-		glVertexAttribDivisor(a_idx, 0);
-
-	// GWN_batch_program_use_end(batch);
 	glBindVertexArray(0);
 	}
diff --git a/intern/gawain/src/gwn_vertex_format.c b/intern/gawain/src/gwn_vertex_format.c
index d6367935703..36d53f9ee20 100644
--- a/intern/gawain/src/gwn_vertex_format.c
+++ b/intern/gawain/src/gwn_vertex_format.c
@@ -143,7 +143,7 @@ unsigned GWN_vertformat_attr_add(Gwn_VertFormat* format, const char* name, Gwn_V
 	assert(format->name_ct < GWN_VERT_ATTR_MAX_LEN); // there's room for more
 	assert(format->attrib_ct < GWN_VERT_ATTR_MAX_LEN); // there's room for more
 	assert(!format->packed); // packed means frozen/locked
-	assert(comp_ct >= 1 && comp_ct <= 4);
+	assert((comp_ct >= 1 && comp_ct <= 4) || comp_ct == 16);
 	switch (comp_type)
 		{
 		case GWN_COMP_F32:
@@ -159,6 +159,8 @@ unsigned GWN_vertformat_attr_add(Gwn_VertFormat* format, const char* name, Gwn_V
 		default:
 			// integer types can be kept as int or converted/normalized to float
 			assert(fetch_mode != GWN_FETCH_FLOAT);
+			// only support float matrices (see Batch_update_program_bindings)
+			assert(comp_ct != 16);
 		}
 #endif
 	format->name_ct++; // multiname support



More information about the Bf-blender-cvs mailing list