diff --git a/source/blender/gpu/GPU_shader.hh b/source/blender/gpu/GPU_shader.hh index 1a0d733e4da..94d073b1385 100644 --- a/source/blender/gpu/GPU_shader.hh +++ b/source/blender/gpu/GPU_shader.hh @@ -206,12 +206,14 @@ void GPU_shader_uniform_4fv_array(GPUShader *sh, const char *name, int len, cons * Used to create #GPUVertexFormat from the shader's vertex input layout. * \{ */ -unsigned int GPU_shader_get_attribute_len(const GPUShader *shader); +uint GPU_shader_get_attribute_len(const GPUShader *shader); +uint GPU_shader_get_ssbo_input_len(const GPUShader *shader); int GPU_shader_get_attribute(const GPUShader *shader, const char *name); bool GPU_shader_get_attribute_info(const GPUShader *shader, int attr_location, char r_name[256], int *r_type); +bool GPU_shader_get_ssbo_input_info(const GPUShader *shader, int ssbo_location, char r_name[256]); /** \} */ diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc index eb4223ab99b..9febd9d97f3 100644 --- a/source/blender/gpu/intern/gpu_shader.cc +++ b/source/blender/gpu/intern/gpu_shader.cc @@ -664,6 +664,12 @@ uint GPU_shader_get_attribute_len(const GPUShader *shader) return interface->attr_len_; } +uint GPU_shader_get_ssbo_input_len(const GPUShader *shader) +{ + const ShaderInterface *interface = unwrap(shader)->interface; + return interface->ssbo_len_; +} + int GPU_shader_get_attribute(const GPUShader *shader, const char *name) { const ShaderInterface *interface = unwrap(shader)->interface; @@ -688,6 +694,19 @@ bool GPU_shader_get_attribute_info(const GPUShader *shader, return true; } +bool GPU_shader_get_ssbo_input_info(const GPUShader *shader, int ssbo_location, char r_name[256]) +{ + const ShaderInterface *interface = unwrap(shader)->interface; + + const ShaderInput *ssbo_input = interface->ssbo_get(ssbo_location); + if (!ssbo_input) { + return false; + } + + BLI_strncpy(r_name, interface->input_name_get(ssbo_input), 256); + return true; +} + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/python/gpu/gpu_py_shader.cc b/source/blender/python/gpu/gpu_py_shader.cc index f9f4928e815..d6f67c0a032 100644 --- a/source/blender/python/gpu/gpu_py_shader.cc +++ b/source/blender/python/gpu/gpu_py_shader.cc @@ -700,30 +700,67 @@ PyDoc_STRVAR( " :rtype: tuple[tuple[str, str | None], ...]\n"); static PyObject *pygpu_shader_attrs_info_get(BPyGPUShader *self, PyObject * /*arg*/) { - uint attr_len = GPU_shader_get_attribute_len(self->shader); + using namespace blender::gpu::shader; + PyObject *ret; + int type; int location_test = 0, attrs_added = 0; + char name[256]; - PyObject *ret = PyTuple_New(attr_len); - while (attrs_added < attr_len) { - char name[256]; - int type; - if (!GPU_shader_get_attribute_info(self->shader, location_test++, name, &type)) { - continue; - } - PyObject *py_type; - if (type != -1) { - py_type = PyUnicode_InternFromString( - PyC_StringEnum_FindIDFromValue(pygpu_attrtype_items, type)); - } - else { - py_type = Py_None; - Py_INCREF(py_type); - } + if (bpygpu_shader_is_polyline(self->shader)) { + /* WORKAROUND: Special case for POLYLINE shader. Check the SSBO inputs as attributes. */ + uint input_len = GPU_shader_get_ssbo_input_len(self->shader); - PyObject *attr_info = PyTuple_New(2); - PyTuple_SET_ITEMS(attr_info, PyUnicode_FromString(name), py_type); - PyTuple_SetItem(ret, attrs_added, attr_info); - attrs_added++; + /* Skip "gpu_index_buf". */ + input_len -= 1; + ret = PyTuple_New(input_len); + while (attrs_added < input_len) { + if (!GPU_shader_get_ssbo_input_info(self->shader, location_test++, name)) { + continue; + } + if (STREQ(name, "gpu_index_buf")) { + continue; + } + + type = STREQ(name, "pos") ? int(Type::VEC3) : STREQ(name, "color") ? int(Type::VEC4) : -1; + PyObject *py_type; + if (type != -1) { + py_type = PyUnicode_InternFromString( + PyC_StringEnum_FindIDFromValue(pygpu_attrtype_items, type)); + } + else { + py_type = Py_None; + Py_INCREF(py_type); + } + + PyObject *attr_info = PyTuple_New(2); + PyTuple_SET_ITEMS(attr_info, PyUnicode_FromString(name), py_type); + PyTuple_SetItem(ret, attrs_added, attr_info); + attrs_added++; + } + } + else { + uint attr_len = GPU_shader_get_attribute_len(self->shader); + + ret = PyTuple_New(attr_len); + while (attrs_added < attr_len) { + if (!GPU_shader_get_attribute_info(self->shader, location_test++, name, &type)) { + continue; + } + PyObject *py_type; + if (type != -1) { + py_type = PyUnicode_InternFromString( + PyC_StringEnum_FindIDFromValue(pygpu_attrtype_items, type)); + } + else { + py_type = Py_None; + Py_INCREF(py_type); + } + + PyObject *attr_info = PyTuple_New(2); + PyTuple_SET_ITEMS(attr_info, PyUnicode_FromString(name), py_type); + PyTuple_SetItem(ret, attrs_added, attr_info); + attrs_added++; + } } return ret; } @@ -1099,4 +1136,12 @@ PyObject *bpygpu_shader_init() return submodule; } +bool bpygpu_shader_is_polyline(GPUShader *shader) +{ + return ELEM(shader, + GPU_shader_get_builtin_shader(GPU_SHADER_3D_POLYLINE_FLAT_COLOR), + GPU_shader_get_builtin_shader(GPU_SHADER_3D_POLYLINE_SMOOTH_COLOR), + GPU_shader_get_builtin_shader(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR)); +} + /** \} */ diff --git a/source/blender/python/gpu/gpu_py_shader.hh b/source/blender/python/gpu/gpu_py_shader.hh index dd90a1fdd79..8db67515fcd 100644 --- a/source/blender/python/gpu/gpu_py_shader.hh +++ b/source/blender/python/gpu/gpu_py_shader.hh @@ -68,3 +68,4 @@ struct BPyGPUShaderCreateInfo { PyObject *BPyGPUStageInterfaceInfo_CreatePyObject(GPUStageInterfaceInfo *interface); PyObject *BPyGPUShaderCreateInfo_CreatePyObject(GPUShaderCreateInfo *info); +bool bpygpu_shader_is_polyline(GPUShader *shader);