[Bf-blender-cvs] [6111568598d] temp-gpu-compute-shaders: Use storage objects.

Jeroen Bakker noreply at git.blender.org
Mon Apr 26 15:15:12 CEST 2021


Commit: 6111568598d561080477bc717b6d5d70bce6ec3c
Author: Jeroen Bakker
Date:   Mon Apr 26 11:34:35 2021 +0200
Branches: temp-gpu-compute-shaders
https://developer.blender.org/rB6111568598d561080477bc717b6d5d70bce6ec3c

Use storage objects.

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

M	source/blender/gpu/GPU_compute.h
M	source/blender/gpu/GPU_shader.h
M	source/blender/gpu/GPU_state.h
M	source/blender/gpu/intern/gpu_compute.cc
M	source/blender/gpu/intern/gpu_shader.cc
M	source/blender/gpu/intern/gpu_shader_private.hh
M	source/blender/gpu/opengl/gl_shader.cc
M	source/blender/gpu/opengl/gl_shader.hh
M	source/blender/gpu/opengl/gl_state.hh
M	source/blender/gpu/opengl/gl_texture.cc
M	source/blender/gpu/tests/gpu_shader_test.cc
M	source/blender/gpu/tests/gpu_testing.cc

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

diff --git a/source/blender/gpu/GPU_compute.h b/source/blender/gpu/GPU_compute.h
index 88230e8a065..a048f72c0a0 100644
--- a/source/blender/gpu/GPU_compute.h
+++ b/source/blender/gpu/GPU_compute.h
@@ -20,13 +20,18 @@
 
 #pragma once
 
+#include "BLI_sys_types.h"
+
 #include "GPU_shader.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-void GPU_compute_dispatch(GPUShader *shader, int groups_x_len, int groups_y_len, int groups_z_len);
+void GPU_compute_dispatch(GPUShader *shader,
+                          uint groups_x_len,
+                          uint groups_y_len,
+                          uint groups_z_len);
 
 #ifdef __cplusplus
 }
diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h
index 22d607327e7..bb84aaa0645 100644
--- a/source/blender/gpu/GPU_shader.h
+++ b/source/blender/gpu/GPU_shader.h
@@ -88,6 +88,8 @@ void GPU_shader_unbind(void);
 bool GPU_shader_transform_feedback_enable(GPUShader *shader, struct GPUVertBuf *vertbuf);
 void GPU_shader_transform_feedback_disable(GPUShader *shader);
 
+void GPU_shader_attach_vertex_buffer(GPUShader *shader, struct GPUVertBuf *vertbuf, int location);
+
 int GPU_shader_get_program(GPUShader *shader);
 
 typedef enum {
diff --git a/source/blender/gpu/GPU_state.h b/source/blender/gpu/GPU_state.h
index 0687f271670..16106e3053b 100644
--- a/source/blender/gpu/GPU_state.h
+++ b/source/blender/gpu/GPU_state.h
@@ -39,6 +39,8 @@ typedef enum eGPUBarrier {
   GPU_BARRIER_NONE = 0,
   GPU_BARRIER_SHADER_IMAGE_ACCESS = (1 << 0),
   GPU_BARRIER_TEXTURE_FETCH = (1 << 1),
+  GPU_BARRIER_VERTEX_ATTRIB_ARRAY = (1 << 2),
+  GPU_BARRIER_SHADER_STORAGE = (1 << 3),
 } eGPUBarrier;
 
 ENUM_OPERATORS(eGPUBarrier, GPU_BARRIER_TEXTURE_FETCH)
diff --git a/source/blender/gpu/intern/gpu_compute.cc b/source/blender/gpu/intern/gpu_compute.cc
index 6c5f6bafee1..963726538c1 100644
--- a/source/blender/gpu/intern/gpu_compute.cc
+++ b/source/blender/gpu/intern/gpu_compute.cc
@@ -26,7 +26,7 @@
 extern "C" {
 #endif
 
-void GPU_compute_dispatch(GPUShader *shader, int groups_x_len, int groups_y_len, int groups_z_len)
+void GPU_compute_dispatch(GPUShader *shader, uint groups_x_len, uint groups_y_len, uint groups_z_len)
 {
   blender::gpu::GPUBackend &gpu_backend = *blender::gpu::GPUBackend::get();
   GPU_shader_bind(shader);
diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc
index fdd912bfd87..b5c3b2c3f58 100644
--- a/source/blender/gpu/intern/gpu_shader.cc
+++ b/source/blender/gpu/intern/gpu_shader.cc
@@ -582,6 +582,17 @@ void GPU_shader_transform_feedback_disable(GPUShader *shader)
 
 /** \} */
 
+/* -------------------------------------------------------------------- */
+/** \name Buffer binding
+ * \{ */
+
+void GPU_shader_attach_vertex_buffer(GPUShader *shader, struct GPUVertBuf *vertbuf, int position)
+{
+  unwrap(shader)->attach_buffer(vertbuf, position);
+}
+
+/** \} */
+
 /* -------------------------------------------------------------------- */
 /** \name Uniforms / Resource location
  * \{ */
diff --git a/source/blender/gpu/intern/gpu_shader_private.hh b/source/blender/gpu/intern/gpu_shader_private.hh
index 281f01dbc22..a6f2e617777 100644
--- a/source/blender/gpu/intern/gpu_shader_private.hh
+++ b/source/blender/gpu/intern/gpu_shader_private.hh
@@ -57,6 +57,8 @@ class Shader {
   virtual bool transform_feedback_enable(GPUVertBuf *) = 0;
   virtual void transform_feedback_disable(void) = 0;
 
+  virtual void attach_buffer(GPUVertBuf *vertex_buffer, uint location) = 0;
+
   virtual void bind(void) = 0;
   virtual void unbind(void) = 0;
 
diff --git a/source/blender/gpu/opengl/gl_shader.cc b/source/blender/gpu/opengl/gl_shader.cc
index 8cdbc647dcf..c0809a0387e 100644
--- a/source/blender/gpu/opengl/gl_shader.cc
+++ b/source/blender/gpu/opengl/gl_shader.cc
@@ -26,6 +26,7 @@
 #include "BLI_string.h"
 #include "BLI_vector.hh"
 
+#include "GPU_capabilities.h"
 #include "GPU_platform.h"
 
 #include "gl_backend.hh"
@@ -299,6 +300,21 @@ void GLShader::transform_feedback_disable()
 
 /** \} */
 
+/* -------------------------------------------------------------------- */
+/** \name Attach buffers
+ * \{ */
+
+void GLShader::attach_buffer(GPUVertBuf *vertex_buffer_, unsigned int location)
+{
+  BLI_assert(GPU_compute_shader_support());
+  GLVertBuf *vertex_buffer = static_cast<GLVertBuf *>(unwrap(vertex_buffer_));
+  vertex_buffer->bind();
+  BLI_assert(vertex_buffer->vbo_id_ != 0);
+  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, location, vertex_buffer->vbo_id_);
+}
+
+/** \} */
+
 /* -------------------------------------------------------------------- */
 /** \name Uniforms setters
  * \{ */
diff --git a/source/blender/gpu/opengl/gl_shader.hh b/source/blender/gpu/opengl/gl_shader.hh
index 48aaaf2283d..3993944b974 100644
--- a/source/blender/gpu/opengl/gl_shader.hh
+++ b/source/blender/gpu/opengl/gl_shader.hh
@@ -65,6 +65,8 @@ class GLShader : public Shader {
   bool transform_feedback_enable(GPUVertBuf *buf) override;
   void transform_feedback_disable(void) override;
 
+  void attach_buffer(GPUVertBuf *vertex_buffer, uint location) override;
+
   void bind(void) override;
   void unbind(void) override;
 
diff --git a/source/blender/gpu/opengl/gl_state.hh b/source/blender/gpu/opengl/gl_state.hh
index 651c3c22afa..c1dc814eb24 100644
--- a/source/blender/gpu/opengl/gl_state.hh
+++ b/source/blender/gpu/opengl/gl_state.hh
@@ -121,6 +121,12 @@ static inline GLbitfield to_gl(eGPUBarrier barrier_bits)
   if (barrier_bits & GPU_BARRIER_TEXTURE_FETCH) {
     barrier |= GL_TEXTURE_FETCH_BARRIER_BIT;
   }
+  if (barrier_bits & GPU_BARRIER_VERTEX_ATTRIB_ARRAY) {
+    barrier |= GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT;
+  }
+  if (barrier_bits & GPU_BARRIER_SHADER_STORAGE) {
+    barrier |= GL_SHADER_STORAGE_BARRIER_BIT;
+  }
   return barrier;
 }
 
diff --git a/source/blender/gpu/opengl/gl_texture.cc b/source/blender/gpu/opengl/gl_texture.cc
index b65686165d9..e2478a9976c 100644
--- a/source/blender/gpu/opengl/gl_texture.cc
+++ b/source/blender/gpu/opengl/gl_texture.cc
@@ -368,7 +368,7 @@ void GLTexture::copy_to(Texture *dst_)
 void *GLTexture::read(int mip, eGPUDataFormat type)
 {
   BLI_assert(!(format_flag_ & GPU_FORMAT_COMPRESSED));
-  BLI_assert(mip <= mipmaps_);
+  BLI_assert(mip <= mipmaps_ || mip == 0);
   BLI_assert(validate_data_format(format_, type));
 
   /* NOTE: mip_size_get() won't override any dimension that is equal to 0. */
diff --git a/source/blender/gpu/tests/gpu_shader_test.cc b/source/blender/gpu/tests/gpu_shader_test.cc
index ad15deeaa6d..3e778ca3e10 100644
--- a/source/blender/gpu/tests/gpu_shader_test.cc
+++ b/source/blender/gpu/tests/gpu_shader_test.cc
@@ -6,6 +6,8 @@
 #include "GPU_compute.h"
 #include "GPU_shader.h"
 #include "GPU_texture.h"
+#include "GPU_vertex_buffer.h"
+#include "GPU_vertex_format.h"
 
 #include "MEM_guardedalloc.h"
 
@@ -22,7 +24,7 @@ TEST_F(GPUTest, gpu_shader_compute)
     return;
   }
 
-  static constexpr int SIZE = 512;
+  static constexpr uint SIZE = 512;
 
   /* Build compute shader. */
   const char *compute_glsl = R"(
@@ -74,4 +76,78 @@ void main() {
   GPU_shader_free(shader);
 }
 
+TEST_F(GPUTest, gpu_shader_compute_write_vbo)
+{
+
+  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;
+  }
+
+  static constexpr uint SIZE = 10;
+
+  /* Build compute shader. */
+  const char *compute_glsl = R"(
+
+layout(local_size_x = 1) in;
+
+struct VBOData {
+  vec4 pos;
+};
+
+layout(std140, binding = 1) buffer outputVboData {
+  VBOData data[];
+};
+
+void main() {
+  int index = int(gl_GlobalInvocationID.x);
+  vec4 pos = vec4(gl_GlobalInvocationID.x);
+  data[index].pos = pos;
+}
+
+)";
+
+  GPUShader *shader = GPU_shader_create_compute(
+      compute_glsl, nullptr, nullptr, "gpu_shader_compute");
+  EXPECT_NE(shader, nullptr);
+
+  /* Construct VBO. */
+  static GPUVertFormat format = {0};
+  GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+  /* TODO: Should add a new GPU_USAGE_TYPE. (device only) that won't upload the data. */
+  GPUVertBuf *vbo = GPU_vertbuf_create_with_format_ex(&format, GPU_USAGE_STATIC);
+  GPU_vertbuf_data_alloc(vbo, SIZE);
+
+  GPU_shader_bind(shader);
+  GPU_shader_attach_vertex_buffer(shader, vbo, 1);
+
+  /* Dispatch compute task. */
+  GPU_compute_dispatch(shader, SIZE, 1, 1);
+
+  /* Check if compute has been done. */
+  GPU_memory_barrier(GPU_BARRIER_SHADER_STORAGE | GPU_BARRIER_VERTEX_ATTRIB_ARRAY);
+
+  /* Create texture to load back result. */
+  GPUTexture *texture = GPU_texture_create_from_vertbuf("gpu_shader_compute_write_vbo", vbo);
+  EXPECT_NE(texture, nullptr);
+  float *data = static_cast<float *>(GPU_texture_read(texture, GPU_DATA_FLOAT, 0));
+  EXPECT_NE(data, nullptr);
+  for (int index = 0; index < SIZE; index++) {
+    float expected_value = index;
+    EXPECT_FLOAT_EQ(data[index * 4 + 0], expected_value);
+    EXPECT_FLOAT_EQ(data[index * 4 + 1], expected_value);
+    EXPECT_FLOAT_EQ(data[index * 4 + 2], expected_value);
+    EXPECT_FLOAT_EQ(data[index * 4 + 3], expected_value);
+  }
+  MEM_freeN(data);
+
+  /* Cleanup. */
+  GPU_shader_unbind();
+  GPU_texture_unbind(texture);
+  GPU_texture_free(texture);
+  GPU_vertbuf_discard(vbo);
+  GPU_shader_free(shader);
+}
+
 }  // namespace blender::gpu::tests
diff --git a/source/blender/gpu/tests/gpu_testing.cc b/source/blender/gpu/tests/gpu_testing.cc
index b9fc78dc084..ac42c5875c8 100644
--- a/source/blender/gpu/tests/gpu_testing.cc
+++ b/source/blender/gpu/tests/gpu_testing.cc
@@ -2,6 +2,8 @@
 
 #include "testing/testing.h"
 
+#include "CLG_log.h"
+
 #include "GPU_context.h"
 #include "GPU_init_exit.h"
 #include "gpu_testing.hh"
@@ -13,6 +15,7 @@ namespace blender::gpu {
 void GPUTest::SetUp()
 {
   GHOST_GLSettings glSettings = {0};
+  CLG_init();
   ghost_system = GHOST_CreateSystem();
   ghost_context = GHOST_CreateOpenGLContext(ghost_system, glSettings);
   context = GPU_context_create(nullptr);
@@ -26,6 +29,7 @@ void GPUTest::TearDown()
   GPU_context_discard(context);
   GHOST_DisposeOpenGLContext(ghost_system, ghost_context);
   GHOST_DisposeSystem(ghost_

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list