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