const nir_lower_drawpixels_options *options;
nir_shader *shader;
nir_builder b;
- nir_variable *texcoord, *scale, *bias;
+ nir_variable *texcoord, *texcoord_const, *scale, *bias, *tex, *pixelmap;
} lower_drawpixels_state;
static nir_ssa_def *
nir_variable *texcoord = NULL;
/* find gl_TexCoord, if it exists: */
- nir_foreach_variable(var, &state->shader->inputs) {
+ nir_foreach_shader_in_variable(var, state->shader) {
if (var->data.location == VARYING_SLOT_TEX0) {
texcoord = var;
break;
static nir_ssa_def *
get_texcoord_const(lower_drawpixels_state *state)
{
- if (state->bias == NULL) {
- state->bias = create_uniform(state->shader, "gl_MultiTexCoord0",
+ if (state->texcoord_const == NULL) {
+ state->texcoord_const = create_uniform(state->shader,
+ "gl_MultiTexCoord0",
state->options->texcoord_state_tokens);
}
- return nir_load_var(&state->b, state->bias);
+ return nir_load_var(&state->b, state->texcoord_const);
}
static void
texcoord = get_texcoord(state);
+ const struct glsl_type *sampler2D =
+ glsl_sampler_type(GLSL_SAMPLER_DIM_2D, false, false, GLSL_TYPE_FLOAT);
+
+ if (!state->tex) {
+ state->tex =
+ nir_variable_create(b->shader, nir_var_uniform, sampler2D, "drawpix");
+ state->tex->data.binding = state->options->drawpix_sampler;
+ state->tex->data.explicit_binding = true;
+ state->tex->data.how_declared = nir_var_hidden;
+ }
+
+ nir_deref_instr *tex_deref = nir_build_deref_var(b, state->tex);
+
/* replace load_var(gl_Color) w/ texture sample:
* TEX def, texcoord, drawpix_sampler, 2D
*/
- tex = nir_tex_instr_create(state->shader, 1);
+ tex = nir_tex_instr_create(state->shader, 3);
tex->op = nir_texop_tex;
tex->sampler_dim = GLSL_SAMPLER_DIM_2D;
tex->coord_components = 2;
- tex->sampler_index = state->options->drawpix_sampler;
- tex->texture_index = state->options->drawpix_sampler;
tex->dest_type = nir_type_float;
- tex->src[0].src_type = nir_tex_src_coord;
- tex->src[0].src =
+ tex->src[0].src_type = nir_tex_src_texture_deref;
+ tex->src[0].src = nir_src_for_ssa(&tex_deref->dest.ssa);
+ tex->src[1].src_type = nir_tex_src_sampler_deref;
+ tex->src[1].src = nir_src_for_ssa(&tex_deref->dest.ssa);
+ tex->src[2].src_type = nir_tex_src_coord;
+ tex->src[2].src =
nir_src_for_ssa(nir_channels(b, texcoord,
(1 << tex->coord_components) - 1));
}
if (state->options->pixel_maps) {
- static const unsigned swiz_xy[4] = {0,1};
- static const unsigned swiz_zw[4] = {2,3};
+ if (!state->pixelmap) {
+ state->pixelmap = nir_variable_create(b->shader, nir_var_uniform,
+ sampler2D, "pixelmap");
+ state->pixelmap->data.binding = state->options->pixelmap_sampler;
+ state->pixelmap->data.explicit_binding = true;
+ state->pixelmap->data.how_declared = nir_var_hidden;
+ }
+
+ nir_deref_instr *pixelmap_deref =
+ nir_build_deref_var(b, state->pixelmap);
/* do four pixel map look-ups with two TEX instructions: */
nir_ssa_def *def_xy, *def_zw;
/* TEX def.xy, def.xyyy, pixelmap_sampler, 2D; */
- tex = nir_tex_instr_create(state->shader, 1);
+ tex = nir_tex_instr_create(state->shader, 3);
tex->op = nir_texop_tex;
tex->sampler_dim = GLSL_SAMPLER_DIM_2D;
tex->coord_components = 2;
tex->sampler_index = state->options->pixelmap_sampler;
tex->texture_index = state->options->pixelmap_sampler;
tex->dest_type = nir_type_float;
- tex->src[0].src_type = nir_tex_src_coord;
- tex->src[0].src = nir_src_for_ssa(nir_swizzle(b, def, swiz_xy, 2, true));
+ tex->src[0].src_type = nir_tex_src_texture_deref;
+ tex->src[0].src = nir_src_for_ssa(&pixelmap_deref->dest.ssa);
+ tex->src[1].src_type = nir_tex_src_sampler_deref;
+ tex->src[1].src = nir_src_for_ssa(&pixelmap_deref->dest.ssa);
+ tex->src[2].src_type = nir_tex_src_coord;
+ tex->src[2].src = nir_src_for_ssa(nir_channels(b, def, 0x3));
nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, NULL);
nir_builder_instr_insert(b, &tex->instr);
tex->sampler_index = state->options->pixelmap_sampler;
tex->dest_type = nir_type_float;
tex->src[0].src_type = nir_tex_src_coord;
- tex->src[0].src = nir_src_for_ssa(nir_swizzle(b, def, swiz_zw, 2, true));
+ tex->src[0].src = nir_src_for_ssa(nir_channels(b, def, 0xc));
nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, NULL);
nir_builder_instr_insert(b, &tex->instr);
nir_foreach_instr_safe(instr, block) {
if (instr->type == nir_instr_type_intrinsic) {
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
- if (intr->intrinsic == nir_intrinsic_load_var) {
- nir_deref_var *dvar = intr->variables[0];
- nir_variable *var = dvar->var;
+
+ 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(dvar->deref.child == NULL);
+ assert(deref->deref_type == nir_deref_type_var);
lower_color(state, intr);
} else if (var->data.location == VARYING_SLOT_TEX0) {
/* gl_TexCoord should not have array/struct derefs: */
- assert(dvar->deref.child == NULL);
+ assert(deref->deref_type == nir_deref_type_var);
lower_texcoord(state, intr);
}
+ break;
+ }
+
+ case nir_intrinsic_load_color0:
+ lower_color(state, intr);
+ break;
+
+ case nir_intrinsic_load_interpolated_input:
+ case nir_intrinsic_load_input: {
+ if (nir_intrinsic_io_semantics(intr).location == VARYING_SLOT_TEX0)
+ lower_texcoord(state, intr);
+ break;
+ }
+ default:
+ break;
}
}
}