[Bf-blender-cvs] [2712265598a] master: Metal: Addressing a number of small outstanding issues across Metal backend.

Jason Fielder noreply at git.blender.org
Tue Dec 20 14:06:33 CET 2022


Commit: 2712265598a09c3868b9d097488f22d42efbf6eb
Author: Jason Fielder
Date:   Tue Dec 20 14:03:22 2022 +0100
Branches: master
https://developer.blender.org/rB2712265598a09c3868b9d097488f22d42efbf6eb

Metal: Addressing a number of small outstanding issues across Metal backend.

 - Support for non-contiguous shader resource bindings for all cases required by create-info
 - Implement missing geometry shader alternative path for edit curve handle.
 - Add support for non-float dummy textures to address all cases where default bindings may be required.

Authored by Apple: Michael Parkin-White
Ref T96261
Depends on D16721

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

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

M	source/blender/draw/engines/overlay/shaders/infos/overlay_edit_mode_info.hh
M	source/blender/draw/engines/overlay/shaders/overlay_edit_curve_handle_vert_no_geom.glsl
M	source/blender/gpu/intern/gpu_shader_create_info.cc
M	source/blender/gpu/intern/gpu_texture_private.hh
M	source/blender/gpu/metal/mtl_batch.mm
M	source/blender/gpu/metal/mtl_context.hh
M	source/blender/gpu/metal/mtl_context.mm
M	source/blender/gpu/metal/mtl_drawlist.mm
M	source/blender/gpu/metal/mtl_framebuffer.mm
M	source/blender/gpu/metal/mtl_immediate.mm
M	source/blender/gpu/metal/mtl_pso_descriptor_state.hh
M	source/blender/gpu/metal/mtl_shader.mm
M	source/blender/gpu/metal/mtl_shader_generator.hh
M	source/blender/gpu/metal/mtl_shader_generator.mm
M	source/blender/gpu/metal/mtl_shader_interface.hh
M	source/blender/gpu/metal/mtl_shader_interface.mm
M	source/blender/gpu/metal/mtl_shader_interface_type.hh
M	source/blender/gpu/metal/mtl_texture.mm
M	source/blender/gpu/metal/mtl_vertex_buffer.hh
M	source/blender/imbuf/intern/util_gpu.c

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

diff --git a/source/blender/draw/engines/overlay/shaders/infos/overlay_edit_mode_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_edit_mode_info.hh
index 3e0492d024c..b1c28bcb3e3 100644
--- a/source/blender/draw/engines/overlay/shaders/infos/overlay_edit_mode_info.hh
+++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_edit_mode_info.hh
@@ -397,8 +397,8 @@ GPU_SHADER_CREATE_INFO(overlay_edit_curve_handle_no_geom)
     /* NOTE: Color already in Linear space. Which is what we want. */
     .define("srgbTarget", "false")
     .vertex_in(0, Type::VEC3, "pos")
-    .vertex_in(1, Type::UINT, "data")
-    .vertex_out(overlay_edit_curve_handle_iface)
+    .vertex_in(1, Type::UCHAR, "data")
+    .vertex_out(overlay_edit_smooth_color_iface)
     .push_constant(Type::BOOL, "showCurveHandles")
     .push_constant(Type::INT, "curveHandleDisplay")
     .fragment_out(0, Type::VEC4, "fragColor")
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_edit_curve_handle_vert_no_geom.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_curve_handle_vert_no_geom.glsl
index 8b4b7afb996..518b98e4ce5 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_edit_curve_handle_vert_no_geom.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_curve_handle_vert_no_geom.glsl
@@ -1,16 +1,166 @@
-/* TODO(Metal): Implement correct SSBO implementation for geom shader workaround.
- * Currently included as placeholder to unblock failing compilation in Metal. */
 
 #pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl)
 #pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma USE_SSBO_VERTEX_FETCH(TriangleStrip, 10)
+
+#define DISCARD_VERTEX \
+  gl_Position = vec4(0.0); \
+  finalColor = vec4(0.0); \
+  return;
+
+void output_line(vec2 offset, vec4 color, vec3 out_world_pos, vec4 out_ndc_pos)
+{
+  finalColor = color;
+  gl_Position = out_ndc_pos;
+  gl_Position.xy += offset * out_ndc_pos.w;
+  view_clipping_distances(out_world_pos);
+}
 
 void main()
 {
   GPU_INTEL_VERTEX_SHADER_WORKAROUND
 
-  vec3 world_pos = point_object_to_world(pos);
-  gl_Position = point_world_to_ndc(world_pos);
-  vert.flag = data;
+  /* Perform vertex shader for each input primitive. */
+  vec3 in_pos[2];
+  vec3 world_pos[2];
+  vec4 ndc_pos[2];
+  uint vert_flag[2];
+
+  /* Input prim is LineList. */
+  /* Index of the input line primitive. */
+  int input_line_id = gl_VertexID / 10;
+  /* Index of output vertex set. Grouped into pairs as outputted by original "output_line" function
+   * in overlay_edit_curve_handle_geom.glsl. */
+  int output_prim_id = (gl_VertexID / 2) % 5;
+  /* ID of vertex within line primitive (0 or 1) for current vertex. */
+  int output_prim_vert_id = gl_VertexID % 2;
+
+  for (int i = 0; i < 2; i++) {
+    in_pos[i] = vertex_fetch_attribute((input_line_id * 2) + i, pos, vec3).xyz;
+    vert_flag[i] = (uint)vertex_fetch_attribute((input_line_id * 2) + i, data, uchar);
+    world_pos[i] = point_object_to_world(in_pos[i]);
+    ndc_pos[i] = point_world_to_ndc(world_pos[i]);
+  }
+
+  /* Perform Geometry shader equivalent calculation. */
+  uint is_active_nurb = (vert_flag[1] & ACTIVE_NURB);
+  uint color_id = (vert_flag[1] >> COLOR_SHIFT);
+
+  /* Don't output any edges if we don't show handles */
+  if (!showCurveHandles && (color_id < 5)) {
+    return;
+  }
+
+  bool edge_selected = (((vert_flag[1] | vert_flag[0]) & VERT_SELECTED) != 0u);
+  bool handle_selected = (showCurveHandles &&
+                          (((vert_flag[1] | vert_flag[0]) & VERT_SELECTED_BEZT_HANDLE) != 0u));
+
+  bool is_gpencil = ((vert_flag[1] & VERT_GPENCIL_BEZT_HANDLE) != 0u);
+
+  /* If handle type is only selected and the edge is not selected, don't show. */
+  if ((curveHandleDisplay != CURVE_HANDLE_ALL) && (!handle_selected)) {
+    /* Nurbs must show the handles always. */
+    bool is_u_segment = (((vert_flag[1] ^ vert_flag[0]) & EVEN_U_BIT) != 0u);
+    if ((!is_u_segment) && (color_id <= 4)) {
+      return;
+    }
+    if (is_gpencil) {
+      return;
+    }
+  }
+
+  vec4 inner_color;
+  if (color_id == 0) {
+    inner_color = (edge_selected) ? colorHandleSelFree : colorHandleFree;
+  }
+  else if (color_id == 1) {
+    inner_color = (edge_selected) ? colorHandleSelAuto : colorHandleAuto;
+  }
+  else if (color_id == 2) {
+    inner_color = (edge_selected) ? colorHandleSelVect : colorHandleVect;
+  }
+  else if (color_id == 3) {
+    inner_color = (edge_selected) ? colorHandleSelAlign : colorHandleAlign;
+  }
+  else if (color_id == 4) {
+    inner_color = (edge_selected) ? colorHandleSelAutoclamp : colorHandleAutoclamp;
+  }
+  else {
+    bool is_selected = (((vert_flag[1] & vert_flag[0]) & VERT_SELECTED) != 0);
+    bool is_u_segment = (((vert_flag[1] ^ vert_flag[0]) & EVEN_U_BIT) != 0);
+    if (is_u_segment) {
+      inner_color = (is_selected) ? colorNurbSelUline : colorNurbUline;
+    }
+    else {
+      inner_color = (is_selected) ? colorNurbSelVline : colorNurbVline;
+    }
+  }
+
+  vec4 outer_color = (is_active_nurb != 0) ?
+                         mix(colorActiveSpline,
+                             inner_color,
+                             0.25) /* Minimize active color bleeding on inner_color. */
+                         :
+                         vec4(inner_color.rgb, 0.0);
+
+  vec2 v1_2 = (ndc_pos[1].xy / ndc_pos[1].w - ndc_pos[0].xy / ndc_pos[0].w);
+  vec2 offset = sizeEdge * 4.0 * sizeViewportInv; /* 4.0 is eyeballed */
+
+  if (abs(v1_2.x * sizeViewport.x) < abs(v1_2.y * sizeViewport.y)) {
+    offset.y = 0.0;
+  }
+  else {
+    offset.x = 0.0;
+  }
+
+  /* Output geometry based on output line ID. */
+  switch (output_prim_id) {
+    case 0: {
+      /* draw the transparent border (AA). */
+      if (is_active_nurb != 0u) {
+        offset *= 0.75; /* Don't make the active "halo" appear very thick. */
+        output_line(offset * 2.0,
+                    vec4(colorActiveSpline.rgb, 0.0),
+                    world_pos[output_prim_vert_id],
+                    ndc_pos[output_prim_vert_id]);
+      }
+      else {
+        DISCARD_VERTEX
+      }
+      break;
+    }
+    case 1: {
+      /* draw the outline. */
+      output_line(
+          offset, outer_color, world_pos[output_prim_vert_id], ndc_pos[output_prim_vert_id]);
+      break;
+    }
+    case 2: {
+      /* draw the core of the line. */
+      output_line(
+          vec2(0.0), inner_color, world_pos[output_prim_vert_id], ndc_pos[output_prim_vert_id]);
+      break;
+    }
+    case 3: {
+      /* draw the outline. */
+      output_line(
+          -offset, outer_color, world_pos[output_prim_vert_id], ndc_pos[output_prim_vert_id]);
+      break;
+    }
+    case 4: {
+      /* draw the transparent border (AA). */
+      if (is_active_nurb != 0u) {
+        output_line(offset * -2.0,
+                    vec4(colorActiveSpline.rgb, 0.0),
+                    world_pos[output_prim_vert_id],
+                    ndc_pos[output_prim_vert_id]);
+      }
+      break;
+    }
 
-  view_clipping_distances(world_pos);
+    default: {
+      DISCARD_VERTEX
+      break;
+    }
+  }
 }
diff --git a/source/blender/gpu/intern/gpu_shader_create_info.cc b/source/blender/gpu/intern/gpu_shader_create_info.cc
index bc3f462e9f9..0e3057ee8c1 100644
--- a/source/blender/gpu/intern/gpu_shader_create_info.cc
+++ b/source/blender/gpu/intern/gpu_shader_create_info.cc
@@ -334,6 +334,8 @@ void gpu_shader_create_info_init()
     overlay_edit_mesh_edge_flat = overlay_edit_mesh_edge_flat_no_geom;
     overlay_edit_mesh_edge_clipped = overlay_edit_mesh_edge_clipped_no_geom;
     overlay_edit_mesh_edge_flat_clipped = overlay_edit_mesh_edge_flat_clipped_no_geom;
+    overlay_edit_curve_handle = overlay_edit_curve_handle_no_geom;
+    overlay_edit_curve_handle_clipped = overlay_edit_curve_handle_clipped_no_geom;
 
     /* Overlay Armature Shape outline. */
     overlay_armature_shape_outline = overlay_armature_shape_outline_no_geom;
diff --git a/source/blender/gpu/intern/gpu_texture_private.hh b/source/blender/gpu/intern/gpu_texture_private.hh
index 115e38443b5..fc5e39a3534 100644
--- a/source/blender/gpu/intern/gpu_texture_private.hh
+++ b/source/blender/gpu/intern/gpu_texture_private.hh
@@ -43,6 +43,19 @@ typedef enum eGPUTextureType {
 
 ENUM_OPERATORS(eGPUTextureType, GPU_TEXTURE_CUBE_ARRAY)
 
+/* Format types for samplers within the shader.
+ * This covers the sampler format type permutations within GLSL/MSL.*/
+typedef enum eGPUSamplerFormat {
+  GPU_SAMPLER_TYPE_FLOAT = 0,
+  GPU_SAMPLER_TYPE_INT = 1,
+  GPU_SAMPLER_TYPE_UINT = 2,
+  /* Special case for depth, as these require differing dummy formats. */
+  GPU_SAMPLER_TYPE_DEPTH = 3,
+  GPU_SAMPLER_TYPE_MAX = 4
+} eGPUSamplerFormat;
+
+ENUM_OPERATORS(eGPUSamplerFormat, GPU_SAMPLER_TYPE_UINT)
+
 #ifdef DEBUG
 #  define DEBUG_NAME_LEN 64
 #else
diff --git a/source/blender/gpu/metal/mtl_batch.mm b/source/blender/gpu/metal/mtl_batch.mm
index 768278ec0c6..13496e8ad6f 100644
--- a/source/blender/gpu/metal/mtl_batch.mm
+++ b/source/blender/gpu/metal/mtl_batch.mm
@@ -154,11 +154,13 @@ int MTLBatch::prepare_vertex_binding(MTLVertBuf *verts,
         continue;
       }
 
-      /* Fetch metal attribute information. */
-      const MTLShaderInputAttribute &mtl_attr = interface->get_attribute(input->location);
+      /* Fetch metal attribute information (ShaderInput->binding is used to fetch the corresponding
+       * slot. */
+      const MTLShaderInputAttribute &mtl_attr = interface->get_attribute(input->binding);
       BLI_assert(mtl_attr.location >= 0);
       /* Verify that the attribute location from the shader interface
-       * matches the attribute location returned. */
+       * matches the attribute location returned in the input table. These should always be the
+       * same. */
       BLI_assert(mtl_attr.location == input->location);
 
       /* Check if attribute is already present in the given slot. */
@@ -247,12 +249,16 @@ int MTLBatch::prepare_vertex_binding(MTLVertBuf *verts,
                     buffer_index;
 
                 /* Update total attribute account. */
-                desc.vertex_descriptor.num_attributes = max_ii(
-                    mtl_attr.location + i + 1, desc.vertex_des

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list