From 3f42417cd4c8c01142937ba03c8fa6ef6e895494 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 25 Jan 2022 14:46:25 +0100 Subject: Draw: Migrate hair refine compute shader to use create info. This patch migrates the draw manager hair refine compute shader to use GPUShaderCreateInfo. Reviewed By: fclem Differential Revision: https://developer.blender.org/D13915 --- source/blender/draw/intern/draw_hair.c | 2 +- source/blender/draw/intern/draw_shader.c | 7 +--- .../draw/intern/shaders/common_hair_lib.glsl | 7 ++-- .../intern/shaders/common_hair_refine_comp.glsl | 5 ++- .../draw/intern/shaders/draw_hair_refine_info.hh | 42 ++++++++++++++++++++++ source/blender/gpu/CMakeLists.txt | 1 + source/blender/gpu/intern/gpu_shader.cc | 2 ++ .../blender/gpu/intern/gpu_shader_create_info.cc | 10 +++--- .../blender/gpu/intern/gpu_shader_create_info.hh | 32 ++++++++--------- source/blender/gpu/intern/gpu_shader_private.hh | 1 + source/blender/gpu/opengl/gl_shader.cc | 32 ++++++++++++----- source/blender/gpu/opengl/gl_shader.hh | 1 + 12 files changed, 103 insertions(+), 39 deletions(-) create mode 100644 source/blender/draw/intern/shaders/draw_hair_refine_info.hh diff --git a/source/blender/draw/intern/draw_hair.c b/source/blender/draw/intern/draw_hair.c index bf37ea45dda..e9010d7a81a 100644 --- a/source/blender/draw/intern/draw_hair.c +++ b/source/blender/draw/intern/draw_hair.c @@ -130,7 +130,7 @@ static void drw_hair_particle_cache_update_compute(ParticleHairCache *cache, con GPUShader *shader = hair_refine_shader_get(PART_REFINE_CATMULL_ROM); DRWShadingGroup *shgrp = DRW_shgroup_create(shader, g_tf_pass); drw_hair_particle_cache_shgrp_attach_resources(shgrp, cache, subdiv); - DRW_shgroup_vertex_buffer(shgrp, "hairPointOutputBuffer", cache->final[subdiv].proc_buf); + DRW_shgroup_vertex_buffer(shgrp, "posTime", cache->final[subdiv].proc_buf); const int max_strands_per_call = GPU_max_work_group_count(0); int strands_start = 0; diff --git a/source/blender/draw/intern/draw_shader.c b/source/blender/draw/intern/draw_shader.c index 121a0acd059..28ac76ccd7f 100644 --- a/source/blender/draw/intern/draw_shader.c +++ b/source/blender/draw/intern/draw_shader.c @@ -47,12 +47,7 @@ static struct { static GPUShader *hair_refine_shader_compute_create(ParticleRefineShader UNUSED(refinement)) { - GPUShader *sh = NULL; - sh = GPU_shader_create_compute(datatoc_common_hair_refine_comp_glsl, - datatoc_common_hair_lib_glsl, - "#define HAIR_PHASE_SUBDIV\n", - __func__); - return sh; + return GPU_shader_create_from_info_name("draw_hair_refine_compute"); } static GPUShader *hair_refine_shader_transform_feedback_create( diff --git a/source/blender/draw/intern/shaders/common_hair_lib.glsl b/source/blender/draw/intern/shaders/common_hair_lib.glsl index 6cc7f09a852..049d7785bf7 100644 --- a/source/blender/draw/intern/shaders/common_hair_lib.glsl +++ b/source/blender/draw/intern/shaders/common_hair_lib.glsl @@ -5,6 +5,7 @@ * of data the CPU has to precompute and transfer for each update. */ +#ifndef USE_GPU_SHADER_CREATE_INFO /** * hairStrandsRes: Number of points per hair strand. * 2 - no subdivision @@ -33,8 +34,6 @@ uniform int hairStrandOffset = 0; /* -- Per control points -- */ uniform samplerBuffer hairPointBuffer; /* RGBA32F */ -#define point_position xyz -#define point_time w /* Position along the hair length */ /* -- Per strands data -- */ uniform usamplerBuffer hairStrandBuffer; /* R32UI */ @@ -43,6 +42,10 @@ uniform usamplerBuffer hairStrandSegBuffer; /* R16UI */ /* Not used, use one buffer per uv layer */ // uniform samplerBuffer hairUVBuffer; /* RG32F */ // uniform samplerBuffer hairColBuffer; /* RGBA16 linear color */ +#endif + +#define point_position xyz +#define point_time w /* Position along the hair length */ /* -- Subdivision stage -- */ /** diff --git a/source/blender/draw/intern/shaders/common_hair_refine_comp.glsl b/source/blender/draw/intern/shaders/common_hair_refine_comp.glsl index 4dcde4b0245..6a3a7815cdc 100644 --- a/source/blender/draw/intern/shaders/common_hair_refine_comp.glsl +++ b/source/blender/draw/intern/shaders/common_hair_refine_comp.glsl @@ -1,4 +1,6 @@ +#pragma BLENDER_REQUIRE(common_hair_lib.glsl) +#ifndef USE_GPU_SHADER_CREATE_INFO /* * To be compiled with common_hair_lib.glsl. */ @@ -9,6 +11,7 @@ layout(std430, binding = 0) writeonly buffer hairPointOutputBuffer vec4 posTime[]; } out_vertbuf; +#endif void main(void) { @@ -20,5 +23,5 @@ void main(void) vec4 result = hair_interp_data(data0, data1, data2, data3, weights); uint index = uint(hair_get_id() * hairStrandsRes) + gl_GlobalInvocationID.y; - out_vertbuf.posTime[index] = result; + posTime[index] = result; } diff --git a/source/blender/draw/intern/shaders/draw_hair_refine_info.hh b/source/blender/draw/intern/shaders/draw_hair_refine_info.hh new file mode 100644 index 00000000000..3c1af1bf759 --- /dev/null +++ b/source/blender/draw/intern/shaders/draw_hair_refine_info.hh @@ -0,0 +1,42 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2022 Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup draw + */ + +#include "gpu_shader_create_info.hh" + +GPU_SHADER_CREATE_INFO(draw_hair_refine_compute) + .local_group_size(1, 1) + .storage_buf(0, Qualifier::WRITE_ONLY, "vec4", "posTime[]") + .sampler(0, ImageType::FLOAT_BUFFER, "hairPointBuffer") + .sampler(1, ImageType::UINT_BUFFER, "hairStrandBuffer") + .sampler(2, ImageType::UINT_BUFFER, "hairStrandSegBuffer") + .push_constant(0, Type::VEC4, "hairDupliMatrix", 4) + .push_constant(16, Type::BOOL, "hairCloseTip") + .push_constant(17, Type::FLOAT, "hairRadShape") + .push_constant(18, Type::FLOAT, "hairRadTip") + .push_constant(19, Type::FLOAT, "hairRadRoot") + .push_constant(20, Type::INT, "hairThicknessRes") + .push_constant(21, Type::INT, "hairStrandsRes") + .push_constant(22, Type::INT, "hairStrandOffset") + .compute_source("common_hair_refine_comp.glsl") + .define("HAIR_PHASE_SUBDIV") + .do_static_compilation(true); diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 4bb66b78dd0..3e811caa14b 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -406,6 +406,7 @@ set(SHADER_CREATE_INFOS ../draw/intern/shaders/draw_fullscreen_info.hh ../draw/intern/shaders/draw_object_infos_info.hh ../draw/intern/shaders/draw_view_info.hh +../draw/intern/shaders/draw_hair_refine_info.hh shaders/infos/gpu_clip_planes_info.hh shaders/infos/gpu_shader_2D_area_borders_info.hh diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc index 8c97f423800..ef800abc3c9 100644 --- a/source/blender/gpu/intern/gpu_shader.cc +++ b/source/blender/gpu/intern/gpu_shader.cc @@ -394,6 +394,7 @@ GPUShader *GPU_shader_create_from_info(const GPUShaderCreateInfo *_info) uint32_t builtins = 0; char *code = gpu_shader_dependency_get_resolved_source(info.compute_source_.c_str(), &builtins); + std::string layout = shader->compute_layout_declare(info); Vector sources; standard_defines(sources); @@ -406,6 +407,7 @@ GPUShader *GPU_shader_create_from_info(const GPUShaderCreateInfo *_info) sources.append(types); } sources.append(resources.c_str()); + sources.append(layout.c_str()); sources.append(code); shader->compute_shader_from_glsl(sources); diff --git a/source/blender/gpu/intern/gpu_shader_create_info.cc b/source/blender/gpu/intern/gpu_shader_create_info.cc index b8ae6bc3868..9a32e1b2406 100644 --- a/source/blender/gpu/intern/gpu_shader_create_info.cc +++ b/source/blender/gpu/intern/gpu_shader_create_info.cc @@ -74,12 +74,12 @@ void ShaderCreateInfo::finalize() validate(info); - if (info.local_group_size_[0] != 0) { - BLI_assert(local_group_size_[0] == 0); - for (int i = 0; i < 3; i++) { - local_group_size_[i] = info.local_group_size_[i]; - } + if (info.compute_layout_.local_size_x != -1) { + compute_layout_.local_size_x = info.compute_layout_.local_size_x; + compute_layout_.local_size_y = info.compute_layout_.local_size_y; + compute_layout_.local_size_z = info.compute_layout_.local_size_z; } + if (!info.vertex_source_.is_empty()) { BLI_assert(vertex_source_.is_empty()); vertex_source_ = info.vertex_source_; diff --git a/source/blender/gpu/intern/gpu_shader_create_info.hh b/source/blender/gpu/intern/gpu_shader_create_info.hh index c7b3ac5ca37..02c303fb8fa 100644 --- a/source/blender/gpu/intern/gpu_shader_create_info.hh +++ b/source/blender/gpu/intern/gpu_shader_create_info.hh @@ -223,8 +223,6 @@ struct ShaderCreateInfo { * Only for names used by gpu::ShaderInterface. */ size_t interface_names_size_ = 0; - /** Only for compute shaders. */ - int local_group_size_[3] = {0, 0, 0}; struct VertIn { int index; @@ -242,6 +240,14 @@ struct ShaderCreateInfo { }; GeometryStageLayout geometry_layout_; + struct ComputeStageLayout { + int local_size_x = -1; + int local_size_y = -1; + int local_size_z = -1; + }; + + ComputeStageLayout compute_layout_; + struct FragOut { int index; Type type; @@ -366,6 +372,14 @@ struct ShaderCreateInfo { return *(Self *)this; } + Self &local_group_size(int local_size_x = -1, int local_size_y = -1, int local_size_z = -1) + { + compute_layout_.local_size_x = local_size_x; + compute_layout_.local_size_y = local_size_y; + compute_layout_.local_size_z = local_size_z; + return *(Self *)this; + } + /* Only needed if geometry shader is enabled. */ Self &geometry_out(StageInterfaceInfo &interface) { @@ -503,20 +517,6 @@ struct ShaderCreateInfo { /** \} */ - /* -------------------------------------------------------------------- */ - /** \name Compute shaders Local Group Size - * \{ */ - - Self &local_group_size(int x, int y = 1, int z = 1) - { - local_group_size_[0] = x; - local_group_size_[1] = y; - local_group_size_[2] = z; - return *(Self *)this; - } - - /** \} */ - /* -------------------------------------------------------------------- */ /** \name Defines * \{ */ diff --git a/source/blender/gpu/intern/gpu_shader_private.hh b/source/blender/gpu/intern/gpu_shader_private.hh index 7837af0dcf2..3bfecdefba7 100644 --- a/source/blender/gpu/intern/gpu_shader_private.hh +++ b/source/blender/gpu/intern/gpu_shader_private.hh @@ -77,6 +77,7 @@ class Shader { virtual std::string fragment_interface_declare(const shader::ShaderCreateInfo &info) const = 0; virtual std::string geometry_interface_declare(const shader::ShaderCreateInfo &info) const = 0; virtual std::string geometry_layout_declare(const shader::ShaderCreateInfo &info) const = 0; + virtual std::string compute_layout_declare(const shader::ShaderCreateInfo &info) const = 0; /* DEPRECATED: Kept only because of BGL API. */ virtual int program_handle_get() const = 0; diff --git a/source/blender/gpu/opengl/gl_shader.cc b/source/blender/gpu/opengl/gl_shader.cc index cec85abae6f..bf18ba09c03 100644 --- a/source/blender/gpu/opengl/gl_shader.cc +++ b/source/blender/gpu/opengl/gl_shader.cc @@ -271,16 +271,16 @@ static void print_image_type(std::ostream &os, static std::ostream &print_qualifier(std::ostream &os, const Qualifier &qualifiers) { - if ((qualifiers & Qualifier::RESTRICT) != Qualifier::RESTRICT) { - os << "restrict"; + if ((qualifiers & Qualifier::RESTRICT) == Qualifier::RESTRICT) { + os << "restrict "; } - if ((qualifiers & Qualifier::READ_ONLY) != Qualifier::READ_ONLY) { - os << "readonly"; + if ((qualifiers & Qualifier::READ_ONLY) == Qualifier::READ_ONLY) { + os << "readonly "; } - if ((qualifiers & Qualifier::WRITE_ONLY) != Qualifier::WRITE_ONLY) { - os << "writeonly"; + if ((qualifiers & Qualifier::WRITE_ONLY) == Qualifier::WRITE_ONLY) { + os << "writeonly "; } - return os << " "; + return os; } static void print_resource(std::ostream &os, const ShaderCreateInfo::Resource &res) @@ -328,8 +328,8 @@ static void print_resource(std::ostream &os, const ShaderCreateInfo::Resource &r array_offset = res.storagebuf.name.find_first_of("["); name_no_array = (array_offset == -1) ? res.storagebuf.name : StringRef(res.storagebuf.name.c_str(), array_offset); - os << "buffer "; print_qualifier(os, res.storagebuf.qualifiers); + os << "buffer "; os << name_no_array << " { " << res.storagebuf.type_name << " _" << res.storagebuf.name << "; };\n"; break; @@ -507,6 +507,22 @@ std::string GLShader::geometry_interface_declare(const ShaderCreateInfo &info) c return ss.str(); } +std::string GLShader::compute_layout_declare(const ShaderCreateInfo &info) const +{ + std::stringstream ss; + ss << "\n/* Compute Layout. */\n"; + ss << "layout(local_size_x = " << info.compute_layout_.local_size_x; + if (info.compute_layout_.local_size_y != -1) { + ss << ", local_size_y = " << info.compute_layout_.local_size_y; + } + if (info.compute_layout_.local_size_z != -1) { + ss << ", local_size_y = " << info.compute_layout_.local_size_z; + } + ss << ") in;\n"; + ss << "\n"; + return ss.str(); +} + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/gpu/opengl/gl_shader.hh b/source/blender/gpu/opengl/gl_shader.hh index af92c77db54..a82ab026c16 100644 --- a/source/blender/gpu/opengl/gl_shader.hh +++ b/source/blender/gpu/opengl/gl_shader.hh @@ -69,6 +69,7 @@ class GLShader : public Shader { std::string fragment_interface_declare(const shader::ShaderCreateInfo &info) const override; std::string geometry_interface_declare(const shader::ShaderCreateInfo &info) const override; std::string geometry_layout_declare(const shader::ShaderCreateInfo &info) const override; + std::string compute_layout_declare(const shader::ShaderCreateInfo &info) const override; /** Should be called before linking. */ void transform_feedback_names_set(Span name_list, -- cgit v1.2.3