[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