nir: Support vec8/vec16 in nir_lower_bit_size
[mesa.git] / src / compiler / nir / nir_lower_drawpixels.c
index acec9443431be774195661f0175d41394d5d3ef8..f2e64722be8e491d030023f4e0c761bc0e490b4c 100644 (file)
@@ -35,7 +35,7 @@ typedef struct {
    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 *
@@ -67,7 +67,8 @@ get_texcoord(lower_drawpixels_state *state)
 }
 
 static nir_variable *
-create_uniform(nir_shader *shader, const char *name, const int state_tokens[5])
+create_uniform(nir_shader *shader, const char *name,
+               const gl_state_index16 state_tokens[STATE_LENGTH])
 {
    nir_variable *var = nir_variable_create(shader,
                                            nir_var_uniform,
@@ -103,11 +104,12 @@ get_bias(lower_drawpixels_state *state)
 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
@@ -124,18 +126,33 @@ lower_color(lower_drawpixels_state *state, nir_intrinsic_instr *intr)
 
    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));
 
@@ -150,22 +167,34 @@ lower_color(lower_drawpixels_state *state, nir_intrinsic_instr *intr)
    }
 
    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);
@@ -179,7 +208,7 @@ lower_color(lower_drawpixels_state *state, nir_intrinsic_instr *intr)
       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);
@@ -211,19 +240,44 @@ lower_drawpixels_block(lower_drawpixels_state *state, nir_block *block)
    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: {
+            /* The intrinsic doesn't carry the variable. We need to find it
+             * manually.
+             */
+            nir_foreach_variable(var, &state->b.shader->inputs) {
+               if ((var->data.driver_location == nir_intrinsic_base(intr)) &&
+                   (nir_intrinsic_component(intr) >= var->data.location_frac  &&
+                    nir_intrinsic_component(intr) <
+                     (var->data.location_frac + glsl_get_components(var->type))))
+                  lower_texcoord(state, intr);
+            }
+            break;
+         }
+         default:
+            break;
          }
       }
    }