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:
@@ -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,
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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,
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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,
|
||||
|
@@ -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,
|
||||
};
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user