mesa: Use the NIR pass for fixed function fog.

Reviewed-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23111>
This commit is contained in:
Emma Anholt 2023-05-16 16:54:20 -07:00 committed by Marge Bot
parent 804647acfc
commit 6b529eabeb

View file

@ -42,6 +42,7 @@
#include "state_tracker/st_context.h"
#include "state_tracker/st_program.h"
#include "state_tracker/st_nir.h"
#include "compiler/nir/nir_builder.h"
#include "compiler/nir/nir_builtin_builder.h"
@ -875,80 +876,6 @@ load_texunit_sources(struct texenv_fragment_program *p, GLuint unit)
return GL_TRUE;
}
/**
* Applies the fog calculations.
*
* This is basically like the ARB_fragment_prorgam fog options. Note
* that ffvertex_prog.c produces fogcoord for us when
* GL_FOG_COORDINATE_EXT is set to GL_FRAGMENT_DEPTH_EXT.
*/
static nir_ssa_def *
emit_fog_instructions(struct texenv_fragment_program *p,
nir_ssa_def *fragcolor)
{
struct state_key *key = p->state;
nir_ssa_def *color, *oparams;
nir_ssa_def *fogcoord;
/* Temporary storage for the whole fog result. Fog calculations
* only affect rgb so we're hanging on to the .a value of fragcolor
* this way.
*/
nir_ssa_def *fog_alpha = nir_channel(p->b, fragcolor, 3);
oparams = load_state_var(p, STATE_FOG_PARAMS_OPTIMIZED,
0, 0, 0,
glsl_vec4_type());
assert(oparams);
fogcoord = load_input(p, VARYING_SLOT_FOGC, glsl_float_type());
assert(fogcoord);
color = load_state_var(p, STATE_FOG_COLOR,
0, 0, 0,
glsl_vec4_type());
assert(color);
nir_ssa_def *f = fogcoord;
switch (key->fog_mode) {
case FOG_LINEAR:
/* f = (end - z) / (end - start)
*
* gl_MesaFogParamsOptimized gives us (-1 / (end - start)) and
* (end / (end - start)) so we can generate a single MAD.
*/
f = nir_fadd(p->b, nir_fmul(p->b, f,
nir_channel(p->b, oparams, 0)),
nir_channel(p->b, oparams, 1));
break;
case FOG_EXP:
/* f = e^(-(density * fogcoord))
*
* gl_MesaFogParamsOptimized gives us density/ln(2) so we can
* use EXP2 which is generally the native instruction without
* having to do any further math on the fog density uniform.
*/
f = nir_fmul(p->b, f, nir_channel(p->b, oparams, 2));
f = nir_fexp2(p->b, nir_fneg(p->b, f));
break;
case FOG_EXP2:
/* f = e^(-(density * fogcoord)^2)
*
* gl_MesaFogParamsOptimized gives us density/sqrt(ln(2)) so we
* can do this like FOG_EXP but with a squaring after the
* multiply by density.
*/
f = nir_fmul(p->b, f, nir_channel(p->b, oparams, 3));
f = nir_fmul(p->b, f, f);
f = nir_fexp2(p->b, nir_fneg(p->b, f));
break;
}
f = nir_fsat(p->b, f);
nir_ssa_def *fog_rgb = nir_flrp(p->b, color, fragcolor, f);
return nir_vector_insert_imm(p->b, fog_rgb, fog_alpha, 3);
}
static void
emit_instructions(struct texenv_fragment_program *p)
{
@ -990,10 +917,6 @@ emit_instructions(struct texenv_fragment_program *p)
cf = nir_fadd(p->b, spec_result, secondary);
}
if (key->fog_mode) {
cf = emit_fog_instructions(p, cf);
}
const char *name =
gl_frag_result_name(FRAG_RESULT_COLOR);
nir_variable *var =
@ -1041,6 +964,9 @@ create_new_program(struct state_key *key,
nir_validate_shader(b.shader, "after generating ff-vertex shader");
if (key->fog_mode)
NIR_PASS_V(b.shader, st_nir_lower_fog, key->fog_mode, p.state_params);
_mesa_add_separate_state_parameters(program, p.state_params);
_mesa_free_parameter_list(p.state_params);