[Bf-blender-cvs] [8f2bb1b1f05] temp-gpu-uniform-builtin-structs: Use compile time inlining for buitin structs.

Jeroen Bakker noreply at git.blender.org
Wed Jul 7 14:04:33 CEST 2021


Commit: 8f2bb1b1f055b55f41165b00de58109dab6df8f9
Author: Jeroen Bakker
Date:   Wed Jul 7 12:36:25 2021 +0200
Branches: temp-gpu-uniform-builtin-structs
https://developer.blender.org/rB8f2bb1b1f055b55f41165b00de58109dab6df8f9

Use compile time inlining for buitin structs.

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

M	source/blender/gpu/intern/gpu_shader.cc
M	source/blender/gpu/intern/gpu_uniform_buffer_private.hh
M	source/blender/gpu/intern/gpu_uniform_buffer_structs.cc

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

diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc
index 373162d35f7..b71f46fb3fc 100644
--- a/source/blender/gpu/intern/gpu_shader.cc
+++ b/source/blender/gpu/intern/gpu_shader.cc
@@ -211,7 +211,7 @@ void GPU_shader_free(GPUShader *shader)
 /* -------------------------------------------------------------------- */
 /** \name Creation utils
  * \{ */
-
+  
 GPUShader *GPU_shader_create(const char *vertcode,
                              const char *fragcode,
                              const char *geomcode,
diff --git a/source/blender/gpu/intern/gpu_uniform_buffer_private.hh b/source/blender/gpu/intern/gpu_uniform_buffer_private.hh
index b514b312c11..06ec14780a8 100644
--- a/source/blender/gpu/intern/gpu_uniform_buffer_private.hh
+++ b/source/blender/gpu/intern/gpu_uniform_buffer_private.hh
@@ -29,6 +29,8 @@
 #include "GPU_shader.h"
 #include "GPU_uniform_buffer_types.h"
 
+#include <array>
+
 struct GPUUniformBuf;
 
 namespace blender {
@@ -88,14 +90,55 @@ static inline const UniformBuf *unwrap(const GPUUniformBuf *vert)
 
 class UniformBuiltinStructType {
  public:
-  UniformBuiltinStructType(const GPUUniformBuiltinStructType type);
+  constexpr UniformBuiltinStructType(const GPUUniformBuiltinStructType type);
+  static const UniformBuiltinStructType &get(const GPUUniformBuiltinStructType type);
+
+  bool has_all_builtin_uniforms(const ShaderInterface &interface) const;
 
   GPUUniformBuiltinStructType type;
+  struct AttributeBinding {
+    int binding = -1;
+    size_t offset = -1;
 
-  bool has_all_builtin_uniforms(const ShaderInterface &interface) const;
+    bool has_binding() const;
+  };
+
+  const AttributeBinding &attribute_binding(const GPUUniformBuiltin builtin_uniform) const
+  {
+    return m_attribute_bindings[builtin_uniform];
+  }
+
+  const size_t data_size() const
+  {
+    return m_data_size;
+  }
+
+ private:
+  const std::array<const AttributeBinding, GPU_NUM_UNIFORMS> &m_attribute_bindings;
+  const size_t m_data_size;
+};
+
+class UniformBuiltinStruct {
+ public:
+  struct Flags {
+    bool is_dirty : 1;
+  };
+
+  UniformBuiltinStruct(const GPUUniformBuiltinStructType type);
+  ~UniformBuiltinStruct();
+
+  void *data() const
+  {
+    return m_data;
+  };
+
+  bool uniform_int(int location, int comp_len, int array_size, const int *data);
+  bool uniform_float(int location, int comp_len, int array_size, const float *data);
 
  private:
-  bool has_attribute(const GPUUniformBuiltin builtin_uniform) const;
+  Flags m_flags;
+  const UniformBuiltinStructType &m_type_info;
+  void *m_data;
 };
 
 std::optional<const GPUUniformBuiltinStructType> find_smallest_uniform_builtin_struct(
diff --git a/source/blender/gpu/intern/gpu_uniform_buffer_structs.cc b/source/blender/gpu/intern/gpu_uniform_buffer_structs.cc
index 897d1088e43..bdb16d2ec54 100644
--- a/source/blender/gpu/intern/gpu_uniform_buffer_structs.cc
+++ b/source/blender/gpu/intern/gpu_uniform_buffer_structs.cc
@@ -23,6 +23,8 @@
 
 #include "gpu_uniform_buffer_private.hh"
 
+#include "MEM_guardedalloc.h"
+
 #include "GPU_shader.h"
 #include "GPU_uniform_buffer_types.h"
 #include "gpu_shader_interface.hh"
@@ -30,49 +32,168 @@
 namespace blender::gpu {
 
 /* -------------------------------------------------------------------- */
-/** \name Struct type
+/** \name Attribute bindings
  * \{ */
+const int BUILTIN_BINDING_LOCATION_OFFSET = 1000;
 
-UniformBuiltinStructType::UniformBuiltinStructType(const GPUUniformBuiltinStructType type)
-    : type(type)
+static constexpr int to_binding_location(const GPUUniformBuiltin builtin_uniform)
 {
+  return BUILTIN_BINDING_LOCATION_OFFSET + builtin_uniform;
 }
 
-bool UniformBuiltinStructType::has_attribute(const GPUUniformBuiltin builtin_uniform) const
+static GPUUniformBuiltin to_builtin_uniform(int location)
 {
-  switch (type) {
-    case GPU_UNIFORM_STRUCT_NONE:
-      return false;
+  return static_cast<GPUUniformBuiltin>(location - BUILTIN_BINDING_LOCATION_OFFSET);
+}
+
+static bool is_valid_location(int location)
+{
+  int builtin_uniform = location - BUILTIN_BINDING_LOCATION_OFFSET;
+  if (builtin_uniform < 0 || builtin_uniform >= GPU_NUM_UNIFORMS) {
+    return false;
+  }
+  return true;
+}
+
+static constexpr UniformBuiltinStructType::AttributeBinding determine_binding_struct_1(
+    const GPUUniformBuiltin builtin_uniform)
+{
+  UniformBuiltinStructType::AttributeBinding result;
+  switch (builtin_uniform) {
+    case GPU_UNIFORM_MODEL:
+      result.binding = to_binding_location(builtin_uniform);
+      result.offset = offsetof(GPUUniformBuiltinStruct1, ModelMatrix);
+      break;
+    case GPU_UNIFORM_MVP:
+      result.binding = to_binding_location(builtin_uniform);
+      result.offset = offsetof(GPUUniformBuiltinStruct1, ModelViewProjectionMatrix);
+      break;
+    case GPU_UNIFORM_COLOR:
+      result.binding = to_binding_location(builtin_uniform);
+      result.offset = offsetof(GPUUniformBuiltinStruct1, color);
+      break;
+    case GPU_UNIFORM_CLIPPLANES:
+      result.binding = to_binding_location(builtin_uniform);
+      result.offset = offsetof(GPUUniformBuiltinStruct1, WorldClipPlanes);
+      break;
+    case GPU_UNIFORM_SRGB_TRANSFORM:
+      result.binding = to_binding_location(builtin_uniform);
+      result.offset = offsetof(GPUUniformBuiltinStruct1, SrgbTransform);
       break;
 
-    case GPU_UNIFORM_STRUCT_1:
-      return ELEM(builtin_uniform,
-                  GPU_UNIFORM_MODEL,
-                  GPU_UNIFORM_MVP,
-                  GPU_UNIFORM_COLOR,
-                  GPU_UNIFORM_CLIPPLANES,
-                  GPU_UNIFORM_SRGB_TRANSFORM);
+    default:
       break;
+  };
+
+  return result;
+}
+
+static constexpr UniformBuiltinStructType::AttributeBinding determine_binding(
+    const GPUUniformBuiltinStructType struct_type, const GPUUniformBuiltin builtin_uniform)
+{
 
+  switch (struct_type) {
+    case GPU_UNIFORM_STRUCT_NONE:
     case GPU_NUM_UNIFORM_STRUCTS:
-      return false;
-      break;
-  }
-  return false;
+      return {};
+
+    case GPU_UNIFORM_STRUCT_1:
+      return determine_binding_struct_1(builtin_uniform);
+  };
+  return {};
+}
+
+static constexpr std::array<const UniformBuiltinStructType::AttributeBinding, GPU_NUM_UNIFORMS>
+builtin_uniforms_for_struct_type(const GPUUniformBuiltinStructType struct_type)
+{
+  return {
+      determine_binding(struct_type, GPU_UNIFORM_MODEL),
+      determine_binding(struct_type, GPU_UNIFORM_VIEW),
+      determine_binding(struct_type, GPU_UNIFORM_MODELVIEW),
+      determine_binding(struct_type, GPU_UNIFORM_PROJECTION),
+      determine_binding(struct_type, GPU_UNIFORM_VIEWPROJECTION),
+      determine_binding(struct_type, GPU_UNIFORM_MVP),
+      determine_binding(struct_type, GPU_UNIFORM_MODEL_INV),
+      determine_binding(struct_type, GPU_UNIFORM_VIEW_INV),
+      determine_binding(struct_type, GPU_UNIFORM_MODELVIEW_INV),
+      determine_binding(struct_type, GPU_UNIFORM_PROJECTION_INV),
+      determine_binding(struct_type, GPU_UNIFORM_VIEWPROJECTION_INV),
+      determine_binding(struct_type, GPU_UNIFORM_NORMAL),
+      determine_binding(struct_type, GPU_UNIFORM_ORCO),
+      determine_binding(struct_type, GPU_UNIFORM_CLIPPLANES),
+      determine_binding(struct_type, GPU_UNIFORM_COLOR),
+      determine_binding(struct_type, GPU_UNIFORM_BASE_INSTANCE),
+      determine_binding(struct_type, GPU_UNIFORM_RESOURCE_CHUNK),
+      determine_binding(struct_type, GPU_UNIFORM_RESOURCE_ID),
+      determine_binding(struct_type, GPU_UNIFORM_SRGB_TRANSFORM),
+  };
+}
+
+static constexpr std::array<
+    const std::array<const UniformBuiltinStructType::AttributeBinding, GPU_NUM_UNIFORMS>,
+    GPU_NUM_UNIFORM_STRUCTS>
+    ATTRIBUTE_BINDINGS = {
+        builtin_uniforms_for_struct_type(GPU_UNIFORM_STRUCT_NONE),
+        builtin_uniforms_for_struct_type(GPU_UNIFORM_STRUCT_1),
+};
+
+static constexpr size_t data_size_for(const GPUUniformBuiltinStructType struct_type)
+{
+
+  switch (struct_type) {
+    case GPU_UNIFORM_STRUCT_NONE:
+    case GPU_NUM_UNIFORM_STRUCTS:
+      return 0;
+
+    case GPU_UNIFORM_STRUCT_1:
+      return sizeof(GPUUniformBuiltinStruct1);
+  };
+  return 0;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Struct type
+ * \{ */
+
+constexpr UniformBuiltinStructType::UniformBuiltinStructType(
+    const GPUUniformBuiltinStructType type)
+    : type(type), m_attribute_bindings(ATTRIBUTE_BINDINGS[type]), m_data_size(data_size_for(type))
+{
+}
+
+bool UniformBuiltinStructType::AttributeBinding::has_binding() const
+{
+  return binding != -1;
 }
 
 bool UniformBuiltinStructType::has_all_builtin_uniforms(const ShaderInterface &interface) const
 {
   for (int i = 0; i < GPU_NUM_UNIFORMS; i++) {
     const GPUUniformBuiltin builtin_uniform = static_cast<const GPUUniformBuiltin>(i);
+    const AttributeBinding &binding = attribute_binding(builtin_uniform);
     const bool builtin_is_used = interface.builtins_[i] != -1;
-    if (builtin_is_used && !has_attribute(builtin_uniform)) {
+    const bool has_attribute = binding.has_binding();
+    if (builtin_is_used && !has_attribute) {
       return false;
     }
   }
   return true;
 }
 
+static constexpr std::array<UniformBuiltinStructType, GPU_NUM_UNIFORM_STRUCTS> STRUCT_TYPE_INFOS =
+    {
+        UniformBuiltinStructType(GPU_UNIFORM_STRUCT_NONE),
+        UniformBuiltinStructType(GPU_UNIFORM_STRUCT_1),
+};
+
+const UniformBuiltinStructType &UniformBuiltinStructType::get(
+    const GPUUniformBuiltinStructType type)
+{
+  return STRUCT_TYPE_INFOS[type];
+}
+
 std::optional<const GPUUniformBuiltinStructType> find_smallest_uniform_builtin_struct(
     const ShaderInterface &interface)
 {
@@ -80,10 +201,8 @@ std::optional<const GPUUniformBuiltinStructType> find_smallest_uniform_builtin_s
     return std::nullopt;
   }
 
-  const UniformBuiltinStructType struct1(GPU_UNIFORM_STRUCT_1);
-
-  if (struct1.has_all_builtin_uniforms(interface)) {
-    return std::make_optional(struct1.type);
+  if (UniformBuiltinStructType::get(GPU_UNIFORM_STRUCT_1).has_all_builtin_uniforms(interface)) {
+    return std::make_optional(GPU_UNIFORM_STRUCT_1);
   }
 
   return std::nullopt;
@@ -91,4 +210,6

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list