37 # define USE_TRANSFORM_FEEDBACK
38 # define USE_COMPUTE_SHADERS
43 #ifdef USE_COMPUTE_SHADERS
48 #ifdef USE_TRANSFORM_FEEDBACK
54 #ifndef USE_TRANSFORM_FEEDBACK
55 struct CurvesEvalCall {
56 struct CurvesEvalCall *
next;
62 static CurvesEvalCall *g_tf_calls =
nullptr;
63 static int g_tf_id_offset;
64 static int g_tf_target_width;
65 static int g_tf_target_height;
86 ubos.append(std::make_unique<CurvesInfosBuf>());
104 drw_data->
curves_ubos = MEM_new<CurvesUniformBufPool>(
"CurvesUniformBufPool");
109 #if defined(USE_TRANSFORM_FEEDBACK) || defined(USE_COMPUTE_SHADERS)
122 const float vert[4] = {0.0f, 0.0f, 0.0f, 0.0f};
150 const int strands_len,
160 int strands_start = 0;
161 while (strands_start < strands_len) {
162 int batch_strands_len =
MIN2(strands_len - strands_start, max_strands_per_call);
166 strands_start += batch_strands_len;
173 const int final_points_len = cache->
final[subdiv].
strands_res * strands_len;
174 if (final_points_len == 0) {
200 const int final_points_len)
204 #ifdef USE_TRANSFORM_FEEDBACK
209 CurvesEvalCall *pr_call = MEM_new<CurvesEvalCall>(__func__);
210 pr_call->next = g_tf_calls;
212 pr_call->shgrp = tf_shgrp;
213 pr_call->vert_len = final_points_len;
214 g_tf_calls = pr_call;
227 if (final_points_len == 0) {
256 &
curves, &cache, gpu_material, subdiv, thickness_res);
293 if (
STREQ(gpu_attr->name, name)) {
311 Curves &curves_id = *
static_cast<Curves *
>(
object->data);
317 curves_id, gpu_material, subdiv, thickness_res);
329 float hair_rad_shape = 0.0f;
330 float hair_rad_root = 0.005f;
331 float hair_rad_tip = 0.0f;
332 bool hair_close_tip =
true;
338 if (
curves.curves_num() >= 1) {
342 const float first_radius =
radii[first_curve_points.
first()];
343 const float last_radius =
radii[first_curve_points.
last()];
344 const float middle_radius =
radii[first_curve_points.
size() / 2];
345 hair_rad_root =
radii[first_curve_points.
first()];
346 hair_rad_tip =
radii[first_curve_points.
last()];
348 safe_divide(middle_radius - first_radius, last_radius - first_radius) * 2.0f - 1.0f,
362 char sampler_name[32];
419 #ifndef USE_TRANSFORM_FEEDBACK
430 if (g_tf_calls ==
nullptr) {
436 for (CurvesEvalCall *pr_call = g_tf_calls; pr_call; pr_call = pr_call->next) {
437 max_size =
max_ii(max_size, pr_call->vert_len);
447 g_tf_target_height =
height;
448 g_tf_target_width =
width;
451 GPU_framebuffer_ensure_config(&
fb,
454 GPU_ATTACHMENT_TEXTURE(
tex),
457 float *
data =
static_cast<float *
>(
461 while (g_tf_calls !=
nullptr) {
462 CurvesEvalCall *pr_call = g_tf_calls;
463 g_tf_calls = g_tf_calls->next;
466 while (pr_call->vert_len > 0) {
475 sizeof(
float[4]) * g_tf_id_offset,
476 sizeof(
float[4]) * max_read_px_len,
479 g_tf_id_offset += max_read_px_len;
480 pr_call->vert_len -= max_read_px_len;
Low-level operations for curves.
#define LISTBASE_FOREACH(type, var, list)
MINLINE int min_ii(int a, int b)
MINLINE int max_ii(int a, int b)
#define DRW_shgroup_vertex_buffer(shgroup, name, vert)
#define DRW_shgroup_call_no_cull(shgroup, geom, ob)
#define DRW_shgroup_uniform_block(shgroup, name, ubo)
#define DRW_TEXTURE_FREE_SAFE(tex)
bool GPU_compute_shader_support(void)
int GPU_max_work_group_count(int index)
bool GPU_shader_storage_buffer_objects_support(void)
struct GPUFrameBuffer GPUFrameBuffer
void GPU_framebuffer_free(GPUFrameBuffer *fb)
void GPU_framebuffer_bind(GPUFrameBuffer *fb)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
ListBase GPU_material_attributes(GPUMaterial *material)
struct GPUShader GPUShader
void GPU_memory_barrier(eGPUBarrier barrier)
@ GPU_BARRIER_SHADER_STORAGE
struct GPUTexture GPUTexture
GPUTexture * GPU_texture_create_from_vertbuf(const char *name, struct GPUVertBuf *vert)
#define GPU_vertbuf_create_with_format(format)
struct GPUVertBuf GPUVertBuf
void GPU_vertbuf_update_sub(GPUVertBuf *verts, uint start, uint len, const void *data)
void GPU_vertbuf_data_alloc(GPUVertBuf *, uint v_len)
#define GPU_VERTBUF_DISCARD_SAFE(verts)
void GPU_vertbuf_use(GPUVertBuf *)
void GPU_vertbuf_attr_fill(GPUVertBuf *, uint a_idx, const void *data)
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to curves
constexpr int64_t first() const
constexpr int64_t last(const int64_t n=0) const
constexpr int64_t size() const
static CurvesGeometry & wrap(::CurvesGeometry &dna_struct)
bool curves_ensure_procedural_data(Curves *curves, CurvesEvalCache **r_hair_cache, GPUMaterial *gpu_material, const int subdiv, const int thickness_res)
void drw_curves_get_attribute_sampler_name(const char *layer_name, char r_sampler_name[32])
void DRW_hair_update(void)
DRWShadingGroup * DRW_shgroup_curves_create_sub(Object *object, DRWShadingGroup *shgrp_parent, GPUMaterial *gpu_material)
void DRW_curves_init(DRWData *drw_data)
static void drw_curves_cache_shgrp_attach_resources(DRWShadingGroup *shgrp, CurvesEvalCache *cache, GPUTexture *tex, const int subdiv)
BLI_INLINE eParticleRefineShaderType drw_curves_shader_type_get()
static GPUTexture * g_dummy_texture
static GPUVertBuf * g_dummy_vbo
static GPUShader * curves_eval_shader_get(CurvesEvalShader type)
void DRW_curves_ubos_pool_free(CurvesUniformBufPool *pool)
GPUVertBuf * DRW_curves_pos_buffer_get(Object *object)
static void drw_curves_cache_update_transform_feedback(CurvesEvalCache *cache, GPUVertBuf *vbo, GPUTexture *tex, const int subdiv, const int final_points_len)
static CurvesEvalCache * drw_curves_cache_get(Curves &curves, GPUMaterial *gpu_material, int subdiv, int thickness_res)
static void drw_curves_cache_update_compute(CurvesEvalCache *cache, const int subdiv, const int strands_len, GPUVertBuf *buffer, GPUTexture *tex)
static int attribute_index_in_material(GPUMaterial *gpu_material, const char *name)
static DRWPass * g_tf_pass
@ CURVES_EVAL_CATMULL_ROM
const DRWContextState * DRW_context_state_get(void)
void DRW_shgroup_uniform_float_copy(DRWShadingGroup *shgroup, const char *name, const float value)
void DRW_shgroup_uniform_texture(DRWShadingGroup *shgroup, const char *name, const GPUTexture *tex)
void DRW_shgroup_call_compute(DRWShadingGroup *shgroup, int groups_x_len, int groups_y_len, int groups_z_len)
void DRW_shgroup_call_procedural_points(DRWShadingGroup *shgroup, Object *ob, uint point_count)
void DRW_shgroup_uniform_int_copy(DRWShadingGroup *shgroup, const char *name, const int value)
DRWShadingGroup * DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass)
void DRW_shgroup_uniform_int(DRWShadingGroup *shgroup, const char *name, const int *value, int arraysize)
DRWShadingGroup * DRW_shgroup_transform_feedback_create(struct GPUShader *shader, DRWPass *pass, GPUVertBuf *tf_target)
void DRW_shgroup_add_material_resources(DRWShadingGroup *grp, struct GPUMaterial *material)
DRWShadingGroup * DRW_shgroup_create_sub(DRWShadingGroup *shgroup)
DRWPass * DRW_pass_create(const char *name, DRWState state)
void DRW_shgroup_uniform_bool_copy(DRWShadingGroup *shgroup, const char *name, const bool value)
void DRW_shgroup_uniform_mat4_copy(DRWShadingGroup *shgroup, const char *name, const float(*value)[4])
void DRW_draw_pass(DRWPass *pass)
void DRW_draw_pass_subset(DRWPass *pass, DRWShadingGroup *start_group, DRWShadingGroup *end_group)
GPUTexture * DRW_texture_pool_query_2d(int w, int h, eGPUTextureFormat format, DrawEngineType *engine_type)
GPUShader * DRW_shader_curves_refine_get(CurvesEvalShader type, eParticleRefineShaderType sh_type)
eParticleRefineShaderType
@ PART_REFINE_SHADER_TRANSFORM_FEEDBACK_WORKAROUND
@ PART_REFINE_SHADER_COMPUTE
@ PART_REFINE_SHADER_TRANSFORM_FEEDBACK
void GPU_framebuffer_read_color(GPUFrameBuffer *gpu_fb, int x, int y, int w, int h, int channels, int slot, eGPUDataFormat format, void *data)
BLI_INLINE float fb(float length, float L)
ccl_global float * buffer
void(* MEM_freeN)(void *vmemh)
void *(* MEM_mallocN)(size_t len, const char *str)
T clamp(const T &a, const T &min, const T &max)
T safe_divide(const T &a, const T &b)
static void update(bNodeTree *ntree)
MutableSpan< float > radii
CurvesEvalFinalCache final[MAX_HAIR_SUBDIV]
GPUTexture * proc_attributes_tex[GPU_MAX_ATTR]
GPUTexture * strand_seg_tex
GPUBatch * proc_hairs[MAX_THICKRES]
GPUVertBuf * attributes_buf[GPU_MAX_ATTR]
GPUTexture * attributes_tex[GPU_MAX_ATTR]
struct CurvesUniformBufPool * curves_ubos
DRW_AttributeRequest requests[GPU_MAX_ATTR]