diff options
author | Jacques Lucke <mail@jlucke.com> | 2018-10-09 12:17:29 +0300 |
---|---|---|
committer | Jacques Lucke <mail@jlucke.com> | 2018-10-09 12:17:29 +0300 |
commit | 9560fe60e42d4fe098a24c17f31b6313eaae3364 (patch) | |
tree | 03e12f53792db7bc55c53523bc29bb1141f55bf0 /source/blender | |
parent | 1b910082a0effdeb06653203b1d773094a2068e5 (diff) |
Python API: new GPUShader.format_calc() method
Reviewers: mano-wii, fclem, campbellbarton
Differential Revision: https://developer.blender.org/D3772
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/gpu/GPU_vertex_format.h | 3 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_vertex_format.c | 111 | ||||
-rw-r--r-- | source/blender/python/gpu/gpu_py_shader.c | 19 |
3 files changed, 133 insertions, 0 deletions
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} }; |