Metal: Overlay UV Edge support.

Implemented geometry shader alternative for rendering of UV edges in Metal, as geometry shaders are unsupported.

Authored by Apple: Michael Parkin-White

Ref T96261

Reviewed By: fclem
Differential Revision: https://developer.blender.org/D16452
This commit is contained in:
Jason Fielder 2022-12-08 22:22:50 +01:00 committed by Clément Foucault
parent 18a91ecee7
commit a83f2834c7
Notes: blender-bot 2023-02-14 04:07:50 +01:00
Referenced by issue #96261, Metal Viewport
5 changed files with 60 additions and 23 deletions

View File

@ -22,7 +22,9 @@ GPU_SHADER_CREATE_INFO(overlay_edit_mesh_common)
.vertex_source("overlay_edit_mesh_vert.glsl")
.additional_info("draw_modelmat", "draw_globals");
#ifdef WITH_METAL_BACKEND
GPU_SHADER_CREATE_INFO(overlay_edit_mesh_common_no_geom)
.metal_backend_only(true)
.define("blender_srgb_to_framebuffer_space(a)", "a")
.sampler(0, ImageType::DEPTH_2D, "depthTex")
.fragment_out(0, Type::VEC4, "fragColor")
@ -32,6 +34,7 @@ GPU_SHADER_CREATE_INFO(overlay_edit_mesh_common_no_geom)
.push_constant(Type::IVEC4, "dataMask")
.vertex_source("overlay_edit_mesh_vert_no_geom.glsl")
.additional_info("draw_modelmat", "draw_globals");
#endif
GPU_SHADER_INTERFACE_INFO(overlay_edit_mesh_vert_iface, "")
.smooth(Type::VEC4, "finalColor")
@ -73,8 +76,10 @@ GPU_SHADER_CREATE_INFO(overlay_edit_mesh_edge)
.additional_info("overlay_edit_mesh_common");
/* The Non-Geometry shader variant passes directly to fragment. */
#ifdef WITH_METAL_BACKEND
GPU_SHADER_CREATE_INFO(overlay_edit_mesh_edge_no_geom)
// .do_static_compilation(true) /* TODO fix on GL */
.metal_backend_only(true)
.do_static_compilation(true)
.define("EDGE")
.vertex_in(0, Type::VEC3, "pos")
.vertex_in(1, Type::UCHAR4, "data")
@ -83,16 +88,20 @@ GPU_SHADER_CREATE_INFO(overlay_edit_mesh_edge_no_geom)
.vertex_out(overlay_edit_mesh_edge_geom_iface)
.fragment_source("overlay_edit_mesh_frag.glsl")
.additional_info("overlay_edit_mesh_common_no_geom");
#endif
GPU_SHADER_CREATE_INFO(overlay_edit_mesh_edge_flat)
.do_static_compilation(true)
.define("FLAT")
.additional_info("overlay_edit_mesh_edge");
#ifdef WITH_METAL_BACKEND
GPU_SHADER_CREATE_INFO(overlay_edit_mesh_edge_flat_no_geom)
// .do_static_compilation(true) /* TODO fix on GL */
.metal_backend_only(true)
.do_static_compilation(true)
.define("FLAT")
.additional_info("overlay_edit_mesh_edge_no_geom");
#endif
GPU_SHADER_CREATE_INFO(overlay_edit_mesh_face)
.do_static_compilation(true)
@ -164,17 +173,23 @@ GPU_SHADER_CREATE_INFO(overlay_edit_mesh_edge_clipped)
.do_static_compilation(true)
.additional_info("overlay_edit_mesh_edge", "drw_clipped");
#ifdef WITH_METAL_BACKEND
GPU_SHADER_CREATE_INFO(overlay_edit_mesh_edge_clipped_no_geom)
// .do_static_compilation(true) /* TODO fix on GL */
.metal_backend_only(true)
.do_static_compilation(true)
.additional_info("overlay_edit_mesh_edge_no_geom", "drw_clipped");
#endif
GPU_SHADER_CREATE_INFO(overlay_edit_mesh_edge_flat_clipped)
.do_static_compilation(true)
.additional_info("overlay_edit_mesh_edge_flat", "drw_clipped");
#ifdef WITH_METAL_BACKEND
GPU_SHADER_CREATE_INFO(overlay_edit_mesh_edge_flat_clipped_no_geom)
// .do_static_compilation(true) /* TODO fix on GL */
.metal_backend_only(true)
.do_static_compilation(true)
.additional_info("overlay_edit_mesh_edge_flat_no_geom", "drw_clipped");
#endif
GPU_SHADER_CREATE_INFO(overlay_edit_mesh_face_clipped)
.do_static_compilation(true)
@ -215,7 +230,7 @@ GPU_SHADER_INTERFACE_INFO(overlay_edit_uv_geom_iface, "geom_out")
GPU_SHADER_CREATE_INFO(overlay_edit_uv_edges_common)
.vertex_in(0, Type::VEC2, "au")
.vertex_in(1, Type::UINT, "flag")
.vertex_in(1, Type::INT, "flag")
.push_constant(Type::INT, "lineStyle")
.push_constant(Type::BOOL, "doSmoothWire")
.push_constant(Type::FLOAT, "alpha")
@ -233,11 +248,14 @@ GPU_SHADER_CREATE_INFO(overlay_edit_uv_edges)
.vertex_source("overlay_edit_uv_edges_vert.glsl")
.geometry_source("overlay_edit_uv_edges_geom.glsl");
#ifdef WITH_METAL_BACKEND
GPU_SHADER_CREATE_INFO(overlay_edit_uv_edges_no_geom)
.metal_backend_only(true)
.additional_info("overlay_edit_uv_edges_common")
// .do_static_compilation(true)
.do_static_compilation(true)
.vertex_out(overlay_edit_uv_geom_iface)
.vertex_source("overlay_edit_uv_edges_vert_no_geom.glsl");
#endif
GPU_SHADER_CREATE_INFO(overlay_edit_uv_edges_select)
.do_static_compilation(true)
@ -371,8 +389,10 @@ GPU_SHADER_CREATE_INFO(overlay_edit_curve_handle)
.fragment_source("overlay_varying_color.glsl")
.additional_info("draw_mesh", "draw_globals");
#ifdef WITH_METAL_BACKEND
GPU_SHADER_CREATE_INFO(overlay_edit_curve_handle_no_geom)
// .do_static_compilation(true) /* TODO fix on GL */
.metal_backend_only(true)
.do_static_compilation(true)
.typedef_source("overlay_shader_shared.h")
/* NOTE: Color already in Linear space. Which is what we want. */
.define("srgbTarget", "false")
@ -385,14 +405,18 @@ GPU_SHADER_CREATE_INFO(overlay_edit_curve_handle_no_geom)
.vertex_source("overlay_edit_curve_handle_vert_no_geom.glsl")
.fragment_source("overlay_varying_color.glsl")
.additional_info("draw_mesh", "draw_globals");
#endif
GPU_SHADER_CREATE_INFO(overlay_edit_curve_handle_clipped)
.do_static_compilation(true)
.additional_info("overlay_edit_curve_handle", "drw_clipped");
#ifdef WITH_METAL_BACKEND
GPU_SHADER_CREATE_INFO(overlay_edit_curve_handle_clipped_no_geom)
// .do_static_compilation(true) /* TODO fix on GL */
.metal_backend_only(true)
.do_static_compilation(true)
.additional_info("overlay_edit_curve_handle_no_geom", "drw_clipped");
#endif
GPU_SHADER_CREATE_INFO(overlay_edit_curve_point)
.do_static_compilation(true)

View File

@ -45,14 +45,14 @@ void main()
/* Vertex shader per input vertex. */
vec3 world_pos0 = point_object_to_world(vec3(root_au0, 0.0));
vec3 world_pos1 = point_object_to_world(vec3(root_au1, 0.0));
vec4 gl_pos0 = point_world_to_ndc(world_pos0);
vec4 gl_pos1 = point_world_to_ndc(world_pos1);
vec4 ndc_pos0 = point_world_to_ndc(world_pos0);
vec4 ndc_pos1 = point_world_to_ndc(world_pos1);
/* Snap vertices to the pixel grid to reduce artifacts. */
vec2 half_viewport_res = sizeViewport * 0.5;
vec2 half_pixel_offset = sizeViewportInv * 0.5;
gl_pos0.xy = floor(gl_pos0.xy * half_viewport_res) / half_viewport_res + half_pixel_offset;
gl_pos1.xy = floor(gl_pos1.xy * half_viewport_res) / half_viewport_res + half_pixel_offset;
ndc_pos0.xy = floor(ndc_pos0.xy * half_viewport_res) / half_viewport_res + half_pixel_offset;
ndc_pos1.xy = floor(ndc_pos1.xy * half_viewport_res) / half_viewport_res + half_pixel_offset;
#ifdef USE_EDGE_SELECT
bool is_select0 = (root_flag0 & EDGE_UV_SELECT) != 0;
@ -74,19 +74,19 @@ void main()
* actual pixels are at 0.75, 1.0 is used for the background. */
float depth0 = is_select0 ? 0.25 : 0.35;
float depth1 = is_select1 ? 0.25 : 0.35;
gl_pos0.z = depth0;
gl_pos1.z = depth1;
ndc_pos0.z = depth0;
ndc_pos1.z = depth1;
/* Avoid precision loss. */
vec2 stipplePos0 = 500.0 + 500.0 * (gl_pos0.xy / gl_pos0.w);
vec2 stipplePos1 = 500.0 + 500.0 * (gl_pos1.xy / gl_pos1.w);
vec2 stipplePos0 = 500.0 + 500.0 * (ndc_pos0.xy / ndc_pos0.w);
vec2 stipplePos1 = 500.0 + 500.0 * (ndc_pos1.xy / ndc_pos1.w);
vec2 stippleStart0 = stipplePos0;
vec2 stippleStart1 = stipplePos1;
/* Geometry shader equivalent calculations. */
vec2 ss_pos[2];
ss_pos[0] = gl_pos0.xy / gl_pos0.w;
ss_pos[1] = gl_pos1.xy / gl_pos1.w;
ss_pos[0] = ndc_pos0.xy / ndc_pos0.w;
ss_pos[1] = ndc_pos1.xy / ndc_pos1.w;
float half_size = sizeEdge;
@ -108,19 +108,19 @@ void main()
switch (quad_vertex_id) {
case 1: /* vertex A */
case 3:
do_vertex(gl_pos1, selectionFac1, stippleStart1, stipplePos1, half_size, edge_ofs.xy);
do_vertex(ndc_pos1, selectionFac1, stippleStart1, stipplePos1, half_size, edge_ofs.xy);
break;
case 0: /* B */
do_vertex(gl_pos0, selectionFac0, stippleStart0, stipplePos0, half_size, edge_ofs.xy);
do_vertex(ndc_pos0, selectionFac0, stippleStart0, stipplePos0, half_size, edge_ofs.xy);
break;
case 2: /* C */
case 4:
do_vertex(gl_pos0, selectionFac0, stippleStart0, stipplePos0, -half_size, -edge_ofs.xy);
do_vertex(ndc_pos0, selectionFac0, stippleStart0, stipplePos0, -half_size, -edge_ofs.xy);
break;
case 5: /* D */
do_vertex(gl_pos1, selectionFac1, stippleStart1, stipplePos1, -half_size, -edge_ofs.xy);
do_vertex(ndc_pos1, selectionFac1, stippleStart1, stipplePos1, -half_size, -edge_ofs.xy);
break;
}
}

View File

@ -416,7 +416,8 @@ bool gpu_shader_create_info_compile_all()
for (ShaderCreateInfo *info : g_create_infos->values()) {
info->finalize();
if (info->do_static_compilation_) {
if ((GPU_compute_shader_support() == false && info->compute_source_ != nullptr) ||
if ((info->metal_backend_only_ && GPU_backend_get_type() != GPU_BACKEND_METAL) ||
(GPU_compute_shader_support() == false && info->compute_source_ != nullptr) ||
(GPU_geometry_shader_support() == false && info->geometry_source_ != nullptr) ||
(GPU_shader_image_load_store_support() == false && info->has_resource_image()) ||
(GPU_shader_storage_buffer_objects_support() == false && info->has_resource_storage())) {

View File

@ -345,6 +345,9 @@ struct ShaderCreateInfo {
bool legacy_resource_location_ = false;
/** Allow optimization when fragment shader writes to `gl_FragDepth`. */
DepthWrite depth_write_ = DepthWrite::NONE;
/** GPU Backend compatibility flag. Temporary requirement until Metal enablement is fully
* complete. */
bool metal_backend_only_ = false;
/**
* Maximum length of all the resource names including each null terminator.
* Only for names used by #gpu::ShaderInterface.
@ -794,6 +797,12 @@ struct ShaderCreateInfo {
return *(Self *)this;
}
Self &metal_backend_only(bool flag)
{
metal_backend_only_ = flag;
return *(Self *)this;
}
/** \} */
/* -------------------------------------------------------------------- */

View File

@ -21,18 +21,21 @@ GPU_SHADER_CREATE_INFO(depth_2d_update_info_base)
.vertex_source("depth_2d_update_vert.glsl");
GPU_SHADER_CREATE_INFO(depth_2d_update_float)
.metal_backend_only(true)
.fragment_source("depth_2d_update_float_frag.glsl")
.additional_info("depth_2d_update_info_base")
// .do_static_compilation(true)
.depth_write(DepthWrite::ANY);
GPU_SHADER_CREATE_INFO(depth_2d_update_int24)
.metal_backend_only(true)
.fragment_source("depth_2d_update_int24_frag.glsl")
.additional_info("depth_2d_update_info_base")
// .do_static_compilation(true)
.depth_write(DepthWrite::ANY);
GPU_SHADER_CREATE_INFO(depth_2d_update_int32)
.metal_backend_only(true)
.fragment_source("depth_2d_update_int32_frag.glsl")
.additional_info("depth_2d_update_info_base")
// .do_static_compilation(true)