[Bf-blender-cvs] [010d0c222d5] temp-gpu-compute-shader-hair: Use attach vertex buffer.

Jeroen Bakker noreply at git.blender.org
Wed Apr 28 14:18:34 CEST 2021


Commit: 010d0c222d5e5c9d5637fbb20b44b2c9dd2c1776
Author: Jeroen Bakker
Date:   Wed Apr 28 14:18:05 2021 +0200
Branches: temp-gpu-compute-shader-hair
https://developer.blender.org/rB010d0c222d5e5c9d5637fbb20b44b2c9dd2c1776

Use attach vertex buffer.

===================================================================

M	source/blender/draw/intern/DRW_render.h
M	source/blender/draw/intern/draw_hair.c
M	source/blender/draw/intern/draw_manager.h
M	source/blender/draw/intern/draw_manager_data.c
M	source/blender/draw/intern/draw_manager_exec.c
M	source/blender/draw/intern/shaders/common_hair_refine_vert.glsl

===================================================================

diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index 949a2225aa6..d9ed760c4b8 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -579,6 +579,9 @@ void DRW_shgroup_uniform_vec4_array_copy(DRWShadingGroup *shgroup,
                                          const char *name,
                                          const float (*value)[4],
                                          int arraysize);
+void DRW_shgroup_vertex_buffer(DRWShadingGroup *shgroup,
+                               const int location,
+                               struct GPUVertBuf *vertex_buffer);
 
 bool DRW_shgroup_is_empty(DRWShadingGroup *shgroup);
 
diff --git a/source/blender/draw/intern/draw_hair.c b/source/blender/draw/intern/draw_hair.c
index 1f75a760be3..2ea8edc6abd 100644
--- a/source/blender/draw/intern/draw_hair.c
+++ b/source/blender/draw/intern/draw_hair.c
@@ -97,7 +97,7 @@ static GPUShader *hair_refine_shader_get(ParticleRefineShader sh)
   const bool do_compute = drw_hair_use_compute_shaders();
   if (do_compute) {
     g_refine_shaders[sh] = GPU_shader_create_compute(datatoc_common_hair_refine_vert_glsl,
-                                                     NULL /* datatoc_common_hair_lib_glsl*/,
+                                                     datatoc_common_hair_lib_glsl,
                                                      "#define HAIR_PHASE_SUBDIV\n",
                                                      __func__);
     return g_refine_shaders[sh];
@@ -158,31 +158,34 @@ static void drw_hair_particle_cache_shgrp_attach_resources(DRWShadingGroup *shgr
   DRW_shgroup_uniform_int(shgrp, "hairStrandsRes", &cache->final[subdiv].strands_res, 1);
 }
 
+#if 0
 static void drw_hair_particle_cache_update_compute(ParticleHairCache *cache, const int subdiv)
 {
   const int final_points_len = cache->final[subdiv].strands_res * cache->strands_len;
   if (final_points_len > 0) {
     GPUShader *shader = hair_refine_shader_get(PART_REFINE_CATMULL_ROM);
     GPU_shader_bind(shader);
-    // GPU_texture_bind(cache->point_tex, GPU_shader_get_uniform(shader, "hairPointBuffer"));
-    // GPU_texture_bind(cache->strand_tex, GPU_shader_get_uniform(shader, "hairStrandBuffer"));
-    // GPU_texture_bind(cache->strand_seg_tex, GPU_shader_get_uniform(shader,
-    // "hairStrandSegBuffer")); GPU_shader_uniform_1i(shader, "hairStrandsRes",
-    // cache->final[subdiv].strands_res);
-    GPU_texture_image_bind(cache->final[subdiv].proc_tex,
-                           GPU_shader_get_uniform(shader, "hairPointOutputBuffer"));
-    GPU_compute_dispatch(shader, final_points_len, 1, 1);
-    GPU_memory_barrier(GPU_BARRIER_TEXTURE_FETCH);
-    float *data = GPU_texture_read(cache->final[subdiv].proc_tex, GPU_DATA_FLOAT, 0);
-    for (int index = 0; index < final_points_len; index++) {
-      printf("%f, %f, %f, %f\n",
-             data[index * 4],
-             data[index * 4 + 1],
-             data[index * 4 + 2],
-             data[index * 4 + 3]);
-    }
+    GPU_shader_attach_vertex_buffer(shader, cache->final[subdiv].proc_buf, 0);
+    GPU_texture_bind(cache->point_tex, GPU_shader_get_uniform(shader, "hairPointBuffer"));
+    GPU_texture_bind(cache->strand_tex, GPU_shader_get_uniform(shader, "hairStrandBuffer"));
+    GPU_texture_bind(cache->strand_seg_tex, GPU_shader_get_uniform(shader, "hairStrandSegBuffer"));
+    GPU_shader_uniform_1i(shader, "hairStrandsRes", cache->final[subdiv].strands_res);
+    GPU_compute_dispatch(shader, cache->strands_len, cache->final[subdiv].strands_res, 1);
+  }
+}
+#else
+static void drw_hair_particle_cache_update_compute(ParticleHairCache *cache, const int subdiv)
+{
+  const int final_points_len = cache->final[subdiv].strands_res * cache->strands_len;
+  if (final_points_len > 0) {
+    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, 0, cache->final[subdiv].proc_buf);
+    DRW_shgroup_call_compute(shgrp, cache->strands_len, cache->final[subdiv].strands_res, 1);
   }
 }
+#endif
 
 static void drw_hair_particle_cache_update_transform_feedback(ParticleHairCache *cache,
                                                               const int subdiv)
@@ -438,8 +441,7 @@ void DRW_hair_update(void)
   /* Just render the pass when using compute shaders or transform feedback. */
   DRW_draw_pass(g_tf_pass);
   if (drw_hair_use_compute_shaders()) {
-    GPU_memory_barrier(GPU_BARRIER_VERTEX_ATTRIB_ARRAY);
-    GPU_memory_barrier(GPU_BARRIER_TEXTURE_FETCH);
+    GPU_memory_barrier(GPU_BARRIER_SHADER_STORAGE);
   }
 #endif
   TIMEIT_END(DRW_hair_update);
diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h
index f2af1bcdcf2..89d6e5645da 100644
--- a/source/blender/draw/intern/draw_manager.h
+++ b/source/blender/draw/intern/draw_manager.h
@@ -297,6 +297,8 @@ typedef enum {
   DRW_UNIFORM_BLOCK,
   DRW_UNIFORM_BLOCK_REF,
   DRW_UNIFORM_TFEEDBACK_TARGET,
+  /* Not an actual uniform, but a buffer for compute shaders. */
+  DRW_VERTEX_BUFFER,
   /** Per drawcall uniforms/UBO */
   DRW_UNIFORM_BLOCK_OBMATS,
   DRW_UNIFORM_BLOCK_OBINFOS,
diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c
index d19c3bc7db1..7f26ef8d115 100644
--- a/source/blender/draw/intern/draw_manager_data.c
+++ b/source/blender/draw/intern/draw_manager_data.c
@@ -447,6 +447,13 @@ void DRW_shgroup_uniform_vec4_array_copy(DRWShadingGroup *shgroup,
   }
 }
 
+void DRW_shgroup_vertex_buffer(DRWShadingGroup *shgroup,
+                               const int location,
+                               GPUVertBuf *vertex_buffer)
+{
+  drw_shgroup_uniform_create_ex(shgroup, location, DRW_VERTEX_BUFFER, vertex_buffer, 0, 0, 1);
+}
+
 /** \} */
 
 /* -------------------------------------------------------------------- */
@@ -515,10 +522,10 @@ static void drw_call_obinfos_init(DRWObjectInfos *ob_infos, Object *ob)
   drw_call_calc_orco(ob, ob_infos->orcotexfac);
   /* Random float value. */
   uint random = (DST.dupli_source) ?
-                    DST.dupli_source->random_id :
-                    /* TODO(fclem): this is rather costly to do at runtime. Maybe we can
-                     * put it in ob->runtime and make depsgraph ensure it is up to date. */
-                    BLI_hash_int_2d(BLI_hash_string(ob->id.name + 2), 0);
+                     DST.dupli_source->random_id :
+                     /* TODO(fclem): this is rather costly to do at runtime. Maybe we can
+                      * put it in ob->runtime and make depsgraph ensure it is up to date. */
+                     BLI_hash_int_2d(BLI_hash_string(ob->id.name + 2), 0);
   ob_infos->ob_random = random * (1.0f / (float)0xFFFFFFFF);
   /* Object State. */
   ob_infos->ob_flag = 1.0f; /* Required to have a correct sign */
diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c
index e268b137152..1ec09bc1259 100644
--- a/source/blender/draw/intern/draw_manager_exec.c
+++ b/source/blender/draw/intern/draw_manager_exec.c
@@ -673,6 +673,10 @@ static void draw_update_uniforms(DRWShadingGroup *shgroup,
           *use_tfeedback = GPU_shader_transform_feedback_enable(shgroup->shader,
                                                                 ((GPUVertBuf *)uni->pvalue));
           break;
+        case DRW_VERTEX_BUFFER:
+          GPU_shader_attach_vertex_buffer(
+              shgroup->shader, (GPUVertBuf *)uni->pvalue, uni->location);
+          break;
           /* Legacy/Fallback support. */
         case DRW_UNIFORM_BASE_INSTANCE:
           state->baseinst_loc = uni->location;
diff --git a/source/blender/draw/intern/shaders/common_hair_refine_vert.glsl b/source/blender/draw/intern/shaders/common_hair_refine_vert.glsl
index 8b29b1a09b9..317a4abffa6 100644
--- a/source/blender/draw/intern/shaders/common_hair_refine_vert.glsl
+++ b/source/blender/draw/intern/shaders/common_hair_refine_vert.glsl
@@ -4,25 +4,27 @@
  * Shader can be used as a vertex or a compute shader.
  */
 
-#if 0
-#  ifdef GPU_VERTEX_SHADER
+#ifdef GPU_VERTEX_SHADER
 out vec4 finalColor;
-#  endif
+#endif
 
-#  ifdef GPU_COMPUTE_SHADER
+#ifdef GPU_COMPUTE_SHADER
 layout(local_size_x = 1, local_size_y = 1) in;
-layout(rgba32f, binding = 0) uniform image1D hairPointOutputBuffer;
-#  endif
+layout(std430, binding = 0) buffer hairPointOutputBuffer
+{
+  vec4 Positions[];
+};
+#endif
 
 vec4 get_weights_cardinal(float t)
 {
   float t2 = t * t;
   float t3 = t2 * t;
-#  if defined(CARDINAL)
+#if defined(CARDINAL)
   float fc = 0.71;
-#  else /* defined(CATMULL_ROM) */
+#else /* defined(CATMULL_ROM) */
   float fc = 0.5;
-#  endif
+#endif
 
   vec4 weights;
   /* GLSL Optimized version of key_curve_position_weights() */
@@ -55,11 +57,11 @@ vec4 interp_data(vec4 v0, vec4 v1, vec4 v2, vec4 v3, vec4 w)
   return v0 * w.x + v1 * w.y + v2 * w.z + v3 * w.w;
 }
 
-#  ifdef TF_WORKAROUND
+#ifdef TF_WORKAROUND
 uniform int targetWidth;
 uniform int targetHeight;
 uniform int idOffset;
-#  endif
+#endif
 
 void main(void)
 {
@@ -70,10 +72,10 @@ void main(void)
   vec4 weights = get_weights_cardinal(interp_time);
   vec4 result = interp_data(data0, data1, data2, data3, weights);
 
-#  ifdef GPU_VERTEX_SHADER
+#ifdef GPU_VERTEX_SHADER
   finalColor = result;
 
-#    ifdef TF_WORKAROUND
+#  ifdef TF_WORKAROUND
   int id = gl_VertexID - idOffset;
   gl_Position.x = ((float(id % targetWidth) + 0.5) / float(targetWidth)) * 2.0 - 1.0;
   gl_Position.y = ((float(id / targetWidth) + 0.5) / float(targetHeight)) * 2.0 - 1.0;
@@ -81,24 +83,11 @@ void main(void)
   gl_Position.w = 1.0;
 
   gl_PointSize = 1.0;
-#    endif
 #  endif
+#endif
 
-#  ifdef GPU_COMPUTE_SHADER
+#ifdef GPU_COMPUTE_SHADER
   int index = int(gl_GlobalInvocationID.x) * hairStrandsRes + int(gl_GlobalInvocationID.y);
-  imageStore(hairPointOutputBuffer, index, result);
-#  endif
+  Positions[index] = result;
+#endif
 }
-#else
-
-layout(local_size_x = 1, local_size_y = 1) i

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list