[Bf-blender-cvs] [bb73a86977a] temp-gpu-compute-shaders: Add GPU api to read vertex/index buffers.
Jeroen Bakker
noreply at git.blender.org
Tue May 11 10:55:48 CEST 2021
Commit: bb73a86977aff4bd83d5945cb45ca7ade43b3e5b
Author: Jeroen Bakker
Date: Tue May 11 10:54:54 2021 +0200
Branches: temp-gpu-compute-shaders
https://developer.blender.org/rBbb73a86977aff4bd83d5945cb45ca7ade43b3e5b
Add GPU api to read vertex/index buffers.
===================================================================
M source/blender/gpu/GPU_index_buffer.h
M source/blender/gpu/GPU_vertex_buffer.h
M source/blender/gpu/intern/gpu_index_buffer.cc
M source/blender/gpu/intern/gpu_index_buffer_private.hh
M source/blender/gpu/intern/gpu_vertex_buffer.cc
M source/blender/gpu/intern/gpu_vertex_buffer_private.hh
M source/blender/gpu/opengl/gl_index_buffer.cc
M source/blender/gpu/opengl/gl_index_buffer.hh
M source/blender/gpu/opengl/gl_vertex_buffer.cc
M source/blender/gpu/opengl/gl_vertex_buffer.hh
M source/blender/gpu/tests/gpu_shader_test.cc
===================================================================
diff --git a/source/blender/gpu/GPU_index_buffer.h b/source/blender/gpu/GPU_index_buffer.h
index 4fabf1eb0de..5ab0299c35d 100644
--- a/source/blender/gpu/GPU_index_buffer.h
+++ b/source/blender/gpu/GPU_index_buffer.h
@@ -80,6 +80,8 @@ void GPU_indexbuf_create_subrange_in_place(GPUIndexBuf *elem,
uint start,
uint length);
+uint32_t *GPU_indexbuf_read(GPUIndexBuf *elem);
+
void GPU_indexbuf_discard(GPUIndexBuf *elem);
bool GPU_indexbuf_is_init(GPUIndexBuf *elem);
diff --git a/source/blender/gpu/GPU_vertex_buffer.h b/source/blender/gpu/GPU_vertex_buffer.h
index 139b11557ec..b528c024e01 100644
--- a/source/blender/gpu/GPU_vertex_buffer.h
+++ b/source/blender/gpu/GPU_vertex_buffer.h
@@ -71,6 +71,7 @@ GPUVertBuf *GPU_vertbuf_create_with_format_ex(const GPUVertFormat *, GPUUsageTyp
#define GPU_vertbuf_create_with_format(format) \
GPU_vertbuf_create_with_format_ex(format, GPU_USAGE_STATIC)
+void *GPU_vertbuf_read(GPUVertBuf *verts);
void GPU_vertbuf_clear(GPUVertBuf *verts);
void GPU_vertbuf_discard(GPUVertBuf *);
diff --git a/source/blender/gpu/intern/gpu_index_buffer.cc b/source/blender/gpu/intern/gpu_index_buffer.cc
index 4d3894ce7d4..b9d1514c7c4 100644
--- a/source/blender/gpu/intern/gpu_index_buffer.cc
+++ b/source/blender/gpu/intern/gpu_index_buffer.cc
@@ -368,6 +368,11 @@ void GPU_indexbuf_create_subrange_in_place(GPUIndexBuf *elem,
unwrap(elem)->init_subrange(unwrap(elem_src), start, length);
}
+uint32_t *GPU_indexbuf_read(GPUIndexBuf *elem)
+{
+ return unwrap(elem)->read();
+}
+
void GPU_indexbuf_discard(GPUIndexBuf *elem)
{
delete unwrap(elem);
diff --git a/source/blender/gpu/intern/gpu_index_buffer_private.hh b/source/blender/gpu/intern/gpu_index_buffer_private.hh
index 7acbf6f1194..113b054953f 100644
--- a/source/blender/gpu/intern/gpu_index_buffer_private.hh
+++ b/source/blender/gpu/intern/gpu_index_buffer_private.hh
@@ -82,7 +82,7 @@ class IndexBuf {
return index_len_;
}
/* Return size in byte of the drawable data buffer range. Actual buffer size might be bigger. */
- size_t size_get(void)
+ size_t size_get(void) const
{
return index_len_ * to_bytesize(index_type_);
};
@@ -94,6 +94,8 @@ class IndexBuf {
virtual void bind_as_ssbo(uint binding) = 0;
+ virtual uint32_t *read() const = 0;
+
private:
inline void squeeze_indices_short(uint min_idx, uint max_idx);
inline uint index_range(uint *r_min, uint *r_max);
diff --git a/source/blender/gpu/intern/gpu_vertex_buffer.cc b/source/blender/gpu/intern/gpu_vertex_buffer.cc
index 3abd7e489f7..fa27ccfbed8 100644
--- a/source/blender/gpu/intern/gpu_vertex_buffer.cc
+++ b/source/blender/gpu/intern/gpu_vertex_buffer.cc
@@ -149,6 +149,11 @@ GPUVertBuf *GPU_vertbuf_duplicate(GPUVertBuf *verts_)
return wrap(unwrap(verts_)->duplicate());
}
+void *GPU_vertbuf_read(GPUVertBuf *verts)
+{
+ return unwrap(verts)->read();
+}
+
/** Same as discard but does not free. */
void GPU_vertbuf_clear(GPUVertBuf *verts)
{
diff --git a/source/blender/gpu/intern/gpu_vertex_buffer_private.hh b/source/blender/gpu/intern/gpu_vertex_buffer_private.hh
index 03c60745f99..27e36ae3915 100644
--- a/source/blender/gpu/intern/gpu_vertex_buffer_private.hh
+++ b/source/blender/gpu/intern/gpu_vertex_buffer_private.hh
@@ -97,6 +97,7 @@ class VertBuf {
}
virtual void update_sub(uint start, uint len, void *data) = 0;
+ virtual void *read() = 0;
protected:
virtual void acquire_data(void) = 0;
diff --git a/source/blender/gpu/opengl/gl_index_buffer.cc b/source/blender/gpu/opengl/gl_index_buffer.cc
index 308fec40038..11822176bce 100644
--- a/source/blender/gpu/opengl/gl_index_buffer.cc
+++ b/source/blender/gpu/opengl/gl_index_buffer.cc
@@ -63,4 +63,24 @@ void GLIndexBuf::bind_as_ssbo(uint binding)
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, binding, ibo_id_);
}
+uint32_t *GLIndexBuf::read() const
+{
+ BLI_assert(is_active());
+ size_t size = size_get();
+ uint32_t *result = static_cast<uint32_t *>(MEM_mallocN(size, __func__));
+ void *data = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
+ memcpy(result, data, size);
+ return result;
+}
+
+bool GLIndexBuf::is_active() const
+{
+ if (!ibo_id_) {
+ return false;
+ }
+ int active_ibo_id = 0;
+ glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &active_ibo_id);
+ return ibo_id_ == active_ibo_id;
+}
+
} // namespace blender::gpu
diff --git a/source/blender/gpu/opengl/gl_index_buffer.hh b/source/blender/gpu/opengl/gl_index_buffer.hh
index 2b0411d03f8..9a1f5c5d4e5 100644
--- a/source/blender/gpu/opengl/gl_index_buffer.hh
+++ b/source/blender/gpu/opengl/gl_index_buffer.hh
@@ -45,6 +45,8 @@ class GLIndexBuf : public IndexBuf {
void bind(void);
void bind_as_ssbo(uint binding) override;
+ uint32_t *read() const override;
+
void *offset_ptr(uint additional_vertex_offset) const
{
additional_vertex_offset += index_start_;
@@ -59,6 +61,9 @@ class GLIndexBuf : public IndexBuf {
return (index_type_ == GPU_INDEX_U16) ? 0xFFFFu : 0xFFFFFFFFu;
}
+ private:
+ bool is_active() const;
+
MEM_CXX_CLASS_ALLOC_FUNCS("GLIndexBuf")
};
diff --git a/source/blender/gpu/opengl/gl_vertex_buffer.cc b/source/blender/gpu/opengl/gl_vertex_buffer.cc
index 9242ca090e5..477af8342f8 100644
--- a/source/blender/gpu/opengl/gl_vertex_buffer.cc
+++ b/source/blender/gpu/opengl/gl_vertex_buffer.cc
@@ -123,6 +123,25 @@ void GLVertBuf::bind_as_ssbo(uint binding)
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, binding, vbo_id_);
}
+void *GLVertBuf::read()
+{
+ BLI_assert(is_active());
+ void *result = MEM_mallocN(vbo_size_, __func__);
+ void *data = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
+ memcpy(result, data, vbo_size_);
+ return result;
+}
+
+bool GLVertBuf::is_active() const
+{
+ if (!vbo_id_) {
+ return false;
+ }
+ int active_vbo_id = 0;
+ glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &active_vbo_id);
+ return vbo_id_ == active_vbo_id;
+}
+
void GLVertBuf::update_sub(uint start, uint len, void *data)
{
glBufferSubData(GL_ARRAY_BUFFER, start, len, data);
diff --git a/source/blender/gpu/opengl/gl_vertex_buffer.hh b/source/blender/gpu/opengl/gl_vertex_buffer.hh
index 77e68908e61..fd7a63db519 100644
--- a/source/blender/gpu/opengl/gl_vertex_buffer.hh
+++ b/source/blender/gpu/opengl/gl_vertex_buffer.hh
@@ -47,6 +47,8 @@ class GLVertBuf : public VertBuf {
void update_sub(uint start, uint len, void *data) override;
+ void *read() override;
+
protected:
void acquire_data(void) override;
void resize_data(void) override;
@@ -55,6 +57,9 @@ class GLVertBuf : public VertBuf {
void duplicate_data(VertBuf *dst) override;
void bind_as_ssbo(uint binding) override;
+ private:
+ bool is_active() const;
+
MEM_CXX_CLASS_ALLOC_FUNCS("GLVertBuf");
};
diff --git a/source/blender/gpu/tests/gpu_shader_test.cc b/source/blender/gpu/tests/gpu_shader_test.cc
index ef06307a9ae..daa9c112060 100644
--- a/source/blender/gpu/tests/gpu_shader_test.cc
+++ b/source/blender/gpu/tests/gpu_shader_test.cc
@@ -185,9 +185,8 @@ void main() {
/* Check if compute has been done. */
GPU_memory_barrier(GPU_BARRIER_SHADER_STORAGE);
- /* Use opengl function to download the vertex buffer. */
- /* TODO(jbakker): Add function to copy it back to the VertexBuffer data. */
- float *data = static_cast<float *>(glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY));
+ /* Download the vertex buffer. */
+ float *data = static_cast<float *>(GPU_vertbuf_read(vbo));
ASSERT_NE(data, nullptr);
for (int index = 0; index < SIZE; index++) {
float expected_value = index;
@@ -196,6 +195,7 @@ void main() {
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();
@@ -246,15 +246,14 @@ void main() {
/* Check if compute has been done. */
GPU_memory_barrier(GPU_BARRIER_SHADER_STORAGE);
- /* Use opengl function to download the index buffer. */
- /* TODO(jbakker): Add function to copy it back to the IndexBuffer data and accessors to read
- * data. */
- uint32_t *data = static_cast<uint32_t *>(glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY));
+ /* Download the index buffer. */
+ uint32_t *data = GPU_indexbuf_read(ibo);
ASSERT_NE(data, nullptr);
for (int index = 0; index < SIZE; index++) {
uint32_t expected = index;
EXPECT_EQ(data[index], expected);
}
+ MEM_freeN(data);
/* Cleanup. */
GPU_shader_unbind();
@@ -264,7 +263,6 @@ void main() {
TEST_F(GPUTest, gpu_shader_ssbo_binding)
{
-
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";
More information about the Bf-blender-cvs
mailing list