Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGermano Cavalcante <mano-wii>2022-09-01 14:21:10 +0300
committerGermano Cavalcante <germano.costa@ig.com.br>2022-09-01 14:25:55 +0300
commit6269d66da29ae000f214e775ee54dfc71623e642 (patch)
treecbf2fb0f29c3d770ede527e844a1e749f78c5522 /source/blender/gpu
parent05fe7ca5af93208e56e3b120fa9caf157f43fc75 (diff)
PyGPU: GPUShader: implementation of 'attrs_info_get' method
With the new `attrs_info_get` method, we can get information about the attributes used in a `GPUShader` and thus have more freedom in the automatic creation of `GPUVertFormat`s Reviewed By: fclem, campbellbarton Differential Revision: https://developer.blender.org/D15764
Diffstat (limited to 'source/blender/gpu')
-rw-r--r--source/blender/gpu/GPU_shader.h5
-rw-r--r--source/blender/gpu/intern/gpu_shader.cc23
-rw-r--r--source/blender/gpu/intern/gpu_shader_interface.hh12
-rw-r--r--source/blender/gpu/intern/gpu_shader_private.hh2
-rw-r--r--source/blender/gpu/intern/gpu_vertex_format.cc81
-rw-r--r--source/blender/gpu/opengl/gl_shader.cc102
-rw-r--r--source/blender/gpu/opengl/gl_shader.hh2
-rw-r--r--source/blender/gpu/opengl/gl_shader_interface.cc54
8 files changed, 173 insertions, 108 deletions
diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h
index 529a3da3ab9..e1f9d1663f6 100644
--- a/source/blender/gpu/GPU_shader.h
+++ b/source/blender/gpu/GPU_shader.h
@@ -191,7 +191,12 @@ void GPU_shader_uniform_mat3_as_mat4(GPUShader *sh, const char *name, const floa
void GPU_shader_uniform_2fv_array(GPUShader *sh, const char *name, int len, const float (*val)[2]);
void GPU_shader_uniform_4fv_array(GPUShader *sh, const char *name, int len, const float (*val)[4]);
+unsigned int GPU_shader_get_attribute_len(const GPUShader *shader);
int GPU_shader_get_attribute(GPUShader *shader, const char *name);
+bool GPU_shader_get_attribute_info(const GPUShader *shader,
+ int attr_location,
+ char r_name[256],
+ int *r_type);
void GPU_shader_set_framebuffer_srgb_target(int use_srgb_to_linear);
diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc
index 08c768b28ba..2d1b3dc2dca 100644
--- a/source/blender/gpu/intern/gpu_shader.cc
+++ b/source/blender/gpu/intern/gpu_shader.cc
@@ -612,6 +612,12 @@ int GPU_shader_get_texture_binding(GPUShader *shader, const char *name)
return tex ? tex->binding : -1;
}
+uint GPU_shader_get_attribute_len(const GPUShader *shader)
+{
+ ShaderInterface *interface = unwrap(shader)->interface;
+ return interface->attr_len_;
+}
+
int GPU_shader_get_attribute(GPUShader *shader, const char *name)
{
ShaderInterface *interface = unwrap(shader)->interface;
@@ -619,6 +625,23 @@ int GPU_shader_get_attribute(GPUShader *shader, const char *name)
return attr ? attr->location : -1;
}
+bool GPU_shader_get_attribute_info(const GPUShader *shader,
+ int attr_location,
+ char r_name[256],
+ int *r_type)
+{
+ ShaderInterface *interface = unwrap(shader)->interface;
+
+ const ShaderInput *attr = interface->attr_get(attr_location);
+ if (!attr) {
+ return false;
+ }
+
+ BLI_strncpy(r_name, interface->input_name_get(attr), 256);
+ *r_type = attr->location != -1 ? interface->attr_types_[attr->location] : -1;
+ return true;
+}
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/gpu/intern/gpu_shader_interface.hh b/source/blender/gpu/intern/gpu_shader_interface.hh
index 812244c9b3a..41e06569bdc 100644
--- a/source/blender/gpu/intern/gpu_shader_interface.hh
+++ b/source/blender/gpu/intern/gpu_shader_interface.hh
@@ -18,6 +18,7 @@
#include "BLI_utildefines.h"
#include "GPU_shader.h"
+#include "GPU_vertex_format.h" /* GPU_VERT_ATTR_MAX_LEN */
#include "gpu_shader_create_info.hh"
namespace blender::gpu {
@@ -58,6 +59,13 @@ class ShaderInterface {
int32_t builtin_blocks_[GPU_NUM_UNIFORM_BLOCKS];
int32_t builtin_buffers_[GPU_NUM_STORAGE_BUFFERS];
+ /**
+ * Currently only used for `GPU_shader_get_attribute_info`.
+ * This utility is useful for automatic creation of `GPUVertFormat` in Python.
+ * Use `ShaderInput::location` to identify the `Type`.
+ */
+ uint8_t attr_types_[GPU_VERT_ATTR_MAX_LEN];
+
public:
ShaderInterface();
ShaderInterface(const shader::ShaderCreateInfo &info);
@@ -69,6 +77,10 @@ class ShaderInterface {
{
return input_lookup(inputs_, attr_len_, name);
}
+ inline const ShaderInput *attr_get(const int binding) const
+ {
+ return input_lookup(inputs_, attr_len_, binding);
+ }
inline const ShaderInput *ubo_get(const char *name) const
{
diff --git a/source/blender/gpu/intern/gpu_shader_private.hh b/source/blender/gpu/intern/gpu_shader_private.hh
index 4d318093c98..a822cd8aa38 100644
--- a/source/blender/gpu/intern/gpu_shader_private.hh
+++ b/source/blender/gpu/intern/gpu_shader_private.hh
@@ -55,8 +55,6 @@ class Shader {
virtual void uniform_float(int location, int comp_len, int array_size, const float *data) = 0;
virtual void uniform_int(int location, int comp_len, int array_size, const int *data) = 0;
- virtual void vertformat_from_shader(GPUVertFormat *) const = 0;
-
std::string defines_declare(const shader::ShaderCreateInfo &info) const;
virtual std::string resources_declare(const shader::ShaderCreateInfo &info) const = 0;
virtual std::string vertex_interface_declare(const shader::ShaderCreateInfo &info) const = 0;
diff --git a/source/blender/gpu/intern/gpu_vertex_format.cc b/source/blender/gpu/intern/gpu_vertex_format.cc
index 59ae862aa51..2463dc2ae06 100644
--- a/source/blender/gpu/intern/gpu_vertex_format.cc
+++ b/source/blender/gpu/intern/gpu_vertex_format.cc
@@ -8,6 +8,7 @@
*/
#include "GPU_vertex_format.h"
+#include "gpu_shader_create_info.hh"
#include "gpu_shader_private.hh"
#include "gpu_vertex_format_private.h"
@@ -25,6 +26,7 @@
#endif
using namespace blender::gpu;
+using namespace blender::gpu::shader;
void GPU_vertformat_clear(GPUVertFormat *format)
{
@@ -338,8 +340,83 @@ void VertexFormat_pack(GPUVertFormat *format)
format->packed = true;
}
+static uint component_size_get(const Type gpu_type)
+{
+ switch (gpu_type) {
+ case Type::VEC2:
+ case Type::IVEC2:
+ case Type::UVEC2:
+ return 2;
+ case Type::VEC3:
+ case Type::IVEC3:
+ case Type::UVEC3:
+ return 3;
+ case Type::VEC4:
+ case Type::IVEC4:
+ case Type::UVEC4:
+ return 4;
+ case Type::MAT3:
+ return 12;
+ case Type::MAT4:
+ return 16;
+ default:
+ return 1;
+ }
+}
+
+static void recommended_fetch_mode_and_comp_type(Type gpu_type,
+ GPUVertCompType *r_comp_type,
+ GPUVertFetchMode *r_fetch_mode)
+{
+ switch (gpu_type) {
+ case Type::FLOAT:
+ case Type::VEC2:
+ case Type::VEC3:
+ case Type::VEC4:
+ case Type::MAT3:
+ case Type::MAT4:
+ *r_comp_type = GPU_COMP_F32;
+ *r_fetch_mode = GPU_FETCH_FLOAT;
+ break;
+ case Type::INT:
+ case Type::IVEC2:
+ case Type::IVEC3:
+ case Type::IVEC4:
+ *r_comp_type = GPU_COMP_I32;
+ *r_fetch_mode = GPU_FETCH_INT;
+ break;
+ case Type::UINT:
+ case Type::UVEC2:
+ case Type::UVEC3:
+ case Type::UVEC4:
+ *r_comp_type = GPU_COMP_U32;
+ *r_fetch_mode = GPU_FETCH_INT;
+ break;
+ default:
+ BLI_assert(0);
+ }
+}
+
void GPU_vertformat_from_shader(GPUVertFormat *format, const struct GPUShader *gpushader)
{
- const Shader *shader = reinterpret_cast<const Shader *>(gpushader);
- shader->vertformat_from_shader(format);
+ GPU_vertformat_clear(format);
+
+ uint attr_len = GPU_shader_get_attribute_len(gpushader);
+ int location_test = 0, attrs_added = 0;;
+ while (attrs_added < attr_len) {
+ char name[256];
+ Type gpu_type;
+ if (!GPU_shader_get_attribute_info(gpushader, location_test++, name, (int *)&gpu_type)) {
+ continue;
+ }
+
+ GPUVertCompType comp_type;
+ GPUVertFetchMode fetch_mode;
+ recommended_fetch_mode_and_comp_type(gpu_type, &comp_type, &fetch_mode);
+
+ int comp_len = component_size_get(gpu_type);
+
+ GPU_vertformat_attr_add(format, name, comp_type, comp_len, fetch_mode);
+ attrs_added++;
+ }
}
diff --git a/source/blender/gpu/opengl/gl_shader.cc b/source/blender/gpu/opengl/gl_shader.cc
index a08019cc707..1f2ef36716e 100644
--- a/source/blender/gpu/opengl/gl_shader.cc
+++ b/source/blender/gpu/opengl/gl_shader.cc
@@ -1136,108 +1136,6 @@ void GLShader::uniform_int(int location, int comp_len, int array_size, const int
/** \name GPUVertFormat from Shader
* \{ */
-static uint calc_component_size(const GLenum gl_type)
-{
- switch (gl_type) {
- case GL_FLOAT_VEC2:
- case GL_INT_VEC2:
- case GL_UNSIGNED_INT_VEC2:
- return 2;
- case GL_FLOAT_VEC3:
- case GL_INT_VEC3:
- case GL_UNSIGNED_INT_VEC3:
- return 3;
- case GL_FLOAT_VEC4:
- case GL_FLOAT_MAT2:
- case GL_INT_VEC4:
- case GL_UNSIGNED_INT_VEC4:
- return 4;
- case GL_FLOAT_MAT3:
- return 9;
- case GL_FLOAT_MAT4:
- return 16;
- case GL_FLOAT_MAT2x3:
- case GL_FLOAT_MAT3x2:
- return 6;
- case GL_FLOAT_MAT2x4:
- case GL_FLOAT_MAT4x2:
- return 8;
- case GL_FLOAT_MAT3x4:
- case GL_FLOAT_MAT4x3:
- return 12;
- default:
- return 1;
- }
-}
-
-static void get_fetch_mode_and_comp_type(int gl_type,
- GPUVertCompType *r_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_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_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_fetch_mode = GPU_FETCH_INT;
- break;
- default:
- BLI_assert(0);
- }
-}
-
-void GLShader::vertformat_from_shader(GPUVertFormat *format) const
-{
- GPU_vertformat_clear(format);
-
- GLint attr_len;
- glGetProgramiv(shader_program_, GL_ACTIVE_ATTRIBUTES, &attr_len);
-
- for (int i = 0; i < attr_len; i++) {
- char name[256];
- GLenum gl_type;
- GLint size;
- glGetActiveAttrib(shader_program_, i, sizeof(name), nullptr, &size, &gl_type, name);
-
- /* Ignore OpenGL names like `gl_BaseInstanceARB`, `gl_InstanceID` and `gl_VertexID`. */
- if (glGetAttribLocation(shader_program_, name) == -1) {
- continue;
- }
-
- GPUVertCompType comp_type;
- GPUVertFetchMode fetch_mode;
- get_fetch_mode_and_comp_type(gl_type, &comp_type, &fetch_mode);
-
- int comp_len = calc_component_size(gl_type) * size;
-
- GPU_vertformat_attr_add(format, name, comp_type, comp_len, fetch_mode);
- }
-}
-
int GLShader::program_handle_get() const
{
return (int)this->shader_program_;
diff --git a/source/blender/gpu/opengl/gl_shader.hh b/source/blender/gpu/opengl/gl_shader.hh
index 2774b24cdbe..bebbb2fa82e 100644
--- a/source/blender/gpu/opengl/gl_shader.hh
+++ b/source/blender/gpu/opengl/gl_shader.hh
@@ -67,8 +67,6 @@ class GLShader : public Shader {
void uniform_float(int location, int comp_len, int array_size, const float *data) override;
void uniform_int(int location, int comp_len, int array_size, const int *data) override;
- void vertformat_from_shader(GPUVertFormat *format) const override;
-
/** DEPRECATED: Kept only because of BGL API. */
int program_handle_get() const override;
diff --git a/source/blender/gpu/opengl/gl_shader_interface.cc b/source/blender/gpu/opengl/gl_shader_interface.cc
index 4623a14dab3..b230706b020 100644
--- a/source/blender/gpu/opengl/gl_shader_interface.cc
+++ b/source/blender/gpu/opengl/gl_shader_interface.cc
@@ -16,6 +16,7 @@
#include "GPU_capabilities.h"
+using namespace blender::gpu::shader;
namespace blender::gpu {
/* -------------------------------------------------------------------- */
@@ -151,6 +152,52 @@ static inline int ssbo_binding(int32_t program, uint32_t ssbo_index)
/** \name Creation / Destruction
* \{ */
+static Type gpu_type_from_gl_type(int gl_type)
+{
+ switch (gl_type) {
+ case GL_FLOAT:
+ return Type::FLOAT;
+ case GL_FLOAT_VEC2:
+ return Type::VEC2;
+ case GL_FLOAT_VEC3:
+ return Type::VEC3;
+ case GL_FLOAT_VEC4:
+ return Type::VEC4;
+ case GL_FLOAT_MAT3:
+ return Type::MAT3;
+ case GL_FLOAT_MAT4:
+ return Type::MAT4;
+ case GL_UNSIGNED_INT:
+ return Type::UINT;
+ case GL_UNSIGNED_INT_VEC2:
+ return Type::UVEC2;
+ case GL_UNSIGNED_INT_VEC3:
+ return Type::UVEC3;
+ case GL_UNSIGNED_INT_VEC4:
+ return Type::UVEC4;
+ case GL_INT:
+ return Type::INT;
+ case GL_INT_VEC2:
+ return Type::IVEC2;
+ case GL_INT_VEC3:
+ return Type::IVEC3;
+ case GL_INT_VEC4:
+ return Type::IVEC4;
+ case GL_BOOL:
+ return Type::BOOL;
+ case GL_FLOAT_MAT2:
+ case GL_FLOAT_MAT2x3:
+ case GL_FLOAT_MAT2x4:
+ case GL_FLOAT_MAT3x2:
+ case GL_FLOAT_MAT3x4:
+ case GL_FLOAT_MAT4x2:
+ case GL_FLOAT_MAT4x3:
+ default:
+ BLI_assert(0);
+ }
+ return Type::FLOAT;
+}
+
GLShaderInterface::GLShaderInterface(GLuint program)
{
/* Necessary to make #glUniform works. */
@@ -246,6 +293,9 @@ GLShaderInterface::GLShaderInterface(GLuint program)
name_buffer_offset += set_input_name(input, name, name_len);
enabled_attr_mask_ |= (1 << input->location);
+
+ /* Used in `GPU_shader_get_attribute_info`. */
+ attr_types_[input->location] = (uint8_t)gpu_type_from_gl_type(type);
}
/* Uniform Blocks */
@@ -405,7 +455,11 @@ GLShaderInterface::GLShaderInterface(GLuint program, const shader::ShaderCreateI
}
if (input->location != -1) {
enabled_attr_mask_ |= (1 << input->location);
+
+ /* Used in `GPU_shader_get_attribute_info`. */
+ attr_types_[input->location] = (uint8_t)attr.type;
}
+
input++;
}