• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2024 Valve Corporation
3  * SPDX-License-Identifier: MIT
4  */
5 
6 #include "nir.h"
7 #include "nir_builder.h"
8 
9 /**
10  * If a clip/cull distance is constant >= 0,
11  * we know that it will never cause clipping/culling.
12  * Remove the sysval_output in that case.
13  *
14  * Assumes that nir_lower_io_to_temporaries was run,
15  * and works best with scalar store_outputs.
16  */
17 
18 static bool
opt_clip_cull(nir_builder * b,nir_intrinsic_instr * intr,void * unused)19 opt_clip_cull(nir_builder *b, nir_intrinsic_instr *intr, void *unused)
20 {
21    if (intr->intrinsic != nir_intrinsic_store_output)
22       return false;
23 
24    const nir_io_semantics io_sem = nir_intrinsic_io_semantics(intr);
25    const unsigned location = io_sem.location;
26 
27    if (io_sem.no_sysval_output)
28       return false;
29 
30    if (location != VARYING_SLOT_CLIP_DIST0 && location != VARYING_SLOT_CLIP_DIST1)
31       return false;
32 
33    nir_def *val = intr->src[0].ssa;
34    for (unsigned i = 0; i < val->num_components; i++) {
35       nir_scalar s = nir_scalar_resolved(val, i);
36       if (!nir_scalar_is_const(s))
37          return false;
38       float distance = nir_scalar_as_float(s);
39 
40       /* NaN gets clipped, and INF after interpolation is NaN. */
41       if (isnan(distance) || distance < 0.0 || distance == INFINITY)
42          return false;
43    }
44 
45    nir_remove_sysval_output(intr, MESA_SHADER_FRAGMENT);
46    return true;
47 }
48 
49 bool
nir_opt_clip_cull_const(nir_shader * shader)50 nir_opt_clip_cull_const(nir_shader *shader)
51 {
52    return nir_shader_intrinsics_pass(shader, opt_clip_cull, nir_metadata_control_flow, NULL);
53 }
54