[Bf-blender-cvs] [6269d66da29] master: PyGPU: GPUShader: implementation of 'attrs_info_get' method

Germano Cavalcante noreply at git.blender.org
Thu Sep 1 13:26:43 CEST 2022


Commit: 6269d66da29ae000f214e775ee54dfc71623e642
Author: Germano Cavalcante
Date:   Thu Sep 1 08:21:10 2022 -0300
Branches: master
https://developer.blender.org/rB6269d66da29ae000f214e775ee54dfc71623e642

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

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

M	release/scripts/modules/gpu_extras/batch.py
M	source/blender/gpu/GPU_shader.h
M	source/blender/gpu/intern/gpu_shader.cc
M	source/blender/gpu/intern/gpu_shader_interface.hh
M	source/blender/gpu/intern/gpu_shader_private.hh
M	source/blender/gpu/intern/gpu_vertex_format.cc
M	source/blender/gpu/opengl/gl_shader.cc
M	source/blender/gpu/opengl/gl_shader.hh
M	source/blender/gpu/opengl/gl_shader_interface.cc
M	source/blender/python/gpu/gpu_py_shader.c
M	source/blender/python/gpu/gpu_py_shader.h
M	source/blender/python/gpu/gpu_py_shader_create_info.cc

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

diff --git a/release/scripts/modules/gpu_extras/batch.py b/release/scripts/modules/gpu_extras/batch.py
index 34dd1f16665..ba8e3879a8e 100644
--- a/release/scripts/modules/gpu_extras/batch.py
+++ b/release/scripts/modules/gpu_extras/batch.py
@@ -22,15 +22,46 @@ def batch_for_shader(shader, type, content, *, indices=None):
         GPUBatch,
         GPUIndexBuf,
         GPUVertBuf,
+        GPUVertFormat,
     )
 
+    def recommended_comp_type(attr_type):
+        if attr_type in {'FLOAT', 'VEC2', 'VEC3', 'VEC4', 'MAT3', 'MAT4'}:
+            return 'F32'
+        if attr_type in {'UINT', 'UVEC2', 'UVEC3', 'UVEC4'}:
+            return 'U32'
+        # `attr_type` in {'INT', 'IVEC2', 'IVEC3', 'IVEC4', 'BOOL'}.
+        return 'I32'
+
+    def recommended_attr_len(attr_name):
+        item = content[attr_name][0]
+        attr_len = 1
+        try:
+            while True:
+                attr_len *= len(item)
+                item = item[0]
+        except TypeError:
+            pass
+        return attr_len
+
+    def recommended_fetch_mode(comp_type):
+        if comp_type == 'F32':
+            return 'FLOAT'
+        return 'INT'
+
     for data in content.values():
         vbo_len = len(data)
         break
     else:
         raise ValueError("Empty 'content'")
 
-    vbo_format = shader.format_calc()
+    vbo_format = GPUVertFormat()
+    attrs_info = shader.attrs_info_get()
+    for name, attr_type in attrs_info:
+        comp_type = recommended_comp_type(attr_type)
+        attr_len = recommended_attr_len(name)
+        vbo_format.attr_add(id=name, comp_type=comp_type, len=attr_len, fetch_mode=recommended_fetch_mode(comp_type))
+
     vbo = GPUVertBuf(vbo_format, vbo_len)
 
     for id, data in content.items():
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,
-                         

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list