[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