[Bf-blender-cvs] [2744ee22624] master: Metal: Enable object selection support

Jason Fielder noreply at git.blender.org
Thu Dec 8 21:58:33 CET 2022


Commit: 2744ee22624b9923ea1ea537410a0f3ea80c45c7
Author: Jason Fielder
Date:   Thu Dec 8 21:57:58 2022 +0100
Branches: master
https://developer.blender.org/rB2744ee22624b9923ea1ea537410a0f3ea80c45c7

Metal: Enable object selection support

Porting conservative depth rendering to use non-geometry shader path for
Metal.

Authored by Apple: Michael Parkin-White

Ref T96261

Reviewed By: fclem
Differential Revision: https://developer.blender.org/D16424

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

M	source/blender/draw/CMakeLists.txt
M	source/blender/draw/engines/basic/shaders/basic_depth_pointcloud_vert.glsl
A	source/blender/draw/engines/basic/shaders/basic_depth_vert_conservative_no_geom.glsl
M	source/blender/draw/engines/basic/shaders/infos/basic_depth_info.hh
M	source/blender/draw/intern/shaders/common_pointcloud_lib.glsl
M	source/blender/gpu/intern/gpu_shader_create_info.cc
M	source/blender/windowmanager/intern/wm_event_system.cc

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

diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index f38e61add02..e8a7167eda5 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -553,6 +553,7 @@ set(GLSL_SRC
 
   engines/basic/shaders/basic_conservative_depth_geom.glsl
   engines/basic/shaders/basic_depth_vert.glsl
+  engines/basic/shaders/basic_depth_vert_conservative_no_geom.glsl
   engines/basic/shaders/basic_depth_curves_vert.glsl
   engines/basic/shaders/basic_depth_pointcloud_vert.glsl
   engines/basic/shaders/basic_depth_frag.glsl
diff --git a/source/blender/draw/engines/basic/shaders/basic_depth_pointcloud_vert.glsl b/source/blender/draw/engines/basic/shaders/basic_depth_pointcloud_vert.glsl
index b82edc61cee..fbf8b5f449d 100644
--- a/source/blender/draw/engines/basic/shaders/basic_depth_pointcloud_vert.glsl
+++ b/source/blender/draw/engines/basic/shaders/basic_depth_pointcloud_vert.glsl
@@ -7,9 +7,19 @@ void main()
 {
   GPU_INTEL_VERTEX_SHADER_WORKAROUND
 
-  vec3 world_pos = pointcloud_get_pos();
+  vec3 world_pos, world_nor;
+  float world_radius;
+  pointcloud_get_pos_nor_radius(world_pos, world_nor, world_radius);
 
   gl_Position = point_world_to_ndc(world_pos);
 
+#ifdef CONSERVATIVE_RASTER
+  /* Avoid expense of geometry shader by ensuring rastered pointcloud primitive
+   * covers at least a whole pixel. */
+  int i = gl_VertexID % 3;
+  vec2 ofs = (i == 0) ? vec2(-1.0) : ((i == 1) ? vec2(2.0, -1.0) : vec2(-1.0, 2.0));
+  gl_Position.xy += sizeViewportInv * gl_Position.w * ofs;
+#endif
+
   view_clipping_distances(world_pos);
 }
diff --git a/source/blender/draw/engines/basic/shaders/basic_depth_vert_conservative_no_geom.glsl b/source/blender/draw/engines/basic/shaders/basic_depth_vert_conservative_no_geom.glsl
new file mode 100644
index 00000000000..b90262d0ac5
--- /dev/null
+++ b/source/blender/draw/engines/basic/shaders/basic_depth_vert_conservative_no_geom.glsl
@@ -0,0 +1,75 @@
+
+#pragma USE_SSBO_VERTEX_FETCH(TriangleList, 3)
+
+#pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
+void main()
+{
+  /* Calculate triangle vertex info. */
+  int output_triangle_id = gl_VertexID / 3;
+  int output_triangle_vertex_id = gl_VertexID % 3;
+  int base_vertex_id = 0;
+
+  if (vertex_fetch_get_input_prim_type() == GPU_PRIM_TRIS) {
+    base_vertex_id = output_triangle_id * 3;
+  }
+  else if (vertex_fetch_get_input_prim_type() == GPU_PRIM_TRI_STRIP) {
+    base_vertex_id = output_triangle_id;
+  }
+  /* NOTE: Triangle fan unsupported in Metal. Will be conveted upfront. */
+
+  /** Perform vertex shader calculations per input vertex. **/
+  /* input pos vertex attribute. */
+  vec3 in_pos[3];
+  /* Calculated per-vertex world pos. */
+  vec3 world_pos[3];
+  /* Output gl_Position per vertex. */
+  vec3 ndc_pos[3];
+  /* Geometry shader normalized position. */
+  vec3 pos[3];
+
+  for (int i = 0; i < 3; i++) {
+    in_pos[0] = vertex_fetch_attribute(base_vertex_id + i, pos, vec3);
+    world_pos[0] = point_object_to_world(in_pos[i]);
+    ndc_pos[i] = point_world_to_ndc(world_pos[i]);
+    pos[i] = ndc_pos[i].xyz / ndc_pos[i].w;
+  }
+
+  /** Geometry Shader equivalent calculation
+   * In this no_geom mode using SSBO vertex fetch, rather than emitting 3 vertices, the vertex
+   * shader is invocated 3 times, and output is determined based on vertex ID within a triangle
+   * 0..2. **/
+  vec3 plane = normalize(cross(pos[1] - pos[0], pos[2] - pos[0]));
+  /* Compute NDC bound box. */
+  vec4 bbox = vec4(min(min(pos[0].xy, pos[1].xy), pos[2].xy),
+                   max(max(pos[0].xy, pos[1].xy), pos[2].xy));
+  /* Convert to pixel space. */
+  bbox = (bbox * 0.5 + 0.5) * sizeViewport.xyxy;
+  /* Detect failure cases where triangles would produce no fragments. */
+  bvec2 is_subpixel = lessThan(bbox.zw - bbox.xy, vec2(1.0));
+  /* View aligned triangle. */
+  const float threshold = 0.00001;
+  bool is_coplanar = abs(plane.z) < threshold;
+
+  /* Determine output position per-vertex in each triangle */
+  gl_Position = ndc_pos[output_triangle_vertex_id];
+  if (all(is_subpixel)) {
+    vec2 ofs = (i == 0) ? vec2(-1.0) : ((i == 1) ? vec2(2.0, -1.0) : vec2(-1.0, 2.0));
+    /* HACK: Fix cases where the triangle is too small make it cover at least one pixel. */
+    gl_Position.xy += sizeViewportInv * gl_Position.w * ofs;
+  }
+  /* Test if the triangle is almost parallel with the view to avoid precision issues. */
+  else if (any(is_subpixel) || is_coplanar) {
+    /* HACK: Fix cases where the triangle is Parallel to the view by deforming it slightly. */
+    vec2 ofs = (i == 0) ? vec2(-1.0) : ((i == 1) ? vec2(1.0, -1.0) : vec2(1.0));
+    gl_Position.xy += sizeViewportInv * gl_Position.w * ofs;
+  }
+  else {
+    /* Triangle expansion should happen here, but we decide to not implement it for
+     * depth precision & performance reasons. */
+  }
+
+  /* Assign vertex shader clipping distances. */
+  view_clipping_distances(world_pos[output_triangle_vertex_id]);
+}
diff --git a/source/blender/draw/engines/basic/shaders/infos/basic_depth_info.hh b/source/blender/draw/engines/basic/shaders/infos/basic_depth_info.hh
index e275d208c7a..64988274e03 100644
--- a/source/blender/draw/engines/basic/shaders/infos/basic_depth_info.hh
+++ b/source/blender/draw/engines/basic/shaders/infos/basic_depth_info.hh
@@ -30,6 +30,18 @@ GPU_SHADER_CREATE_INFO(basic_pointcloud)
 GPU_SHADER_CREATE_INFO(basic_curves)
     .vertex_source("basic_depth_curves_vert.glsl")
     .additional_info("draw_hair");
+
+/* Geometry-shader alterantive paths. */
+GPU_SHADER_CREATE_INFO(basic_mesh_conservative_no_geom)
+    .vertex_in(0, Type::VEC3, "pos")
+    .vertex_source("basic_depth_vert_conservative_no_geom.glsl")
+    .additional_info("draw_mesh");
+
+GPU_SHADER_CREATE_INFO(basic_pointcloud_conservative_no_geom)
+    .define("CONSERVATIVE_RASTER")
+    .vertex_source("basic_depth_pointcloud_vert.glsl")
+    .additional_info("draw_pointcloud");
+
 /** \} */
 
 /* -------------------------------------------------------------------- */
@@ -45,6 +57,7 @@ GPU_SHADER_CREATE_INFO(basic_curves)
 
 #define BASIC_CONSERVATIVE_VARIATIONS(prefix, ...) \
   BASIC_CLIPPING_VARIATIONS(prefix##_conservative, "basic_conservative", __VA_ARGS__) \
+  BASIC_CLIPPING_VARIATIONS(prefix##_conservative_no_geom, __VA_ARGS__) \
   BASIC_CLIPPING_VARIATIONS(prefix, __VA_ARGS__)
 
 #define BASIC_OBTYPE_VARIATIONS(prefix, ...) \
diff --git a/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl b/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl
index d8733ea8598..018e62b8c65 100644
--- a/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl
+++ b/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl
@@ -45,7 +45,7 @@ void pointcloud_get_pos_and_radius(out vec3 outpos, out float outradius)
 }
 
 /* Return world position and normal. */
-void pointcloud_get_pos_and_nor(out vec3 outpos, out vec3 outnor)
+void pointcloud_get_pos_nor_radius(out vec3 outpos, out vec3 outnor, out float outradius)
 {
   vec3 p;
   float radius;
@@ -79,6 +79,17 @@ void pointcloud_get_pos_and_nor(out vec3 outpos, out vec3 outnor)
   radius *= 0.01;
   outnor = facing_mat * pos_inst;
   outpos = p + outnor * radius;
+  outradius = radius;
+}
+
+/* Return world position and normal. */
+void pointcloud_get_pos_and_nor(out vec3 outpos, out vec3 outnor)
+{
+  vec3 nor, pos;
+  float radius;
+  pointcloud_get_pos_nor_radius(pos, nor, radius);
+  outpos = pos;
+  outnor = nor;
 }
 
 vec3 pointcloud_get_pos()
diff --git a/source/blender/gpu/intern/gpu_shader_create_info.cc b/source/blender/gpu/intern/gpu_shader_create_info.cc
index dd28a7ab45b..eca28abd876 100644
--- a/source/blender/gpu/intern/gpu_shader_create_info.cc
+++ b/source/blender/gpu/intern/gpu_shader_create_info.cc
@@ -343,6 +343,13 @@ void gpu_shader_create_info_init()
     overlay_motion_path_line = overlay_motion_path_line_no_geom;
     overlay_motion_path_line_clipped = overlay_motion_path_line_clipped_no_geom;
 
+    /* Conservative rasterization. */
+    basic_depth_mesh_conservative = basic_depth_mesh_conservative_no_geom;
+    basic_depth_mesh_conservative_clipped = basic_depth_mesh_conservative_no_geom_clipped;
+    basic_depth_pointcloud_conservative = basic_depth_pointcloud_conservative_no_geom;
+    basic_depth_pointcloud_conservative_clipped =
+        basic_depth_pointcloud_conservative_no_geom_clipped;
+
     /* Overlay prepass wire. */
     overlay_outline_prepass_wire = overlay_outline_prepass_wire_no_geom;
 
diff --git a/source/blender/windowmanager/intern/wm_event_system.cc b/source/blender/windowmanager/intern/wm_event_system.cc
index f4cd3959475..3b603b6a3c0 100644
--- a/source/blender/windowmanager/intern/wm_event_system.cc
+++ b/source/blender/windowmanager/intern/wm_event_system.cc
@@ -3823,6 +3823,9 @@ void wm_event_do_handlers(bContext *C)
   wmWindowManager *wm = CTX_wm_manager(C);
   BLI_assert(ED_undo_is_state_valid(C));
 
+  /* Begin GPU render boundary - Certain event handlers require GPU usage. */
+  GPU_render_begin();
+
   /* Update key configuration before handling events. */
   WM_keyconfig_update(wm);
   WM_gizmoconfig_update(CTX_data_main(C));
@@ -3962,6 +3965,7 @@ void wm_event_do_handlers(bContext *C)
       /* File-read case. */
       if (CTX_wm_window(C) == nullptr) {
         wm_event_free_and_remove_from_queue_if_valid(event);
+        GPU_render_end();
         return;
       }
 
@@ -4016,6 +4020,7 @@ void wm_event_do_handlers(bContext *C)
             /* File-read case (Python), T29489. */
             if (CTX_wm_window(C) == nullptr) {
               wm_event_free_and_remove_from_queue_if_valid(event);
+              GPU_render_end();
               return;
             }
 
@@ -4044,6 +4049,7 @@ void wm_event_do_handlers(bContext *C)
           /* File-read case. */
           if (CTX_wm_window(C) == nullptr) {
             wm_event_free_and_remove_from_queue_if_valid(event);
+            GPU_render_end();
             return;
           }
         }
@@ -4094,6 +4100,9 @@ void wm_event_do_handlers(bContext *C)
   /* Update key configuration after handling events. */
   WM_keyconfig_update(wm);
   WM_gizmoconfi

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list