[Bf-blender-cvs] [8ff67b51d17] temp-gpu-uniform-builtin-structs: Added uniform builtin struct to shader.

Jeroen Bakker noreply at git.blender.org
Wed Jul 7 16:49:08 CEST 2021


Commit: 8ff67b51d17288fcd13e1e86ae7027d2bd43ef08
Author: Jeroen Bakker
Date:   Wed Jul 7 16:49:04 2021 +0200
Branches: temp-gpu-uniform-builtin-structs
https://developer.blender.org/rB8ff67b51d17288fcd13e1e86ae7027d2bd43ef08

Added uniform builtin struct to shader.

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

M	source/blender/gpu/intern/gpu_shader.cc
M	source/blender/gpu/intern/gpu_shader_private.hh
M	source/blender/gpu/intern/gpu_uniform_buffer_private.hh
M	source/blender/gpu/opengl/gl_shader.cc
M	source/blender/gpu/opengl/gl_shader_interface.cc
M	source/blender/gpu/opengl/gl_shader_interface.hh
M	source/blender/gpu/tests/gpu_uniform_buffer_struct_test.cc

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

diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc
index b71f46fb3fc..048f4582f43 100644
--- a/source/blender/gpu/intern/gpu_shader.cc
+++ b/source/blender/gpu/intern/gpu_shader.cc
@@ -59,6 +59,7 @@ Shader::Shader(const char *sh_name)
 Shader::~Shader()
 {
   delete interface;
+  delete m_shader_struct;
 }
 
 static void standard_defines(Vector<const char *> &sources)
@@ -110,6 +111,9 @@ GPUShader *GPU_shader_create_ex(const char *vertcode,
               (computecode != nullptr)));
 
   Shader *shader = GPUBackend::get()->shader_alloc(shname);
+  if (uniform_struct_type != GPU_UNIFORM_STRUCT_NONE) {
+    shader->set_shader_struct(uniform_struct_type);
+  }
 
   if (vertcode) {
     Vector<const char *> sources;
@@ -211,7 +215,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_shader_private.hh b/source/blender/gpu/intern/gpu_shader_private.hh
index 65720e457d8..06e0b99b276 100644
--- a/source/blender/gpu/intern/gpu_shader_private.hh
+++ b/source/blender/gpu/intern/gpu_shader_private.hh
@@ -24,9 +24,13 @@
 #include "BLI_string_ref.hh"
 
 #include "GPU_shader.h"
+#include "GPU_uniform_buffer_types.h"
 #include "gpu_shader_interface.hh"
+#include "gpu_uniform_buffer_private.hh"
 #include "gpu_vertex_buffer_private.hh"
 
+#include <optional>
+
 namespace blender {
 namespace gpu {
 
@@ -45,6 +49,8 @@ class Shader {
   /** For debugging purpose. */
   char name[64];
 
+  std::optional<UniformBuiltinStruct> shader_struct;
+
  public:
   Shader(const char *name);
   virtual ~Shader();
@@ -76,6 +82,12 @@ class Shader {
     return name;
   };
 
+  UniformBuiltinStruct *m_shader_struct;
+  void set_shader_struct(GPUUniformBuiltinStructType struct_type)
+  {
+    m_shader_struct = new UniformBuiltinStruct(struct_type);
+  }
+
  protected:
   void print_log(Span<const char *> sources,
                  char *log,
diff --git a/source/blender/gpu/intern/gpu_uniform_buffer_private.hh b/source/blender/gpu/intern/gpu_uniform_buffer_private.hh
index 8de5bfdcf93..adeede8f03a 100644
--- a/source/blender/gpu/intern/gpu_uniform_buffer_private.hh
+++ b/source/blender/gpu/intern/gpu_uniform_buffer_private.hh
@@ -125,6 +125,9 @@ class UniformBuiltinStruct {
   };
 
   UniformBuiltinStruct(const GPUUniformBuiltinStructType type);
+  UniformBuiltinStruct(const UniformBuiltinStruct &other) = default;
+  UniformBuiltinStruct(UniformBuiltinStruct &&other) = default;
+
   ~UniformBuiltinStruct();
 
   void *data() const
diff --git a/source/blender/gpu/opengl/gl_shader.cc b/source/blender/gpu/opengl/gl_shader.cc
index 66a1bd5ceb7..63ba0ab0a34 100644
--- a/source/blender/gpu/opengl/gl_shader.cc
+++ b/source/blender/gpu/opengl/gl_shader.cc
@@ -225,8 +225,10 @@ bool GLShader::finalize()
     this->print_log(sources, log, "Linking", true, &parser);
     return false;
   }
-
-  interface = new GLShaderInterface(shader_program_);
+  const UniformBuiltinStructType *type_info = m_shader_struct != nullptr ?
+                                                  &m_shader_struct->type_info() :
+                                                  nullptr;
+  interface = new GLShaderInterface(type_info, shader_program_);
 
   return true;
 }
@@ -308,6 +310,12 @@ void GLShader::transform_feedback_disable()
 
 void GLShader::uniform_float(int location, int comp_len, int array_size, const float *data)
 {
+  if (m_shader_struct) {
+    if (m_shader_struct->uniform_float(location, comp_len, array_size, data)) {
+      return;
+    }
+  }
+
   switch (comp_len) {
     case 1:
       glUniform1fv(location, array_size, data);
@@ -335,6 +343,12 @@ void GLShader::uniform_float(int location, int comp_len, int array_size, const f
 
 void GLShader::uniform_int(int location, int comp_len, int array_size, const int *data)
 {
+  if (m_shader_struct) {
+    if (m_shader_struct->uniform_int(location, comp_len, array_size, data)) {
+      return;
+    }
+  }
+
   switch (comp_len) {
     case 1:
       glUniform1iv(location, array_size, data);
diff --git a/source/blender/gpu/opengl/gl_shader_interface.cc b/source/blender/gpu/opengl/gl_shader_interface.cc
index 9cf072b2e8a..d9291cd642a 100644
--- a/source/blender/gpu/opengl/gl_shader_interface.cc
+++ b/source/blender/gpu/opengl/gl_shader_interface.cc
@@ -145,7 +145,7 @@ static inline int ssbo_binding(int32_t program, uint32_t ssbo_index)
 /** \name Creation / Destruction
  * \{ */
 
-GLShaderInterface::GLShaderInterface(GLuint program)
+GLShaderInterface::GLShaderInterface(const UniformBuiltinStructType *type_info, GLuint program)
 {
   /* Necessary to make #glUniform works. */
   glUseProgram(program);
@@ -187,6 +187,20 @@ GLShaderInterface::GLShaderInterface(GLuint program)
     max_ssbo_name_len = 256;
   }
 
+  /* Perform uniform builtin structs after work around to make sure the work around is passed. */
+  if (type_info) {
+    for (int i = 0; i < GPU_NUM_UNIFORMS; i++) {
+      const GPUUniformBuiltin builtin_uniform = static_cast<const GPUUniformBuiltin>(i);
+      const UniformBuiltinStructType::AttributeBinding &binding = type_info->attribute_binding(
+          builtin_uniform);
+      if (binding.has_binding()) {
+        uniform_len++;
+        max_uniform_name_len = max_ii(max_uniform_name_len,
+                                      strlen(builtin_uniform_name(builtin_uniform)));
+      }
+    }
+  }
+
   /* GL_ACTIVE_UNIFORMS lied to us! Remove the UBO uniforms from the total before
    * allocating the uniform array. */
   GLint max_ubo_uni_len = 0;
@@ -281,6 +295,24 @@ GLShaderInterface::GLShaderInterface(GLuint program)
       enabled_ima_mask_ |= (input->binding != -1) ? (1lu << input->binding) : 0lu;
     }
   }
+  if (type_info) {
+    for (int i = 0; i < GPU_NUM_UNIFORMS; i++) {
+      const GPUUniformBuiltin builtin_uniform = static_cast<const GPUUniformBuiltin>(i);
+      const UniformBuiltinStructType::AttributeBinding &binding = type_info->attribute_binding(
+          builtin_uniform);
+      if (binding.has_binding()) {
+        ShaderInput *input = &inputs_[attr_len_ + ubo_len_ + uniform_len_++];
+        input->location = binding.binding;
+        input->binding = -1;
+
+        char *name = name_buffer_ + name_buffer_offset;
+        const char *uniform_name = builtin_uniform_name(builtin_uniform);
+        size_t name_len = strlen(uniform_name);
+        strcpy(name, uniform_name);
+        name_buffer_offset += this->set_input_name(input, name, name_len);
+      }
+    }
+  }
 
   /* SSBOs */
   for (int i = 0; i < ssbo_len; i++) {
@@ -301,7 +333,8 @@ GLShaderInterface::GLShaderInterface(GLuint program)
   /* Builtin Uniforms */
   for (int32_t u_int = 0; u_int < GPU_NUM_UNIFORMS; u_int++) {
     GPUUniformBuiltin u = static_cast<GPUUniformBuiltin>(u_int);
-    builtins_[u] = glGetUniformLocation(program, builtin_uniform_name(u));
+    const ShaderInput *block = this->uniform_get(builtin_uniform_name(u));
+    builtins_[u] = (block != nullptr) ? block->binding : -1;
   }
 
   /* Builtin Uniforms Blocks */
diff --git a/source/blender/gpu/opengl/gl_shader_interface.hh b/source/blender/gpu/opengl/gl_shader_interface.hh
index 89a5b631047..5125c885cc5 100644
--- a/source/blender/gpu/opengl/gl_shader_interface.hh
+++ b/source/blender/gpu/opengl/gl_shader_interface.hh
@@ -35,6 +35,7 @@
 #include "glew-mx.h"
 
 #include "gpu_shader_interface.hh"
+#include "gpu_uniform_buffer_private.hh"
 
 namespace blender::gpu {
 
@@ -49,7 +50,7 @@ class GLShaderInterface : public ShaderInterface {
   Vector<GLVaoCache *> refs_;
 
  public:
-  GLShaderInterface(GLuint program);
+  GLShaderInterface(const UniformBuiltinStructType *type_info, GLuint program);
   ~GLShaderInterface();
 
   void ref_add(GLVaoCache *ref);
diff --git a/source/blender/gpu/tests/gpu_uniform_buffer_struct_test.cc b/source/blender/gpu/tests/gpu_uniform_buffer_struct_test.cc
index 8468bb1c66a..c03e1438509 100644
--- a/source/blender/gpu/tests/gpu_uniform_buffer_struct_test.cc
+++ b/source/blender/gpu/tests/gpu_uniform_buffer_struct_test.cc
@@ -1,5 +1,8 @@
-#include "testing/testing.h"
+#include "gpu_testing.hh"
 
+#include "GPU_capabilities.h"
+#include "GPU_compute.h"
+#include "GPU_shader.h"
 #include "GPU_uniform_buffer_types.h"
 #include "gpu_uniform_buffer_private.hh"
 
@@ -94,4 +97,52 @@ TEST(GPUUniformStruct, struct1)
   }
 }
 
+static void test_custom_shader_with_uniform_builtin_struct()
+{
+  if (!GPU_compute_shader_support()) {
+    /* We can't test as a the platform does not support compute shaders. */
+    std::cout << "Skipping compute shader test: platform not supported";
+    return;
+  }
+
+  /* Build compute shader. */
+  const char *compute_glsl = R"(
+
+layout(local_size_x = 1, local_size_y = 1) in;
+layout(rgba32f, binding = 0) uniform image2D img_output;
+
+layout(std140) uniform shaderBlock {
+  mat4 ModelMatrix;
+  mat4 ModelViewProjectionMatrix;
+  vec4 color;
+  vec4 WorldClipPlanes[6];
+  bool SrgbTransform;
+};
+
+void main() {
+}
+
+)";
+
+  GPUShader *shader = GPU_shader_create_ex(nullptr,
+                                           nullptr,
+                                           nullptr,
+                                           compute_glsl,
+                                           nullptr,
+                                           nullptr,
+                                           GPU_SHADER_TFB_NONE,
+                                           nullptr,
+                                           0,
+                                           GPU_UNIFORM_STRUCT_1,
+                                           __func__);
+  EXPECT_NE(shader, nullptr);
+
+  float color[4] = {1.0f, 0.0f, 1.0f, 1.0f};
+  GPU_shader_uniform_4fv(shader, "color", color);
+
+  GPU_shader_free(shader);
+}
+
+GPU_TEST(custom_shader_with_uniform_builtin_struct)
+
 }  // namespace blender::gpu::tests
\ No newline at end of file



More information about the Bf-blender-cvs mailing list