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
This commit is contained in:
parent
196da819ba
commit
3f42417cd4
|
@ -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;
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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 -- */
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
|
@ -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
|
||||
|
|
|
@ -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<const char *> 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);
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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
|
||||
* \{ */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
|
|
@ -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<const char *> name_list,
|
||||
|
|
Loading…
Reference in New Issue