ac/nir/ngg: add an option to skip viewport-based culling
We can do W and face culling when we have multiple viewports, but not frustum and small prim culling because those are dependent on the viewport. When a shader writes the viewport index, the new option allows skipping viewport-based culling while keeping W and face culling. Reviewed-by: Timur Kristóf <timur.kristof@gmail.com> Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33482>
This commit is contained in:
@@ -160,6 +160,10 @@ typedef struct {
|
||||
bool kill_layer;
|
||||
bool force_vrs;
|
||||
bool compact_primitives;
|
||||
/* Skip culling dependent on the viewport state, which is frustum culling and small prim
|
||||
* culling. Set this when the shader writes the viewport index.
|
||||
*/
|
||||
bool skip_viewport_culling;
|
||||
|
||||
/* VS */
|
||||
unsigned num_vertices_per_primitive;
|
||||
|
||||
@@ -134,6 +134,7 @@ call_accept_func(nir_builder *b, nir_def *accepted, ac_nir_cull_accepted accept_
|
||||
|
||||
static nir_def *
|
||||
ac_nir_cull_triangle(nir_builder *b,
|
||||
bool skip_viewport_culling,
|
||||
nir_def *initially_accepted,
|
||||
nir_def *pos[3][4],
|
||||
position_w_info *w_info,
|
||||
@@ -144,6 +145,11 @@ ac_nir_cull_triangle(nir_builder *b,
|
||||
accepted = nir_iand(b, accepted, nir_inot(b, w_info->all_w_negative_or_zero_or_nan));
|
||||
accepted = nir_iand(b, accepted, nir_inot(b, cull_face_triangle(b, pos, w_info)));
|
||||
|
||||
if (skip_viewport_culling) {
|
||||
call_accept_func(b, accepted, accept_func, state);
|
||||
return accepted;
|
||||
}
|
||||
|
||||
nir_def *bbox_accepted = NULL;
|
||||
|
||||
nir_if *if_accepted = nir_push_if(b, accepted);
|
||||
@@ -305,6 +311,7 @@ cull_small_primitive_line(nir_builder *b, nir_def *pos[3][4],
|
||||
|
||||
static nir_def *
|
||||
ac_nir_cull_line(nir_builder *b,
|
||||
bool skip_viewport_culling,
|
||||
nir_def *initially_accepted,
|
||||
nir_def *pos[3][4],
|
||||
position_w_info *w_info,
|
||||
@@ -314,6 +321,11 @@ ac_nir_cull_line(nir_builder *b,
|
||||
nir_def *accepted = initially_accepted;
|
||||
accepted = nir_iand(b, accepted, nir_inot(b, w_info->all_w_negative_or_zero_or_nan));
|
||||
|
||||
if (skip_viewport_culling) {
|
||||
call_accept_func(b, accepted, accept_func, state);
|
||||
return accepted;
|
||||
}
|
||||
|
||||
nir_def *bbox_accepted = NULL;
|
||||
|
||||
nir_if *if_accepted = nir_push_if(b, accepted);
|
||||
@@ -336,6 +348,7 @@ ac_nir_cull_line(nir_builder *b,
|
||||
|
||||
nir_def *
|
||||
ac_nir_cull_primitive(nir_builder *b,
|
||||
bool skip_viewport_culling,
|
||||
nir_def *initially_accepted,
|
||||
nir_def *pos[3][4],
|
||||
unsigned num_vertices,
|
||||
@@ -345,12 +358,15 @@ ac_nir_cull_primitive(nir_builder *b,
|
||||
position_w_info w_info = {0};
|
||||
analyze_position_w(b, pos, num_vertices, &w_info);
|
||||
|
||||
if (num_vertices == 3)
|
||||
return ac_nir_cull_triangle(b, initially_accepted, pos, &w_info, accept_func, state);
|
||||
else if (num_vertices == 2)
|
||||
return ac_nir_cull_line(b, initially_accepted, pos, &w_info, accept_func, state);
|
||||
else
|
||||
if (num_vertices == 3) {
|
||||
return ac_nir_cull_triangle(b, skip_viewport_culling, initially_accepted, pos, &w_info,
|
||||
accept_func, state);
|
||||
} else if (num_vertices == 2) {
|
||||
return ac_nir_cull_line(b, skip_viewport_culling, initially_accepted, pos, &w_info,
|
||||
accept_func, state);
|
||||
} else {
|
||||
unreachable("point culling not implemented");
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -146,6 +146,7 @@ ac_nir_map_io_location(unsigned location,
|
||||
|
||||
nir_def *
|
||||
ac_nir_cull_primitive(nir_builder *b,
|
||||
bool skip_viewport_culling,
|
||||
nir_def *initially_accepted,
|
||||
nir_def *pos[3][4],
|
||||
unsigned num_vertices,
|
||||
|
||||
@@ -1288,7 +1288,7 @@ add_deferred_attribute_culling(nir_builder *b, nir_cf_list *original_extracted_c
|
||||
}
|
||||
|
||||
/* See if the current primitive is accepted */
|
||||
ac_nir_cull_primitive(b, accepted_by_clipdist, pos,
|
||||
ac_nir_cull_primitive(b, s->options->skip_viewport_culling, accepted_by_clipdist, pos,
|
||||
s->options->num_vertices_per_primitive,
|
||||
cull_primitive_accepted, s);
|
||||
}
|
||||
|
||||
@@ -631,8 +631,9 @@ ngg_gs_cull_primitive(nir_builder *b, nir_def *tid_in_tg, nir_def *max_vtxcnt,
|
||||
/* TODO: support clipdist culling in GS */
|
||||
nir_def *accepted_by_clipdist = nir_imm_true(b);
|
||||
|
||||
nir_def *accepted = ac_nir_cull_primitive(
|
||||
b, accepted_by_clipdist, pos, s->num_vertices_per_primitive, NULL, NULL);
|
||||
nir_def *accepted = ac_nir_cull_primitive(b, s->options->skip_viewport_culling,
|
||||
accepted_by_clipdist, pos,
|
||||
s->num_vertices_per_primitive, NULL, NULL);
|
||||
|
||||
nir_if *if_rejected = nir_push_if(b, nir_inot(b, accepted));
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user