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. @@ _______________________________________________ Bf-blender-cvs mailing list [email protected] List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
