mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 19:40:10 +01:00
nir: add constant clip/cull distance optimization
Reviewed-by: Marek Olšák <marek.olsak@amd.com> Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32518>
This commit is contained in:
parent
4f88dbffa4
commit
c5c22fc3a3
3 changed files with 56 additions and 0 deletions
|
|
@ -221,6 +221,7 @@ files_libnir = files(
|
|||
'nir_normalize_cubemap_coords.c',
|
||||
'nir_opt_access.c',
|
||||
'nir_opt_barriers.c',
|
||||
'nir_opt_clip_cull_const.c',
|
||||
'nir_opt_combine_stores.c',
|
||||
'nir_opt_comparison_pre.c',
|
||||
'nir_opt_conditional_discard.c',
|
||||
|
|
|
|||
|
|
@ -5718,6 +5718,8 @@ void nir_assign_io_var_locations(nir_shader *shader,
|
|||
unsigned *size,
|
||||
gl_shader_stage stage);
|
||||
|
||||
bool nir_opt_clip_cull_const(nir_shader *shader);
|
||||
|
||||
typedef enum {
|
||||
/* If set, this causes all 64-bit IO operations to be lowered on-the-fly
|
||||
* to 32-bit operations. This is only valid for nir_var_shader_in/out
|
||||
|
|
|
|||
53
src/compiler/nir/nir_opt_clip_cull_const.c
Normal file
53
src/compiler/nir/nir_opt_clip_cull_const.c
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright 2024 Valve Corporation
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "nir.h"
|
||||
#include "nir_builder.h"
|
||||
|
||||
/**
|
||||
* If a clip/cull distance is constant >= 0,
|
||||
* we know that it will never cause clipping/culling.
|
||||
* Remove the sysval_output in that case.
|
||||
*
|
||||
* Assumes that nir_lower_io_to_temporaries was run,
|
||||
* and works best with scalar store_outputs.
|
||||
*/
|
||||
|
||||
static bool
|
||||
opt_clip_cull(nir_builder *b, nir_intrinsic_instr *intr, void *unused)
|
||||
{
|
||||
if (intr->intrinsic != nir_intrinsic_store_output)
|
||||
return false;
|
||||
|
||||
const nir_io_semantics io_sem = nir_intrinsic_io_semantics(intr);
|
||||
const unsigned location = io_sem.location;
|
||||
|
||||
if (io_sem.no_sysval_output)
|
||||
return false;
|
||||
|
||||
if (location != VARYING_SLOT_CLIP_DIST0 && location != VARYING_SLOT_CLIP_DIST1)
|
||||
return false;
|
||||
|
||||
nir_def *val = intr->src[0].ssa;
|
||||
for (unsigned i = 0; i < val->num_components; i++) {
|
||||
nir_scalar s = nir_scalar_resolved(val, i);
|
||||
if (!nir_scalar_is_const(s))
|
||||
return false;
|
||||
float distance = nir_scalar_as_float(s);
|
||||
|
||||
/* NaN gets clipped, and INF after interpolation is NaN. */
|
||||
if (isnan(distance) || distance < 0.0 || distance == INFINITY)
|
||||
return false;
|
||||
}
|
||||
|
||||
nir_remove_sysval_output(intr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
nir_opt_clip_cull_const(nir_shader *shader)
|
||||
{
|
||||
return nir_shader_intrinsics_pass(shader, opt_clip_cull, nir_metadata_control_flow, NULL);
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue