[Bf-blender-cvs] [9560fe60e42] blender2.8: Python API: new GPUShader.format_calc() method

Jacques Lucke noreply at git.blender.org
Tue Oct 9 11:19:16 CEST 2018


Commit: 9560fe60e42d4fe098a24c17f31b6313eaae3364
Author: Jacques Lucke
Date:   Tue Oct 9 11:17:29 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB9560fe60e42d4fe098a24c17f31b6313eaae3364

Python API: new GPUShader.format_calc() method

Reviewers: mano-wii, fclem, campbellbarton

Differential Revision: https://developer.blender.org/D3772

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

M	source/blender/gpu/GPU_vertex_format.h
M	source/blender/gpu/intern/gpu_vertex_format.c
M	source/blender/python/gpu/gpu_py_shader.c

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

diff --git a/source/blender/gpu/GPU_vertex_format.h b/source/blender/gpu/GPU_vertex_format.h
index 5e7e036bf41..113a3e894d0 100644
--- a/source/blender/gpu/GPU_vertex_format.h
+++ b/source/blender/gpu/GPU_vertex_format.h
@@ -80,8 +80,11 @@ typedef struct GPUVertFormat {
 	GPUVertAttr attribs[GPU_VERT_ATTR_MAX_LEN]; /* TODO: variable-size attribs array */
 } GPUVertFormat;
 
+struct GPUShaderInterface;
+
 void GPU_vertformat_clear(GPUVertFormat *);
 void GPU_vertformat_copy(GPUVertFormat *dest, const GPUVertFormat *src);
+void GPU_vertformat_from_interface(GPUVertFormat *format, const struct GPUShaderInterface *shaderface);
 
 uint GPU_vertformat_attr_add(
         GPUVertFormat *, const char *name,
diff --git a/source/blender/gpu/intern/gpu_vertex_format.c b/source/blender/gpu/intern/gpu_vertex_format.c
index f1aaa99fbc6..c3de3d52b47 100644
--- a/source/blender/gpu/intern/gpu_vertex_format.c
+++ b/source/blender/gpu/intern/gpu_vertex_format.c
@@ -29,6 +29,8 @@
  * GPU vertex format
  */
 
+#include "GPU_shader_interface.h"
+
 #include "GPU_vertex_format.h"
 #include "gpu_vertex_format_private.h"
 #include <stddef.h>
@@ -278,6 +280,115 @@ void VertexFormat_pack(GPUVertFormat *format)
 	format->packed = true;
 }
 
+static uint calc_input_component_size(const GPUShaderInput *input)
+{
+	int size = input->size;
+	switch (input->gl_type) {
+		case GL_FLOAT_VEC2:
+		case GL_INT_VEC2:
+		case GL_UNSIGNED_INT_VEC2:
+			return size * 2;
+		case GL_FLOAT_VEC3:
+		case GL_INT_VEC3:
+		case GL_UNSIGNED_INT_VEC3:
+			return size * 3;
+		case GL_FLOAT_VEC4:
+		case GL_FLOAT_MAT2:
+		case GL_INT_VEC4:
+		case GL_UNSIGNED_INT_VEC4:
+			return size * 4;
+		case GL_FLOAT_MAT3:
+			return size * 9;
+		case GL_FLOAT_MAT4:
+			return size * 16;
+		case GL_FLOAT_MAT2x3:
+		case GL_FLOAT_MAT3x2:
+			return size * 6;
+		case GL_FLOAT_MAT2x4:
+		case GL_FLOAT_MAT4x2:
+			return size * 8;
+		case GL_FLOAT_MAT3x4:
+		case GL_FLOAT_MAT4x3:
+			return size * 12;
+		default:
+			return size;
+	}
+}
+
+static void get_fetch_mode_and_comp_type(
+        int gl_type,
+        GPUVertCompType *r_comp_type,
+        uint *r_gl_comp_type,
+        GPUVertFetchMode *r_fetch_mode)
+{
+	switch (gl_type) {
+		case GL_FLOAT:
+		case GL_FLOAT_VEC2:
+		case GL_FLOAT_VEC3:
+		case GL_FLOAT_VEC4:
+		case GL_FLOAT_MAT2:
+		case GL_FLOAT_MAT3:
+		case GL_FLOAT_MAT4:
+		case GL_FLOAT_MAT2x3:
+		case GL_FLOAT_MAT2x4:
+		case GL_FLOAT_MAT3x2:
+		case GL_FLOAT_MAT3x4:
+		case GL_FLOAT_MAT4x2:
+		case GL_FLOAT_MAT4x3:
+			*r_comp_type = GPU_COMP_F32;
+			*r_gl_comp_type = GL_FLOAT;
+			*r_fetch_mode = GPU_FETCH_FLOAT;
+			break;
+		case GL_INT:
+		case GL_INT_VEC2:
+		case GL_INT_VEC3:
+		case GL_INT_VEC4:
+			*r_comp_type = GPU_COMP_I32;
+			*r_gl_comp_type = GL_INT;
+			*r_fetch_mode = GPU_FETCH_INT;
+			break;
+		case GL_UNSIGNED_INT:
+		case GL_UNSIGNED_INT_VEC2:
+		case GL_UNSIGNED_INT_VEC3:
+		case GL_UNSIGNED_INT_VEC4:
+			*r_comp_type = GPU_COMP_U32;
+			*r_gl_comp_type = GL_UNSIGNED_INT;
+			*r_fetch_mode = GPU_FETCH_INT;
+			break;
+		default:
+			BLI_assert(0);
+	}
+}
+
+void GPU_vertformat_from_interface(GPUVertFormat *format, const GPUShaderInterface *shaderface)
+{
+	const char *name_buffer = shaderface->name_buffer;
+
+	for (int i = 0; i < GPU_NUM_SHADERINTERFACE_BUCKETS; i++) {
+		const GPUShaderInput *input = shaderface->attrib_buckets[i];
+		if (input == NULL) {
+			continue;
+		}
+
+		const GPUShaderInput *next = input;
+		while (next != NULL) {
+			input = next;
+			next = input->next;
+
+			format->name_len++; /* multiname support */
+			format->attr_len++;
+
+			GPUVertAttr *attrib = format->attribs + input->location;
+
+			attrib->name[attrib->name_len++] = copy_attrib_name(format, name_buffer + input->name_offset);
+			attrib->offset = 0; /* offsets & stride are calculated later (during pack) */
+			attrib->comp_len = calc_input_component_size(input);
+			attrib->sz = attrib->comp_len * 4;
+			get_fetch_mode_and_comp_type(input->gl_type, &attrib->comp_type, &attrib->gl_comp_type, &attrib->fetch_mode);
+		}
+	}
+}
+
 
 /* OpenGL ES packs in a different order as desktop GL but component conversion is the same.
  * Of the code here, only struct GPUPackedNormal needs to change. */
diff --git a/source/blender/python/gpu/gpu_py_shader.c b/source/blender/python/gpu/gpu_py_shader.c
index 64b208ed49f..154c2f8caf1 100644
--- a/source/blender/python/gpu/gpu_py_shader.c
+++ b/source/blender/python/gpu/gpu_py_shader.c
@@ -36,6 +36,7 @@
 #include "../generic/python_utildefines.h"
 
 #include "gpu_py_shader.h" /* own include */
+#include "gpu_py_vertex_format.h"
 
 
  /* -------------------------------------------------------------------- */
@@ -569,6 +570,21 @@ static PyObject *bpygpu_shader_attr_from_name(
 	return PyLong_FromLong(attrib);
 }
 
+PyDoc_STRVAR(bpygpu_shader_calc_format_doc,
+".. method:: calc_format()\n"
+"\n"
+"   Build a new format based on the attributes of the shader.\n"
+"\n"
+"   :return: vertex attribute format for the shader\n"
+"   :rtype: GPUVertFormat\n"
+);
+static PyObject *bpygpu_shader_calc_format(BPyGPUShader *self, PyObject *UNUSED(arg))
+{
+	BPyGPUVertFormat *ret = (BPyGPUVertFormat *)BPyGPUVertFormat_CreatePyObject(NULL);
+	GPU_vertformat_from_interface(&ret->fmt, GPU_shader_get_interface(self->shader));
+	return (PyObject *)ret;
+}
+
 static struct PyMethodDef bpygpu_shader_methods[] = {
 	{"bind", (PyCFunction)bpygpu_shader_bind,
 	 METH_NOARGS, bpygpu_shader_bind_doc},
@@ -602,6 +618,9 @@ static struct PyMethodDef bpygpu_shader_methods[] = {
 	{"attr_from_name",
 	 (PyCFunction)bpygpu_shader_attr_from_name,
 	 METH_O, bpygpu_shader_attr_from_name_doc},
+	{"format_calc",
+	 (PyCFunction)bpygpu_shader_calc_format,
+	 METH_NOARGS, bpygpu_shader_calc_format_doc},
 	{NULL, NULL, 0, NULL}
 };



More information about the Bf-blender-cvs mailing list