mesa/st: add sampler uniforms
authorRob Clark <robdclark@chromium.org>
Mon, 15 Jul 2019 16:05:55 +0000 (09:05 -0700)
committerRob Clark <robdclark@gmail.com>
Tue, 16 Jul 2019 18:14:44 +0000 (18:14 +0000)
Add sampler uniforms for the UV plane(s), so driver can count the
uniforms and get the correct sampler count.

Fixes lowered YUV on a6xx which actually wants to know # of samplers.

Signed-off-by: Rob Clark <robdclark@chromium.org>
Reviewed-by: Kristian H. Kristensen <hoegsberg@google.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
src/mesa/state_tracker/st_nir_lower_tex_src_plane.c

index 609a9aa4bc7315761728cfca3d8ff7cb7498ac8d..db838612da83087c4e2fa699a85f6f536a2faa10 100644 (file)
@@ -33,7 +33,7 @@
 #include "st_nir.h"
 
 typedef struct {
-   struct shader_info *info;
+   struct nir_shader *shader;
 
    unsigned lower_2plane;
    unsigned lower_3plane;
@@ -44,6 +44,34 @@ typedef struct {
    unsigned char sampler_map[PIPE_MAX_SAMPLERS][2];
 } lower_tex_src_state;
 
+static nir_variable *
+find_sampler(lower_tex_src_state *state, unsigned samp)
+{
+   /* NOTE: arrays of samplerExternalOES do not appear to be allowed: */
+   nir_foreach_variable(var, &state->shader->uniforms)
+      if (var->data.binding == samp)
+         return var;
+   return NULL;
+}
+
+static void
+add_sampler(lower_tex_src_state *state, unsigned orig_binding,
+            unsigned new_binding, const char *ext)
+{
+   const struct glsl_type *samplerExternalOES =
+      glsl_sampler_type(GLSL_SAMPLER_DIM_EXTERNAL, false, false, GLSL_TYPE_FLOAT);
+   nir_variable *new_sampler, *orig_sampler =
+         find_sampler(state, orig_binding);
+   char *name;
+
+   asprintf(&name, "%s:%s", orig_sampler->name, ext);
+   new_sampler = nir_variable_create(state->shader, nir_var_uniform,
+                             samplerExternalOES, name);
+   free(name);
+
+   new_sampler->data.binding = new_binding;
+}
+
 static void
 assign_extra_samplers(lower_tex_src_state *state, unsigned free_slots)
 {
@@ -52,12 +80,23 @@ assign_extra_samplers(lower_tex_src_state *state, unsigned free_slots)
    while (mask) {
       unsigned extra, y_samp = u_bit_scan(&mask);
 
-      extra = u_bit_scan(&free_slots);
-      state->sampler_map[y_samp][0] = extra;
-
       if (state->lower_3plane & (1 << y_samp)) {
+         /* two additional planes (U and V): */
+         extra = u_bit_scan(&free_slots);
+         state->sampler_map[y_samp][0] = extra;
+
+         add_sampler(state, y_samp, extra, "u");
+
          extra = u_bit_scan(&free_slots);
          state->sampler_map[y_samp][1] = extra;
+
+         add_sampler(state, y_samp, extra, "v");
+      } else {
+         /* single additional UV plane: */
+         extra = u_bit_scan(&free_slots);
+         state->sampler_map[y_samp][0] = extra;
+
+         add_sampler(state, y_samp, extra, "uv");
       }
    }
 }
@@ -88,7 +127,7 @@ lower_tex_src_plane_block(lower_tex_src_state *state, nir_block *block)
          tex->texture_index = tex->sampler_index =
                state->sampler_map[y_samp][plane[0].i32 - 1];
 
-         state->info->textures_used |= 1u << tex->texture_index;
+         state->shader->info.textures_used |= 1u << tex->texture_index;
       }
 
       nir_tex_instr_remove_src(tex, plane_index);
@@ -112,7 +151,7 @@ st_nir_lower_tex_src_plane(struct nir_shader *shader, unsigned free_slots,
 {
    lower_tex_src_state state = {0};
 
-   state.info = &shader->info;
+   state.shader = shader;
    state.lower_2plane = lower_2plane;
    state.lower_3plane = lower_3plane;