nir: add a strip parameter to nir_serialize
[mesa.git] / src / gallium / drivers / radeonsi / si_shader_nir.c
index eeb27b66873d61ddc8179bd16e007e2298df02de..e97e5ccb07b2653806ee8c9c103fe9f6c75814e5 100644 (file)
@@ -777,90 +777,14 @@ 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->msaa_images_declared = u_bit_consecutive(0, nir->info.last_msaa_image + 1);
+       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 +818,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,16 +987,23 @@ 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);
 
        NIR_PASS_V(sel->nir, nir_lower_bool_to_int32);
-
-       /* Strip the resulting shader so that the shader cache is more likely
-        * to hit from other similar shaders.
-        */
-       nir_strip(sel->nir);
 }
 
 static void declare_nir_input_vs(struct si_shader_context *ctx,
@@ -1127,7 +1058,7 @@ si_nir_load_sampler_desc(struct ac_shader_abi *abi,
        unsigned const_index = base_index + constant_index;
 
        assert(!descriptor_set);
-       assert(!image || desc_type == AC_DESC_IMAGE || desc_type == AC_DESC_BUFFER);
+       assert(desc_type <= AC_DESC_BUFFER);
 
        if (bindless) {
                LLVMValueRef list =
@@ -1135,11 +1066,14 @@ si_nir_load_sampler_desc(struct ac_shader_abi *abi,
 
                /* dynamic_index is the bindless handle */
                if (image) {
-                       /* For simplicity, bindless image descriptors use fixed
-                        * 16-dword slots for now.
-                        */
+                       /* Bindless image descriptors use 16-dword slots. */
                        dynamic_index = LLVMBuildMul(ctx->ac.builder, dynamic_index,
                                             LLVMConstInt(ctx->i64, 2, 0), "");
+                       /* FMASK is right after the image. */
+                       if (desc_type == AC_DESC_FMASK) {
+                               dynamic_index = LLVMBuildAdd(ctx->ac.builder, dynamic_index,
+                                                            ctx->i32_1, "");
+                       }
 
                        return si_load_image_desc(ctx, list, dynamic_index, desc_type,
                                                  write, true);
@@ -1178,14 +1112,19 @@ si_nir_load_sampler_desc(struct ac_shader_abi *abi,
        }
 
        if (image) {
+               /* FMASKs are separate from images. */
+               if (desc_type == AC_DESC_FMASK) {
+                       index = LLVMBuildAdd(ctx->ac.builder, index,
+                                            LLVMConstInt(ctx->i32, SI_NUM_IMAGES, 0), "");
+               }
                index = LLVMBuildSub(ctx->ac.builder,
-                                    LLVMConstInt(ctx->i32, SI_NUM_IMAGES - 1, 0),
+                                    LLVMConstInt(ctx->i32, SI_NUM_IMAGE_SLOTS - 1, 0),
                                     index, "");
                return si_load_image_desc(ctx, list, index, desc_type, write, false);
        }
 
        index = LLVMBuildAdd(ctx->ac.builder, index,
-                            LLVMConstInt(ctx->i32, SI_NUM_IMAGES / 2, 0), "");
+                            LLVMConstInt(ctx->i32, SI_NUM_IMAGE_SLOTS / 2, 0), "");
        return si_load_sampler_desc(ctx, list, index, desc_type);
 }