[Bf-blender-cvs] [40e4bed4068] temp-gpu-compute-shaders: Add shader interface for shader storage buffers.

Jeroen Bakker noreply at git.blender.org
Fri May 7 14:03:03 CEST 2021


Commit: 40e4bed4068ee9e9c8724f83711ef079523a6959
Author: Jeroen Bakker
Date:   Fri May 7 14:02:48 2021 +0200
Branches: temp-gpu-compute-shaders
https://developer.blender.org/rB40e4bed4068ee9e9c8724f83711ef079523a6959

Add shader interface for shader storage buffers.

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

M	source/blender/gpu/GPU_capabilities.h
M	source/blender/gpu/GPU_shader.h
M	source/blender/gpu/intern/gpu_capabilities.cc
M	source/blender/gpu/intern/gpu_capabilities_private.hh
M	source/blender/gpu/intern/gpu_shader.cc
M	source/blender/gpu/intern/gpu_shader_interface.cc
M	source/blender/gpu/intern/gpu_shader_interface.hh
M	source/blender/gpu/opengl/gl_backend.cc
M	source/blender/gpu/opengl/gl_shader_interface.cc
M	source/blender/gpu/tests/gpu_shader_test.cc

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

diff --git a/source/blender/gpu/GPU_capabilities.h b/source/blender/gpu/GPU_capabilities.h
index a5830455a96..6cff826e490 100644
--- a/source/blender/gpu/GPU_capabilities.h
+++ b/source/blender/gpu/GPU_capabilities.h
@@ -47,6 +47,7 @@ bool GPU_use_hq_normals_workaround(void);
 bool GPU_crappy_amd_driver(void);
 
 bool GPU_compute_shader_support(void);
+bool GPU_shader_storage_buffer_objects_support(void);
 bool GPU_shader_image_load_store_support(void);
 
 bool GPU_mem_stats_supported(void);
diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h
index 8f82ee90873..3923c920c9e 100644
--- a/source/blender/gpu/GPU_shader.h
+++ b/source/blender/gpu/GPU_shader.h
@@ -132,6 +132,7 @@ int GPU_shader_get_uniform(GPUShader *shader, const char *name);
 int GPU_shader_get_builtin_uniform(GPUShader *shader, int builtin);
 int GPU_shader_get_builtin_block(GPUShader *shader, int builtin);
 int GPU_shader_get_uniform_block(GPUShader *shader, const char *name);
+int GPU_shader_get_ssbo(GPUShader *shader, const char *name);
 
 int GPU_shader_get_uniform_block_binding(GPUShader *shader, const char *name);
 int GPU_shader_get_texture_binding(GPUShader *shader, const char *name);
diff --git a/source/blender/gpu/intern/gpu_capabilities.cc b/source/blender/gpu/intern/gpu_capabilities.cc
index cabd7a6493d..284067df5ad 100644
--- a/source/blender/gpu/intern/gpu_capabilities.cc
+++ b/source/blender/gpu/intern/gpu_capabilities.cc
@@ -113,6 +113,11 @@ bool GPU_compute_shader_support(void)
   return GCaps.compute_shader_support;
 }
 
+bool GPU_shader_storage_buffer_objects_support(void)
+{
+  return GCaps.shader_storage_buffer_objects_support;
+}
+
 bool GPU_shader_image_load_store_support(void)
 {
   return GCaps.shader_image_load_store_support;
diff --git a/source/blender/gpu/intern/gpu_capabilities_private.hh b/source/blender/gpu/intern/gpu_capabilities_private.hh
index a951ada75d0..0c2790d85c7 100644
--- a/source/blender/gpu/intern/gpu_capabilities_private.hh
+++ b/source/blender/gpu/intern/gpu_capabilities_private.hh
@@ -43,6 +43,7 @@ struct GPUCapabilities {
   int max_textures_frag = 0;
   bool mem_stats_support = false;
   bool compute_shader_support = false;
+  bool shader_storage_buffer_objects_support = false;
   bool shader_image_load_store_support = false;
   /* OpenGL related workarounds. */
   bool mip_render_workaround = false;
diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc
index ab7d5e52701..265dec7c56a 100644
--- a/source/blender/gpu/intern/gpu_shader.cc
+++ b/source/blender/gpu/intern/gpu_shader.cc
@@ -611,6 +611,13 @@ int GPU_shader_get_builtin_block(GPUShader *shader, int builtin)
   return interface->ubo_builtin((GPUUniformBlockBuiltin)builtin);
 }
 
+int GPU_shader_get_ssbo(GPUShader *shader, const char *name)
+{
+  ShaderInterface *interface = unwrap(shader)->interface;
+  const ShaderInput *ssbo = interface->ssbo_get(name);
+  return ssbo ? ssbo->location : -1;
+}
+
 /* DEPRECATED. */
 int GPU_shader_get_uniform_block(GPUShader *shader, const char *name)
 {
diff --git a/source/blender/gpu/intern/gpu_shader_interface.cc b/source/blender/gpu/intern/gpu_shader_interface.cc
index c584c40eca8..ae94112b17b 100644
--- a/source/blender/gpu/intern/gpu_shader_interface.cc
+++ b/source/blender/gpu/intern/gpu_shader_interface.cc
@@ -80,6 +80,8 @@ void ShaderInterface::debug_print()
   Span<ShaderInput> attrs = Span<ShaderInput>(inputs_, attr_len_);
   Span<ShaderInput> ubos = Span<ShaderInput>(inputs_ + attr_len_, ubo_len_);
   Span<ShaderInput> uniforms = Span<ShaderInput>(inputs_ + attr_len_ + ubo_len_, uniform_len_);
+  Span<ShaderInput> ssbos = Span<ShaderInput>(inputs_ + attr_len_ + ubo_len_ + uniform_len_,
+                                              ssbo_len_);
   char *name_buf = name_buffer_;
   const char format[] = "      | %.8x : %4d : %s\n";
 
@@ -117,6 +119,13 @@ void ShaderInterface::debug_print()
     }
   }
 
+  if (ssbos.size() > 0) {
+    printf("\n    Shader Storage Objects :\n");
+  }
+  for (const ShaderInput &ssbo : ssbos) {
+    printf(format, ssbo.name_hash, ssbo.binding, name_buf + ssbo.name_offset);
+  }
+
   printf("\n");
 }
 
diff --git a/source/blender/gpu/intern/gpu_shader_interface.hh b/source/blender/gpu/intern/gpu_shader_interface.hh
index aec58544111..ebed7b15170 100644
--- a/source/blender/gpu/intern/gpu_shader_interface.hh
+++ b/source/blender/gpu/intern/gpu_shader_interface.hh
@@ -60,6 +60,7 @@ class ShaderInterface {
   uint attr_len_ = 0;
   uint ubo_len_ = 0;
   uint uniform_len_ = 0;
+  uint ssbo_len_ = 0;
   /** Enabled bind-points that needs to be fed with data. */
   uint16_t enabled_attr_mask_ = 0;
   uint16_t enabled_ubo_mask_ = 0;
@@ -99,6 +100,11 @@ class ShaderInterface {
     return input_lookup(inputs_ + attr_len_ + ubo_len_, uniform_len_, binding);
   }
 
+  inline const ShaderInput *ssbo_get(const char *name) const
+  {
+    return input_lookup(inputs_ + attr_len_ + ubo_len_ + uniform_len_, ssbo_len_, name);
+  }
+
   inline const char *input_name_get(const ShaderInput *input) const
   {
     return name_buffer_ + input->name_offset;
diff --git a/source/blender/gpu/opengl/gl_backend.cc b/source/blender/gpu/opengl/gl_backend.cc
index 50b0feba879..a830cc9211d 100644
--- a/source/blender/gpu/opengl/gl_backend.cc
+++ b/source/blender/gpu/opengl/gl_backend.cc
@@ -421,6 +421,7 @@ void GLBackend::capabilities_init()
   GCaps.mem_stats_support = GLEW_NVX_gpu_memory_info || GLEW_ATI_meminfo;
   GCaps.shader_image_load_store_support = GLEW_ARB_shader_image_load_store;
   GCaps.compute_shader_support = GLEW_ARB_compute_shader;
+  GCaps.shader_storage_buffer_objects_support = GLEW_ARB_shader_storage_buffer_object;
   /* GL specific capabilities. */
   glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &GLContext::max_texture_3d_size);
   glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &GLContext::max_cubemap_size);
diff --git a/source/blender/gpu/opengl/gl_shader_interface.cc b/source/blender/gpu/opengl/gl_shader_interface.cc
index 5870c645bf4..26edfd30088 100644
--- a/source/blender/gpu/opengl/gl_shader_interface.cc
+++ b/source/blender/gpu/opengl/gl_shader_interface.cc
@@ -29,6 +29,8 @@
 
 #include "gl_shader_interface.hh"
 
+#include "GPU_capabilities.h"
+
 namespace blender::gpu {
 
 /* -------------------------------------------------------------------- */
@@ -125,6 +127,12 @@ static inline int image_binding(int32_t program,
       return -1;
   }
 }
+
+static inline int ssbo_binding()
+{
+  return -1;
+}
+
 /** \} */
 
 /* -------------------------------------------------------------------- */
@@ -136,6 +144,13 @@ GLShaderInterface::GLShaderInterface(GLuint program)
   /* Necessary to make #glUniform works. */
   glUseProgram(program);
 
+  GLint max_ssbo_name_len = 0, ssbo_len = 0;
+  if (GPU_shader_storage_buffer_objects_support()) {
+    glGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, &ssbo_len);
+    glGetProgramInterfaceiv(
+        program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, &max_ssbo_name_len);
+  }
+
   GLint max_attr_name_len = 0, attr_len = 0;
   glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_attr_name_len);
   glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &attr_len);
@@ -162,6 +177,9 @@ GLShaderInterface::GLShaderInterface(GLuint program)
   if (uniform_len > 0 && max_uniform_name_len == 0) {
     max_uniform_name_len = 256;
   }
+  if (ssbo_len > 0 && max_ssbo_name_len == 0) {
+    max_ssbo_name_len = 256;
+  }
 
   /* GL_ACTIVE_UNIFORMS lied to us! Remove the UBO uniforms from the total before
    * allocating the uniform array. */
@@ -186,11 +204,12 @@ GLShaderInterface::GLShaderInterface(GLuint program)
   }
   MEM_freeN(ubo_uni_ids);
 
-  int input_tot_len = attr_len + ubo_len + uniform_len;
+  int input_tot_len = attr_len + ubo_len + uniform_len + ssbo_len;
   inputs_ = (ShaderInput *)MEM_callocN(sizeof(ShaderInput) * input_tot_len, __func__);
 
   const uint32_t name_buffer_len = attr_len * max_attr_name_len + ubo_len * max_ubo_name_len +
-                                   uniform_len * max_uniform_name_len;
+                                   uniform_len * max_uniform_name_len +
+                                   ssbo_len * max_ssbo_name_len;
   name_buffer_ = (char *)MEM_mallocN(name_buffer_len, "name_buffer");
   uint32_t name_buffer_offset = 0;
 
@@ -257,6 +276,26 @@ GLShaderInterface::GLShaderInterface(GLuint program)
     }
   }
 
+  /* SSBOs */
+  for (int i = 0; i < ssbo_len; i++) {
+    char *name = name_buffer_ + name_buffer_offset;
+    GLsizei remaining_buffer = name_buffer_len - name_buffer_offset;
+    GLsizei name_len = 0;
+    glGetProgramResourceName(
+        program, GL_SHADER_STORAGE_BLOCK, i, remaining_buffer, &name_len, name);
+
+    GLint binding = -1;
+    GLenum property = GL_BUFFER_BINDING;
+    GLint values_written = 0;
+    glGetProgramResourceiv(
+        program, GL_SHADER_STORAGE_BLOCK, i, 1, &property, 1, &values_written, &binding);
+
+    ShaderInput *input = &inputs_[attr_len_ + ubo_len_ + uniform_len_ + ssbo_len_++];
+    input->binding = input->location = binding;
+
+    name_buffer_offset += this->set_input_name(input, name, name_len);
+  }
+
   /* Builtin Uniforms */
   for (int32_t u_int = 0; u_int < GPU_NUM_UNIFORMS; u_int++) {
     GPUUniformBuiltin u = static_cast<GPUUniformBuiltin>(u_int);
diff --git a/source/blender/gpu/tests/gpu_shader_test.cc b/source/blender/gpu/tests/gpu_shader_test.cc
index c6ddef20a45..5a50a4c8b0e 100644
--- a/source/blender/gpu/tests/gpu_shader_test.cc
+++ b/source/blender/gpu/tests/gpu_shader_test.cc
@@ -180,7 +180,7 @@ void main() {
   GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
   GPUVertBuf *vbo = GPU_vertbuf_create_with_format_ex(&format, GPU_USAGE_DEVICE_ONLY);
   GPU_vertbuf_data_alloc(vbo, SIZE);
-  GPU_vertbuf_bind_as_ssbo(vbo, 0);
+  GPU_vertbuf_bind_as_ssbo(vbo, GPU_shader_get_ssbo(shader, "outputVboData"));
 
   /* Dispatch compute task. */
   GPU_compute_dispatch(shader, SIZE, 1, 1);
@@ -252,7 +252,7 @@ void main() {
   }
   GPUIndexBuf *ibo = GPU_indexbuf_build(&ibo_builder);
 
-  GPU_indexbuf_bind_as_ssbo(ibo, 0);
+  GPU_indexbuf_bind_as_ssbo(ibo, GPU_shader_get_ssbo(shad

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list