[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