nir: support feeding state to nir_lower_clip_[vg]s
[mesa.git] / src / mesa / drivers / dri / i965 / brw_nir_uniforms.cpp
index 7e13b2ffe1984748923bc0f94f80460e2d88f016..639bdfc0f2cbe1750dc78200367e2d51d87e3b77 100644 (file)
@@ -80,15 +80,15 @@ setup_vec4_image_param(uint32_t *params, uint32_t idx,
 }
 
 static void
-brw_setup_image_uniform_values(gl_shader_stage stage,
-                               struct brw_stage_prog_data *stage_prog_data,
-                               unsigned param_start_index,
-                               const gl_uniform_storage *storage)
+brw_setup_image_uniform_values(nir_variable *var,
+                               struct brw_stage_prog_data *prog_data)
 {
-   uint32_t *param = &stage_prog_data->param[param_start_index];
+   unsigned param_start_index = var->data.driver_location / 4;
+   uint32_t *param = &prog_data->param[param_start_index];
+   unsigned num_images = MAX2(1, var->type->arrays_of_arrays_size());
 
-   for (unsigned i = 0; i < MAX2(storage->array_elements, 1); i++) {
-      const unsigned image_idx = storage->opaque[stage].index + i;
+   for (unsigned i = 0; i < num_images; i++) {
+      const unsigned image_idx = var->data.binding + i;
 
       /* Upload the brw_image_param structure.  The order is expected to match
        * the BRW_IMAGE_PARAM_*_OFFSET defines.
@@ -150,6 +150,14 @@ brw_nir_setup_glsl_uniform(gl_shader_stage stage, nir_variable *var,
                            struct brw_stage_prog_data *stage_prog_data,
                            bool is_scalar)
 {
+   if (var->type->without_array()->is_sampler())
+      return;
+
+   if (var->type->without_array()->is_image()) {
+      brw_setup_image_uniform_values(var, stage_prog_data);
+      return;
+   }
+
    /* The data for our (non-builtin) uniforms is stored in a series of
     * gl_uniform_storage structs for each subcomponent that
     * glGetUniformLocation() could name.  We know it's been set up in the same
@@ -162,42 +170,42 @@ brw_nir_setup_glsl_uniform(gl_shader_stage stage, nir_variable *var,
       struct gl_uniform_storage *storage =
          &prog->sh.data->UniformStorage[var->data.location + u];
 
-      if (storage->builtin || storage->type->is_sampler())
+      /* We already handled samplers and images via the separate top-level
+       * variables created by gl_nir_lower_samplers_as_deref(), but they're
+       * still part of the structure's storage, and so we'll see them while
+       * walking it to set up the other regular fields.  Just skip over them.
+       */
+      if (storage->builtin ||
+          storage->type->is_sampler() ||
+          storage->type->is_image())
          continue;
 
-      if (storage->type->is_image()) {
-         brw_setup_image_uniform_values(stage, stage_prog_data,
-                                        uniform_index, storage);
-         uniform_index +=
-            BRW_IMAGE_PARAM_SIZE * MAX2(storage->array_elements, 1);
-      } else {
-         gl_constant_value *components = storage->storage;
-         unsigned vector_count = (MAX2(storage->array_elements, 1) *
-                                  storage->type->matrix_columns);
-         unsigned vector_size = storage->type->vector_elements;
-         unsigned max_vector_size = 4;
-         if (storage->type->base_type == GLSL_TYPE_DOUBLE ||
-             storage->type->base_type == GLSL_TYPE_UINT64 ||
-             storage->type->base_type == GLSL_TYPE_INT64) {
-            vector_size *= 2;
-            if (vector_size > 4)
-               max_vector_size = 8;
-         }
+      gl_constant_value *components = storage->storage;
+      unsigned vector_count = (MAX2(storage->array_elements, 1) *
+                               storage->type->matrix_columns);
+      unsigned vector_size = storage->type->vector_elements;
+      unsigned max_vector_size = 4;
+      if (storage->type->base_type == GLSL_TYPE_DOUBLE ||
+          storage->type->base_type == GLSL_TYPE_UINT64 ||
+          storage->type->base_type == GLSL_TYPE_INT64) {
+         vector_size *= 2;
+         if (vector_size > 4)
+            max_vector_size = 8;
+      }
 
-         for (unsigned s = 0; s < vector_count; s++) {
-            unsigned i;
-            for (i = 0; i < vector_size; i++) {
-               uint32_t idx = components - prog->sh.data->UniformDataSlots;
-               stage_prog_data->param[uniform_index++] = BRW_PARAM_UNIFORM(idx);
-               components++;
-            }
+      for (unsigned s = 0; s < vector_count; s++) {
+         unsigned i;
+         for (i = 0; i < vector_size; i++) {
+            uint32_t idx = components - prog->sh.data->UniformDataSlots;
+            stage_prog_data->param[uniform_index++] = BRW_PARAM_UNIFORM(idx);
+            components++;
+         }
 
-            if (!is_scalar) {
-               /* Pad out with zeros if needed (only needed for vec4) */
-               for (; i < max_vector_size; i++) {
-                  stage_prog_data->param[uniform_index++] =
-                     BRW_PARAM_BUILTIN_ZERO;
-               }
+         if (!is_scalar) {
+            /* Pad out with zeros if needed (only needed for vec4) */
+            for (; i < max_vector_size; i++) {
+               stage_prog_data->param[uniform_index++] =
+                  BRW_PARAM_BUILTIN_ZERO;
             }
          }
       }
@@ -325,8 +333,10 @@ brw_nir_lower_gl_images(nir_shader *shader,
          case nir_intrinsic_image_deref_load:
          case nir_intrinsic_image_deref_store:
          case nir_intrinsic_image_deref_atomic_add:
-         case nir_intrinsic_image_deref_atomic_min:
-         case nir_intrinsic_image_deref_atomic_max:
+         case nir_intrinsic_image_deref_atomic_imin:
+         case nir_intrinsic_image_deref_atomic_umin:
+         case nir_intrinsic_image_deref_atomic_imax:
+         case nir_intrinsic_image_deref_atomic_umax:
          case nir_intrinsic_image_deref_atomic_and:
          case nir_intrinsic_image_deref_atomic_or:
          case nir_intrinsic_image_deref_atomic_xor:
@@ -347,7 +357,7 @@ brw_nir_lower_gl_images(nir_shader *shader,
             b.cursor = nir_before_instr(&intrin->instr);
             nir_ssa_def *index = nir_iadd(&b, nir_imm_int(&b, image_var_idx),
                                           get_aoa_deref_offset(&b, deref, 1));
-            brw_nir_rewrite_image_intrinsic(intrin, index);
+            nir_rewrite_image_intrinsic(intrin, index, false);
             break;
          }
 
@@ -387,3 +397,60 @@ brw_nir_lower_gl_images(nir_shader *shader,
       }
    }
 }
+
+void
+brw_nir_lower_legacy_clipping(nir_shader *nir, int nr_userclip_plane_consts,
+                              struct brw_stage_prog_data *prog_data)
+{
+   if (nr_userclip_plane_consts == 0)
+      return;
+
+   nir_function_impl *impl = nir_shader_get_entrypoint(nir);
+
+   nir_lower_clip_vs(nir, (1 << nr_userclip_plane_consts) - 1, true, false,
+                     NULL);
+   nir_lower_io_to_temporaries(nir, impl, true, false);
+   nir_lower_global_vars_to_local(nir);
+   nir_lower_vars_to_ssa(nir);
+
+   const unsigned clip_plane_base = nir->num_uniforms;
+
+   assert(nir->num_uniforms == prog_data->nr_params * 4);
+   const unsigned num_clip_floats = 4 * nr_userclip_plane_consts;
+   uint32_t *clip_param =
+      brw_stage_prog_data_add_params(prog_data, num_clip_floats);
+   nir->num_uniforms += num_clip_floats * sizeof(float);
+   assert(nir->num_uniforms == prog_data->nr_params * 4);
+
+   for (unsigned i = 0; i < num_clip_floats; i++)
+      clip_param[i] = BRW_PARAM_BUILTIN_CLIP_PLANE(i / 4, i % 4);
+
+   nir_builder b;
+   nir_builder_init(&b, impl);
+   nir_foreach_block(block, impl) {
+      nir_foreach_instr_safe(instr, block) {
+         if (instr->type != nir_instr_type_intrinsic)
+            continue;
+
+         nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
+         if (intrin->intrinsic != nir_intrinsic_load_user_clip_plane)
+            continue;
+
+         b.cursor = nir_before_instr(instr);
+
+         nir_intrinsic_instr *load =
+            nir_intrinsic_instr_create(nir, nir_intrinsic_load_uniform);
+         load->num_components = 4;
+         load->src[0] = nir_src_for_ssa(nir_imm_int(&b, 0));
+         nir_ssa_dest_init(&load->instr, &load->dest, 4, 32, NULL);
+         nir_intrinsic_set_base(load, clip_plane_base + 4 * sizeof(float) *
+                                      nir_intrinsic_ucp_id(intrin));
+         nir_intrinsic_set_range(load, 4 * sizeof(float));
+         nir_builder_instr_insert(&b, &load->instr);
+
+         nir_ssa_def_rewrite_uses(&intrin->dest.ssa,
+                                  nir_src_for_ssa(&load->dest.ssa));
+         nir_instr_remove(instr);
+      }
+   }
+}