radeonsi: fix GLSL imageSamples()
[mesa.git] / src / gallium / drivers / radeonsi / si_shader_nir.c
index 21de12a043f5662dbc4a51a6e26acf8d70221a9e..3bf30c724363b29a75b6c760e071d95cd00005ea 100644 (file)
@@ -777,90 +777,13 @@ void si_nir_scan_shader(const struct nir_shader *nir,
        info->num_inputs = nir->num_inputs;
        info->num_outputs = nir->num_outputs;
 
-       struct set *ubo_set = _mesa_set_create(NULL, _mesa_hash_pointer,
-                                              _mesa_key_pointer_equal);
-       struct set *ssbo_set = _mesa_set_create(NULL, _mesa_hash_pointer,
-                                               _mesa_key_pointer_equal);
-
-       /* Intialise const_file_max[0] */
-       info->const_file_max[0] = -1;
-
-       /* The first 8 are reserved for atomic counters using ssbo */
-       unsigned ssbo_idx = 8;
-
-       unsigned ubo_idx = 1;
-       nir_foreach_variable(variable, &nir->uniforms) {
-               const struct glsl_type *type = variable->type;
-               enum glsl_base_type base_type =
-                       glsl_get_base_type(glsl_without_array(type));
-               unsigned aoa_size = MAX2(1, glsl_get_aoa_size(type));
-               unsigned loc = variable->data.driver_location / 4;
-               int slot_count = glsl_count_attribute_slots(type, false);
-               int max_slot = MAX2(info->const_file_max[0], (int) loc) + slot_count;
-
-               /* Gather buffers declared bitmasks. Note: radeonsi doesn't
-                * really use the mask (other than ubo_idx == 1 for regular
-                * uniforms) its really only used for getting the buffer count
-                * so we don't need to worry about the ordering.
-                */
-               if (variable->interface_type != NULL) {
-                       if (variable->data.mode == nir_var_uniform ||
-                           variable->data.mode == nir_var_mem_ubo ||
-                           variable->data.mode == nir_var_mem_ssbo) {
-
-                               struct set *buf_set = variable->data.mode == nir_var_mem_ssbo ?
-                                       ssbo_set : ubo_set;
-
-                               unsigned block_count;
-                               if (base_type != GLSL_TYPE_INTERFACE) {
-                                       struct set_entry *entry =
-                                               _mesa_set_search(buf_set, variable->interface_type);
-
-                                       /* Check if we have already processed
-                                        * a member from this ubo.
-                                        */
-                                       if (entry)
-                                               continue;
-
-                                       block_count = 1;
-                               } else {
-                                       block_count = aoa_size;
-                               }
-
-                               if (variable->data.mode == nir_var_uniform ||
-                                   variable->data.mode == nir_var_mem_ubo) {
-                                       info->const_buffers_declared |= u_bit_consecutive(ubo_idx, block_count);
-                                       ubo_idx += block_count;
-                               } else {
-                                       assert(variable->data.mode == nir_var_mem_ssbo);
-
-                                       info->shader_buffers_declared |= u_bit_consecutive(ssbo_idx, block_count);
-                                       ssbo_idx += block_count;
-                               }
-
-                               _mesa_set_add(buf_set, variable->interface_type);
-                       }
-
-                       continue;
-               }
-
-               /* We rely on the fact that nir_lower_samplers_as_deref has
-                * eliminated struct dereferences.
-                */
-               if (base_type == GLSL_TYPE_SAMPLER && !variable->data.bindless) {
-                       info->samplers_declared |=
-                               u_bit_consecutive(variable->data.binding, aoa_size);
-               } else if (base_type == GLSL_TYPE_IMAGE && !variable->data.bindless) {
-                       info->images_declared |=
-                               u_bit_consecutive(variable->data.binding, aoa_size);
-               } else if (base_type != GLSL_TYPE_ATOMIC_UINT) {
-                       info->const_buffers_declared |= 1;
-                       info->const_file_max[0] = max_slot;
-               }
-       }
-
-       _mesa_set_destroy(ubo_set, NULL);
-       _mesa_set_destroy(ssbo_set, NULL);
+       info->const_file_max[0] = nir->num_uniforms - 1;
+       info->shader_buffers_declared = u_bit_consecutive(0, nir->info.num_ssbos);
+       info->const_buffers_declared = u_bit_consecutive(1, nir->info.num_ubos);
+       if (nir->num_uniforms > 0)
+               info->const_buffers_declared |= 1;
+       info->images_declared = u_bit_consecutive(0, nir->info.num_images);
+       info->samplers_declared = nir->info.textures_used;
 
        info->num_written_clipdistance = nir->info.clip_distance_array_size;
        info->num_written_culldistance = nir->info.cull_distance_array_size;
@@ -894,7 +817,7 @@ si_nir_opts(struct nir_shader *nir)
                NIR_PASS(progress, nir, nir_opt_copy_prop_vars);
                NIR_PASS(progress, nir, nir_opt_dead_write_vars);
 
-               NIR_PASS_V(nir, nir_lower_alu_to_scalar, NULL);
+               NIR_PASS_V(nir, nir_lower_alu_to_scalar, NULL, NULL);
                NIR_PASS_V(nir, nir_lower_phis_to_scalar);
 
                /* (Constant) copy propagation is needed for txf with offsets. */
@@ -1063,6 +986,18 @@ void si_lower_nir(struct si_shader_selector *sel)
        };
        NIR_PASS_V(sel->nir, nir_lower_subgroups, &subgroups_options);
 
+       /* Lower load constants to scalar and then clean up the mess */
+       NIR_PASS_V(sel->nir, nir_lower_load_const_to_scalar);
+       NIR_PASS_V(sel->nir, nir_lower_var_copies);
+       si_nir_opts(sel->nir);
+
+       /* Lower large variables that are always constant with load_constant
+        * intrinsics, which get turned into PC-relative loads from a data
+        * section next to the shader.
+        */
+       NIR_PASS_V(sel->nir, nir_opt_large_constants,
+                  glsl_get_natural_size_align_bytes, 16);
+
        ac_lower_indirect_derefs(sel->nir, sel->screen->info.chip_class);
 
        si_nir_opts(sel->nir);
@@ -1088,7 +1023,6 @@ si_nir_lookup_interp_param(struct ac_shader_abi *abi,
                           enum glsl_interp_mode interp, unsigned location)
 {
        struct si_shader_context *ctx = si_shader_context_from_abi(abi);
-       int interp_param_idx = -1;
 
        switch (interp) {
        case INTERP_MODE_FLAT:
@@ -1096,27 +1030,24 @@ si_nir_lookup_interp_param(struct ac_shader_abi *abi,
        case INTERP_MODE_SMOOTH:
        case INTERP_MODE_NONE:
                if (location == INTERP_CENTER)
-                       interp_param_idx = SI_PARAM_PERSP_CENTER;
+                       return ctx->abi.persp_center;
                else if (location == INTERP_CENTROID)
-                       interp_param_idx = SI_PARAM_PERSP_CENTROID;
+                       return ctx->abi.persp_centroid;
                else if (location == INTERP_SAMPLE)
-                       interp_param_idx = SI_PARAM_PERSP_SAMPLE;
+                       return ctx->abi.persp_sample;
                break;
        case INTERP_MODE_NOPERSPECTIVE:
                if (location == INTERP_CENTER)
-                       interp_param_idx = SI_PARAM_LINEAR_CENTER;
+                       return ctx->abi.linear_center;
                else if (location == INTERP_CENTROID)
-                       interp_param_idx = SI_PARAM_LINEAR_CENTROID;
+                       return ctx->abi.linear_centroid;
                else if (location == INTERP_SAMPLE)
-                       interp_param_idx = SI_PARAM_LINEAR_SAMPLE;
+                       return ctx->abi.linear_sample;
                break;
        default:
                assert(!"Unhandled interpolation mode.");
-               return NULL;
        }
-
-       return interp_param_idx != -1 ?
-               LLVMGetParam(ctx->main_fn, interp_param_idx) : NULL;
+       return NULL;
 }
 
 static LLVMValueRef