mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-17 17:50:29 +01:00
The result of nir_slot_is_varying depends on what the next shader stage is, and nir_remove_sysval_output uses it. Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32855>
53 lines
1.4 KiB
C
53 lines
1.4 KiB
C
/*
|
|
* 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, MESA_SHADER_FRAGMENT);
|
|
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);
|
|
}
|