nir: remove handling IO variables from passes used by st/mesa

Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33146>
This commit is contained in:
Marek Olšák
2024-12-24 18:08:43 -05:00
committed by Marge Bot
parent 2c5deaa98b
commit bdd85c8393
13 changed files with 76 additions and 392 deletions

View File

@@ -51,17 +51,8 @@ static bool
lower(nir_builder *b, nir_intrinsic_instr *intr, void *data)
{
struct alpha_test_state *state = data;
nir_variable *out = NULL;
switch (intr->intrinsic) {
case nir_intrinsic_store_deref:
out = nir_intrinsic_get_var(intr, 0);
if (out->data.mode != nir_var_shader_out)
return false;
if (!is_color_output(out->data.location))
return false;
break;
case nir_intrinsic_store_output:
if (!is_color_output(nir_intrinsic_io_semantics(intr).location))
return false;
@@ -75,8 +66,6 @@ lower(nir_builder *b, nir_intrinsic_instr *intr, void *data)
nir_def *alpha;
if (state->alpha_to_one)
alpha = nir_imm_float(b, 1.0);
else if (intr->intrinsic == nir_intrinsic_store_deref)
alpha = nir_channel(b, intr->src[1].ssa, 3);
else
alpha = nir_channel(b, intr->src[0].ssa, 3);
@@ -96,6 +85,7 @@ nir_lower_alpha_test(nir_shader *shader, enum compare_func func,
bool alpha_to_one,
const gl_state_index16 *alpha_ref_state_tokens)
{
assert(shader->info.io_lowered);
struct alpha_test_state state = {
.alpha_ref_state_tokens = alpha_ref_state_tokens,
.alpha_to_one = alpha_to_one,

View File

@@ -58,17 +58,10 @@ lower_bitmap(nir_shader *shader, nir_builder *b,
nir_tex_instr *tex;
nir_def *cond;
if (shader->info.io_lowered) {
nir_def *baryc =
nir_load_barycentric_pixel(b, 32, .interp_mode = INTERP_MODE_SMOOTH);
texcoord = nir_load_interpolated_input(b, 4, 32, baryc, nir_imm_int(b, 0),
.io_semantics.location = VARYING_SLOT_TEX0);
} else {
nir_variable *var =
nir_get_variable_with_location(shader, nir_var_shader_in,
VARYING_SLOT_TEX0, glsl_vec4_type());
texcoord = nir_load_var(b, var);
}
const struct glsl_type *sampler2D =
glsl_sampler_type(GLSL_SAMPLER_DIM_2D, false, false, GLSL_TYPE_FLOAT);
@@ -121,6 +114,7 @@ nir_lower_bitmap(nir_shader *shader,
const nir_lower_bitmap_options *options)
{
assert(shader->info.stage == MESA_SHADER_FRAGMENT);
assert(shader->info.io_lowered);
lower_bitmap_impl(nir_shader_get_entrypoint(shader), options);
return true;

View File

@@ -52,17 +52,9 @@ is_color_output(nir_shader *shader, int location)
static bool
lower_intrinsic(nir_builder *b, nir_intrinsic_instr *intr, nir_shader *shader)
{
nir_variable *out = NULL;
nir_def *s;
int loc = -1;
switch (intr->intrinsic) {
case nir_intrinsic_store_deref:
out = nir_intrinsic_get_var(intr, 0);
if (out->data.mode != nir_var_shader_out)
return false;
loc = out->data.location;
break;
case nir_intrinsic_store_output:
case nir_intrinsic_store_per_view_output:
loc = nir_intrinsic_io_semantics(intr).location;
@@ -73,13 +65,13 @@ lower_intrinsic(nir_builder *b, nir_intrinsic_instr *intr, nir_shader *shader)
if (is_color_output(shader, loc)) {
b->cursor = nir_before_instr(&intr->instr);
int src = intr->intrinsic == nir_intrinsic_store_deref ? 1 : 0;
s = intr->src[src].ssa;
nir_def *s = intr->src[0].ssa;
s = nir_fsat(b, s);
nir_src_rewrite(&intr->src[src], s);
nir_src_rewrite(&intr->src[0], s);
return true;
}
return true;
return false;
}
static bool
@@ -93,6 +85,7 @@ lower_instr(nir_builder *b, nir_instr *instr, void *cb_data)
bool
nir_lower_clamp_color_outputs(nir_shader *shader)
{
assert(shader->info.io_lowered);
return nir_shader_instructions_pass(shader, lower_instr,
nir_metadata_control_flow,
shader);

View File

@@ -33,88 +33,6 @@
* value if the plane is disabled
*/
/* recursively nest if/else blocks until we get to an array index,
* then overwrite it if that plane isn't enabled
*/
static void
recursive_if_chain(nir_builder *b, nir_deref_instr *deref, nir_def *value, unsigned clip_plane_enable, nir_def *index, unsigned start, unsigned end)
{
if (start == end - 1) {
/* store the original value again if the clip plane is enabled */
if (clip_plane_enable & (1 << start))
nir_store_deref(b, deref, value, 1 << start);
else
nir_store_deref(b, deref, nir_imm_int(b, 0), 1 << start);
return;
}
unsigned mid = start + (end - start) / 2;
nir_push_if(b, nir_ilt_imm(b, index, mid));
recursive_if_chain(b, deref, value, clip_plane_enable, index, start, mid);
nir_push_else(b, NULL);
recursive_if_chain(b, deref, value, clip_plane_enable, index, mid, end);
nir_pop_if(b, NULL);
}
/* vulkan (and some drivers) provides no concept of enabling clip planes through api,
* so we rewrite disabled clip planes to a zero value in order to disable them
*/
static bool
lower_clip_plane_store(nir_builder *b, nir_intrinsic_instr *instr,
void *cb_data)
{
unsigned clip_plane_enable = *(unsigned *)cb_data;
nir_variable *out;
unsigned plane;
if (instr->intrinsic != nir_intrinsic_store_deref)
return false;
nir_deref_instr *deref = nir_src_as_deref(instr->src[0]);
out = nir_deref_instr_get_variable(deref);
if ((out->data.location != VARYING_SLOT_CLIP_DIST0 &&
out->data.location != VARYING_SLOT_CLIP_DIST1) ||
out->data.mode != nir_var_shader_out)
return false;
b->cursor = nir_after_instr(&instr->instr);
if (deref->deref_type == nir_deref_type_var) {
int wrmask = nir_intrinsic_write_mask(instr);
nir_def *components[4];
int start = out->data.location == VARYING_SLOT_CLIP_DIST1 ? 4 : 0;
/* rewrite components as zeroes for planes that aren't enabled */
for (int i = 0; i < 4; i++) {
if (wrmask & (1 << i)) {
if (!(clip_plane_enable & (1 << (start + i))))
components[i] = nir_imm_int(b, 0);
else
components[i] = nir_channel(b, instr->src[1].ssa, i);
} else
components[i] = nir_undef(b, 1, 32);
}
nir_store_deref(b, deref, nir_vec(b, components, instr->num_components), wrmask);
} else if (nir_src_is_const(deref->arr.index)) {
/* storing using a constant index */
plane = nir_src_as_uint(deref->arr.index);
/* no need to make changes if the clip plane is enabled */
if (clip_plane_enable & (1 << plane))
return false;
assert(nir_intrinsic_write_mask(instr) == 1);
nir_store_deref(b, deref, nir_imm_int(b, 0), 1);
} else {
/* storing using a variable index */
nir_def *index = deref->arr.index.ssa;
unsigned length = glsl_get_length(nir_deref_instr_parent(deref)->type);
recursive_if_chain(b, deref, instr->src[1].ssa, clip_plane_enable, index, 0, length);
}
nir_instr_remove(&instr->instr);
return true;
}
/* vulkan (and some drivers) provides no concept of enabling clip planes through api,
* so we rewrite disabled clip planes to a zero value in order to disable them
*/
@@ -172,14 +90,15 @@ lower_clip_plane_store_io(nir_builder *b, nir_intrinsic_instr *intr,
bool
nir_lower_clip_disable(nir_shader *shader, unsigned clip_plane_enable)
{
assert(shader->info.io_lowered);
/* if all user planes are enabled in API that are written in the array, always ignore;
* this explicitly covers the 2x vec4 case
*/
if (clip_plane_enable == u_bit_consecutive(0, shader->info.clip_distance_array_size))
return false;
return nir_shader_intrinsics_pass(shader,
shader->info.io_lowered ? lower_clip_plane_store_io : lower_clip_plane_store,
return nir_shader_intrinsics_pass(shader, lower_clip_plane_store_io,
nir_metadata_control_flow,
&clip_plane_enable);
}

View File

@@ -27,33 +27,23 @@
/* Lower glDrawPixels().
*
* This is based on the logic in st_get_drawpix_shader() in TGSI compiler.
*
* Run before nir_lower_io.
*/
typedef struct {
const nir_lower_drawpixels_options *options;
nir_shader *shader;
nir_variable *texcoord, *texcoord_const, *scale, *bias, *tex, *pixelmap;
nir_variable *texcoord_const, *scale, *bias, *tex, *pixelmap;
} lower_drawpixels_state;
static nir_def *
get_texcoord(nir_builder *b, lower_drawpixels_state *state)
{
if (b->shader->info.io_lowered) {
nir_def *baryc =
nir_load_barycentric_pixel(b, 32, .interp_mode = INTERP_MODE_SMOOTH);
return nir_load_interpolated_input(b, 4, 32, baryc, nir_imm_int(b, 0),
.io_semantics.location = VARYING_SLOT_TEX0);
}
if (state->texcoord == NULL) {
state->texcoord = nir_get_variable_with_location(state->shader, nir_var_shader_in,
VARYING_SLOT_TEX0, glsl_vec4_type());
}
return nir_load_var(b, state->texcoord);
}
static nir_def *
get_scale(nir_builder *b, lower_drawpixels_state *state)
{
@@ -215,22 +205,6 @@ lower_drawpixels_instr(nir_builder *b, nir_instr *instr, void *cb_data)
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
switch (intr->intrinsic) {
case nir_intrinsic_load_deref: {
nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
nir_variable *var = nir_deref_instr_get_variable(deref);
if (var->data.location == VARYING_SLOT_COL0) {
/* gl_Color should not have array/struct derefs: */
assert(deref->deref_type == nir_deref_type_var);
return lower_color(b, state, intr);
} else if (var->data.location == VARYING_SLOT_TEX0) {
/* gl_TexCoord should not have array/struct derefs: */
assert(deref->deref_type == nir_deref_type_var);
return lower_texcoord(b, state, intr);
}
break;
}
case nir_intrinsic_load_color0:
return lower_color(b, state, intr);
@@ -253,6 +227,8 @@ bool
nir_lower_drawpixels(nir_shader *shader,
const nir_lower_drawpixels_options *options)
{
assert(shader->info.io_lowered);
lower_drawpixels_state state = {
.options = options,
.shader = shader,

View File

@@ -33,15 +33,6 @@ check_location(int location)
location == VARYING_SLOT_BFC1;
}
static bool
lower_input(nir_shader *shader, nir_variable *var)
{
if (var->data.interpolation == INTERP_MODE_NONE &&
check_location(var->data.location))
var->data.interpolation = INTERP_MODE_FLAT;
return true;
}
static bool
lower_input_io(nir_builder *b, nir_intrinsic_instr *intr, void *data)
{
@@ -62,21 +53,11 @@ lower_input_io(nir_builder *b, nir_intrinsic_instr *intr, void *data)
nir_def_replace(&intr->def, load);
return true;
}
bool
nir_lower_flatshade(nir_shader *shader)
{
bool progress = false;
if (shader->info.io_lowered) {
progress = nir_shader_intrinsics_pass(shader, lower_input_io,
nir_metadata_all, NULL);
} else {
nir_foreach_shader_in_variable(var, shader) {
progress |= lower_input(shader, var);
}
}
/* Interpolation doesn't affect any metadata */
nir_shader_preserve_all_metadata(shader);
return progress;
assert(shader->info.io_lowered);
return nir_shader_intrinsics_pass(shader, lower_input_io, nir_metadata_all,
NULL);
}

View File

@@ -28,11 +28,7 @@ static void
lower_impl(nir_function_impl *impl)
{
nir_shader *shader = impl->function->shader;
nir_builder b;
nir_variable *in, *out;
nir_def *def;
b = nir_builder_at(nir_before_impl(impl));
nir_builder b = nir_builder_at(nir_before_impl(impl));
/* The edge flag is the last input in st/mesa. This code is also called by
* i965 which calls it before any input locations are assigned.
@@ -40,14 +36,11 @@ lower_impl(nir_function_impl *impl)
assert(shader->num_inputs == 0 ||
shader->num_inputs == util_bitcount64(shader->info.inputs_read));
/* Lowered IO only uses intrinsics. It doesn't use variables. */
if (shader->info.io_lowered) {
assert(shader->num_outputs ==
util_bitcount64(shader->info.outputs_written));
/* Load an edge flag. */
nir_def *load =
nir_load_input(&b, 1, 32, nir_imm_int(&b, 0),
nir_def *load = nir_load_input(&b, 1, 32, nir_imm_int(&b, 0),
.base = shader->num_inputs++,
.io_semantics.location = VERT_ATTRIB_EDGEFLAG);
@@ -56,21 +49,6 @@ lower_impl(nir_function_impl *impl)
.base = shader->num_outputs++,
.io_semantics.location = VARYING_SLOT_EDGE);
nir_metadata_preserve(impl, nir_metadata_control_flow);
return;
}
in = nir_create_variable_with_location(b.shader, nir_var_shader_in,
VERT_ATTRIB_EDGEFLAG, glsl_vec4_type());
shader->info.inputs_read |= VERT_BIT_EDGEFLAG;
out = nir_create_variable_with_location(b.shader, nir_var_shader_out,
VARYING_SLOT_EDGE, glsl_vec4_type());
shader->info.outputs_written |= VARYING_BIT_EDGE;
def = nir_load_var(&b, in);
nir_store_var(&b, out, def, 0xf);
nir_metadata_preserve(impl, nir_metadata_control_flow);
}
@@ -78,6 +56,7 @@ bool
nir_lower_passthrough_edgeflags(nir_shader *shader)
{
assert(shader->info.stage == MESA_SHADER_VERTEX);
assert(shader->info.io_lowered);
shader->info.vs.needs_edge_flag = true;

View File

@@ -97,13 +97,10 @@ lower_pntc_ytransform_block(lower_pntc_ytransform_state *state,
nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
nir_variable *var = nir_deref_instr_get_variable(deref);
if ((var->data.mode == nir_var_shader_in &&
var->data.location == VARYING_SLOT_PNTC) ||
(var->data.mode == nir_var_system_value &&
var->data.location == SYSTEM_VALUE_POINT_COORD)) {
if (var->data.mode == nir_var_system_value &&
var->data.location == SYSTEM_VALUE_POINT_COORD)
lower_load_pointcoord(state, intr);
}
}
if (intr->intrinsic == nir_intrinsic_load_interpolated_input &&
nir_intrinsic_io_semantics(intr).location == VARYING_SLOT_PNTC)
@@ -116,6 +113,8 @@ bool
nir_lower_pntc_ytransform(nir_shader *shader,
const gl_state_index16 pntc_state_tokens[][STATE_LENGTH])
{
assert(shader->info.io_lowered);
if (!shader->options->lower_wpos_pntc)
return false;

View File

@@ -36,27 +36,8 @@ lower_point_size_mov_after(nir_builder *b, nir_variable *in)
{
nir_def *load = nir_load_var(b, in);
load = nir_fclamp(b, nir_channel(b, load, 0), nir_channel(b, load, 1), nir_channel(b, load, 2));
if (b->shader->info.io_lowered) {
nir_store_output(b, load, nir_imm_int(b, 0),
.io_semantics.location = VARYING_SLOT_PSIZ);
} else {
nir_variable *out = NULL;
/* the existing output can't be removed in order to avoid breaking xfb.
* drivers must check var->data.explicit_location to find the original output
* and only emit that one for xfb
*/
nir_foreach_shader_out_variable(var, b->shader) {
if (var->data.location == VARYING_SLOT_PSIZ && !var->data.explicit_location) {
out = var;
break;
}
}
if (!out) {
out = nir_create_variable_with_location(b->shader, nir_var_shader_out,
VARYING_SLOT_PSIZ, glsl_float_type());
}
nir_store_var(b, out, load, 0x1);
}
}
static bool
@@ -73,11 +54,6 @@ lower_point_size_mov(nir_builder *b, nir_intrinsic_instr *intr, void *data)
return false;
break;
}
case nir_intrinsic_store_deref:
var = nir_intrinsic_get_var(intr, 0);
if (var->data.location != VARYING_SLOT_PSIZ)
return false;
break;
default:
return false;
}
@@ -94,7 +70,7 @@ nir_lower_point_size_mov(nir_shader *shader,
{
assert(shader->info.stage != MESA_SHADER_FRAGMENT &&
shader->info.stage != MESA_SHADER_COMPUTE);
assert(shader->info.io_lowered);
bool progress = false;
nir_metadata preserved = nir_metadata_control_flow;

View File

@@ -33,10 +33,6 @@ typedef struct {
nir_builder b;
nir_shader *shader;
bool face_sysval;
struct {
nir_variable *front; /* COLn */
nir_variable *back; /* BFCn */
} colors[MAX_COLORS];
int colors_count;
} lower_2side_state;
@@ -45,19 +41,6 @@ typedef struct {
* instruction used to select front or back color based on FACE.
*/
static nir_variable *
create_input(nir_shader *shader, gl_varying_slot slot,
enum glsl_interp_mode interpolation)
{
nir_variable *var = nir_create_variable_with_location(shader, nir_var_shader_in,
slot, glsl_vec4_type());
var->data.index = 0;
var->data.interpolation = interpolation;
return var;
}
static nir_def *
load_input(nir_builder *b, nir_intrinsic_instr *intr, int location)
{
@@ -79,44 +62,10 @@ load_input(nir_builder *b, nir_intrinsic_instr *intr, int location)
static int
setup_inputs(lower_2side_state *state)
{
if (state->shader->info.io_lowered) {
state->colors_count = util_bitcount64(state->shader->info.inputs_read & (VARYING_BIT_COL0 | VARYING_BIT_COL1));
return state->colors_count ? 0 : -1;
}
/* find color inputs: */
nir_foreach_shader_in_variable(var, state->shader) {
switch (var->data.location) {
case VARYING_SLOT_COL0:
case VARYING_SLOT_COL1:
assert(state->colors_count < ARRAY_SIZE(state->colors));
state->colors[state->colors_count].front = var;
state->colors_count++;
break;
}
}
/* if we don't have any color inputs, nothing to do: */
if (state->colors_count == 0)
return -1;
/* add required back-face color inputs: */
for (int i = 0; i < state->colors_count; i++) {
gl_varying_slot slot;
if (state->colors[i].front->data.location == VARYING_SLOT_COL0)
slot = VARYING_SLOT_BFC0;
else
slot = VARYING_SLOT_BFC1;
state->colors[i].back = create_input(
state->shader, slot,
state->colors[i].front->data.interpolation);
}
return 0;
}
static bool
nir_lower_two_sided_color_instr(nir_builder *b, nir_instr *instr, void *data)
{
@@ -132,18 +81,6 @@ nir_lower_two_sided_color_instr(nir_builder *b, nir_instr *instr, void *data)
if (sem.location != VARYING_SLOT_COL0 && sem.location != VARYING_SLOT_COL1)
return false;
idx = sem.location;
} else if (intr->intrinsic == nir_intrinsic_load_deref) {
nir_variable *var = nir_intrinsic_get_var(intr, 0);
if (var->data.mode != nir_var_shader_in)
return false;
for (idx = 0; idx < state->colors_count; idx++) {
unsigned loc = state->colors[idx].front->data.location;
if (var->data.location == loc)
break;
}
if (idx == state->colors_count)
return false;
} else
return false;
@@ -159,27 +96,14 @@ nir_lower_two_sided_color_instr(nir_builder *b, nir_instr *instr, void *data)
if (state->face_sysval)
face = nir_load_front_face(b, 1);
else {
if (b->shader->info.io_lowered) {
face = nir_load_input(b, 1, 32, nir_imm_int(b, 0), .base = 0,
.dest_type = nir_type_bool32,
.io_semantics.location = VARYING_SLOT_FACE);
face = nir_b2b1(b, face);
} else {
nir_variable *var = nir_get_variable_with_location(b->shader, nir_var_shader_in,
VARYING_SLOT_FACE, glsl_bool_type());
var->data.interpolation = INTERP_MODE_FLAT;
face = nir_load_var(b, var);
}
}
nir_def *front, *back;
if (intr->intrinsic == nir_intrinsic_load_deref) {
front = nir_load_var(b, state->colors[idx].front);
back = nir_load_var(b, state->colors[idx].back);
} else {
front = load_input(b, intr, idx);
back = load_input(b, intr, idx == VARYING_SLOT_COL0 ? VARYING_SLOT_BFC0 : VARYING_SLOT_BFC1);
}
nir_def *front = load_input(b, intr, idx);
nir_def *back = load_input(b, intr, idx == VARYING_SLOT_COL0 ? VARYING_SLOT_BFC0 : VARYING_SLOT_BFC1);
nir_def *color = nir_bcsel(b, face, front, back);
nir_def_rewrite_uses(&intr->def, color);
@@ -190,6 +114,8 @@ nir_lower_two_sided_color_instr(nir_builder *b, nir_instr *instr, void *data)
bool
nir_lower_two_sided_color(nir_shader *shader, bool face_sysval)
{
assert(shader->info.io_lowered);
lower_2side_state state = {
.shader = shader,
.face_sysval = face_sysval,

View File

@@ -280,10 +280,8 @@ lower_wpos_ytransform_instr(nir_builder *b, nir_intrinsic_instr *intr,
case nir_intrinsic_load_deref: {
nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
nir_variable *var = nir_deref_instr_get_variable(deref);
if ((var->data.mode == nir_var_shader_in &&
var->data.location == VARYING_SLOT_POS) ||
(var->data.mode == nir_var_system_value &&
var->data.location == SYSTEM_VALUE_FRAG_COORD)) {
if (var->data.mode == nir_var_system_value &&
var->data.location == SYSTEM_VALUE_FRAG_COORD) {
/* gl_FragCoord should not have array/struct derefs: */
return lower_fragcoord(state, intr);
} else if (var->data.mode == nir_var_system_value &&
@@ -319,6 +317,8 @@ bool
nir_lower_wpos_ytransform(nir_shader *shader,
const nir_lower_wpos_ytransform_options *options)
{
assert(shader->info.io_lowered);
lower_wpos_ytransform_state state = {
.options = options,
};

View File

@@ -11,19 +11,10 @@ static nir_def *
fog_result(nir_builder *b, nir_def *color, enum gl_fog_mode fog_mode, struct gl_program_parameter_list *paramList)
{
nir_shader *s = b->shader;
nir_def *fogc;
if (b->shader->info.io_lowered) {
nir_def *baryc = nir_load_barycentric_pixel(b, 32,
.interp_mode = INTERP_MODE_SMOOTH);
fogc = nir_load_interpolated_input(b, 1, 32, baryc, nir_imm_int(b, 0),
nir_def *fogc = nir_load_interpolated_input(b, 1, 32, baryc, nir_imm_int(b, 0),
.io_semantics.location = VARYING_SLOT_FOGC);
} else {
nir_variable *fogc_var =
nir_create_variable_with_location(s, nir_var_shader_in, VARYING_SLOT_FOGC, glsl_float_type());
s->info.inputs_read |= VARYING_BIT_FOGC;
fogc = nir_load_var(b, fogc_var);
}
static const gl_state_index16 fog_params_tokens[STATE_LENGTH] = {STATE_FOG_PARAMS_OPTIMIZED};
static const gl_state_index16 fog_color_tokens[STATE_LENGTH] = {STATE_FOG_COLOR};
@@ -120,37 +111,13 @@ st_nir_lower_fog_instr(nir_builder *b, nir_instr *instr, void *_state)
bool
st_nir_lower_fog(nir_shader *s, enum gl_fog_mode fog_mode, struct gl_program_parameter_list *paramList)
{
if (s->info.io_lowered) {
assert(s->info.io_lowered);
struct lower_fog_state state = {
.fog_mode = fog_mode,
.paramList = paramList,
};
nir_shader_instructions_pass(s, st_nir_lower_fog_instr,
return nir_shader_instructions_pass(s, st_nir_lower_fog_instr,
nir_metadata_control_flow,
&state);
} else {
nir_variable *color_var = nir_find_variable_with_location(s, nir_var_shader_out, FRAG_RESULT_COLOR);
if (!color_var) {
color_var = nir_find_variable_with_location(s, nir_var_shader_out, FRAG_RESULT_DATA0);
/* Fog result would be undefined if we had no output color (in ARB_fragment_program) */
if (!color_var)
return false;
}
nir_function_impl *impl = nir_shader_get_entrypoint(s);
nir_builder b = nir_builder_at(nir_after_impl(impl));
/* Note: while ARB_fragment_program plus ARB_draw_buffers allows an array
* of result colors, prog_to_nir generates separate vars per slot so we
* don't have to handle that. Fog only applies to the first color result.
*/
assert(!glsl_type_is_array(color_var->type));
nir_def *color = nir_load_var(&b, color_var);
color = fog_result(&b, color, fog_mode, paramList);
nir_store_var(&b, color_var, color, 0x7);
nir_metadata_preserve(b.impl, nir_metadata_control_flow); }
return true;
}

View File

@@ -20,6 +20,7 @@ bool
st_nir_lower_position_invariant(struct nir_shader *s, bool aos,
struct gl_program_parameter_list *paramList)
{
assert(s->info.io_lowered);
nir_function_impl *impl = nir_shader_get_entrypoint(s);
nir_builder b = nir_builder_at(nir_before_impl(impl));
@@ -33,17 +34,8 @@ st_nir_lower_position_invariant(struct nir_shader *s, bool aos,
}
nir_def *result;
nir_def *in_pos;
if (s->info.io_lowered) {
in_pos = nir_load_input(&b, 4, 32, nir_imm_int(&b, 0),
nir_def *in_pos = nir_load_input(&b, 4, 32, nir_imm_int(&b, 0),
.io_semantics.location = VERT_ATTRIB_POS);
} else {
in_pos = nir_load_var(&b, nir_get_variable_with_location(s, nir_var_shader_in,
VERT_ATTRIB_POS,
glsl_vec4_type()));
s->info.inputs_read |= VERT_BIT_POS;
}
if (aos) {
nir_def *chans[4];
@@ -56,16 +48,8 @@ st_nir_lower_position_invariant(struct nir_shader *s, bool aos,
result = nir_fmad(&b, mvp[i], nir_channel(&b, in_pos, i), result);
}
if (s->info.io_lowered) {
nir_store_output(&b, result, nir_imm_int(&b, 0),
.io_semantics.location = VARYING_SLOT_POS);
} else {
nir_store_var(&b, nir_get_variable_with_location(s, nir_var_shader_out,
VARYING_SLOT_POS,
glsl_vec4_type()), result, 0xf);
s->info.outputs_written |= VARYING_BIT_POS;
}
nir_metadata_preserve(b.impl, nir_metadata_control_flow);
return true;