ac/nir: cull triangles/lines when all W positions are zero/NaN
It looks like the fixed-func hardware is very slow to cull primitives with zero pos.w but shader based culling helps a lot. This fixes a massive performance gap with the FSR2 demo compared to AMDGPU-PRO, +228% on RDNA2. Based on my investigation, AMDGPU-PRO seems to always cull these primitives. Note that disabling NGG culling with AMDGPU-PRO reports the same performance as RADV without that fix. Also note that the FSR2 sample doesn't specify any cull mode (ie. VK_CULL_MODE_NONE is used), so this is the only reason PRO was culling more than RADV. Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/7260 Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31891>
This commit is contained in:
committed by
Marge Bot
parent
322a83f321
commit
7015e22cb6
@@ -14,7 +14,7 @@
|
||||
typedef struct
|
||||
{
|
||||
nir_def *w_reflection;
|
||||
nir_def *all_w_negative;
|
||||
nir_def *all_w_negative_or_zero_or_nan;
|
||||
nir_def *any_w_negative;
|
||||
} position_w_info;
|
||||
|
||||
@@ -22,15 +22,17 @@ static void
|
||||
analyze_position_w(nir_builder *b, nir_def *pos[][4], unsigned num_vertices,
|
||||
position_w_info *w_info)
|
||||
{
|
||||
w_info->all_w_negative = nir_imm_true(b);
|
||||
w_info->all_w_negative_or_zero_or_nan = nir_imm_true(b);
|
||||
w_info->w_reflection = nir_imm_false(b);
|
||||
w_info->any_w_negative = nir_imm_false(b);
|
||||
|
||||
for (unsigned i = 0; i < num_vertices; ++i) {
|
||||
nir_def *neg_w = nir_flt_imm(b, pos[i][3], 0.0f);
|
||||
nir_def *neg_or_zero_or_nan_w = nir_fgeu(b, nir_imm_float(b, 0.0f), pos[i][3]);
|
||||
|
||||
w_info->w_reflection = nir_ixor(b, neg_w, w_info->w_reflection);
|
||||
w_info->any_w_negative = nir_ior(b, neg_w, w_info->any_w_negative);
|
||||
w_info->all_w_negative = nir_iand(b, neg_w, w_info->all_w_negative);
|
||||
w_info->all_w_negative_or_zero_or_nan = nir_iand(b, neg_or_zero_or_nan_w, w_info->all_w_negative_or_zero_or_nan);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,7 +133,7 @@ ac_nir_cull_triangle(nir_builder *b,
|
||||
void *state)
|
||||
{
|
||||
nir_def *accepted = initially_accepted;
|
||||
accepted = nir_iand(b, accepted, nir_inot(b, w_info->all_w_negative));
|
||||
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)));
|
||||
|
||||
nir_def *bbox_accepted = NULL;
|
||||
@@ -303,7 +305,7 @@ ac_nir_cull_line(nir_builder *b,
|
||||
void *state)
|
||||
{
|
||||
nir_def *accepted = initially_accepted;
|
||||
accepted = nir_iand(b, accepted, nir_inot(b, w_info->all_w_negative));
|
||||
accepted = nir_iand(b, accepted, nir_inot(b, w_info->all_w_negative_or_zero_or_nan));
|
||||
|
||||
nir_def *bbox_accepted = NULL;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user