freedreno/ir3: Clean up instrlen setup.
[mesa.git] / src / freedreno / ir3 / ir3_nir_lower_io_offsets.c
index 8e80c40eeb884773815fd9f2b28b06dfd5fd9c54..36c48cf1299c8abf05cc2f17c5fd6fdad27fc1c2 100644 (file)
@@ -132,8 +132,6 @@ ir3_nir_try_propagate_bit_shift(nir_builder *b, nir_ssa_def *offset, int32_t shi
        nir_ssa_def *shift_ssa;
        nir_ssa_def *new_offset = NULL;
 
-       b->cursor = nir_after_instr(&alu->instr);
-
        /* the first src could be something like ssa_18.x, but we only want
         * the single component.  Otherwise the ishl/ishr/ushr could turn
         * into a vec4 operation:
@@ -168,15 +166,23 @@ lower_offset_for_ssbo(nir_intrinsic_instr *intrinsic, nir_builder *b,
                                          unsigned ir3_ssbo_opcode, uint8_t offset_src_idx)
 {
        unsigned num_srcs = nir_intrinsic_infos[intrinsic->intrinsic].num_srcs;
+       int shift = 2;
 
        bool has_dest = nir_intrinsic_infos[intrinsic->intrinsic].has_dest;
        nir_ssa_def *new_dest = NULL;
 
+       /* for 16-bit ssbo access, offset is in 16-bit words instead of dwords */
+       if ((has_dest && intrinsic->dest.ssa.bit_size == 16) ||
+               (!has_dest && intrinsic->src[0].ssa->bit_size == 16))
+               shift = 1;
+
        /* Here we create a new intrinsic and copy over all contents from the old one. */
 
        nir_intrinsic_instr *new_intrinsic;
        nir_src *target_src;
 
+       b->cursor = nir_before_instr(&intrinsic->instr);
+
        /* 'offset_src_idx' holds the index of the source that represent the offset. */
        new_intrinsic =
                nir_intrinsic_instr_create(b->shader, ir3_ssbo_opcode);
@@ -192,7 +198,7 @@ lower_offset_for_ssbo(nir_intrinsic_instr *intrinsic, nir_builder *b,
         * Here we use the convention that shifting right is negative while shifting
         * left is positive. So 'x / 4' ~ 'x >> 2' or 'x << -2'.
         */
-       nir_ssa_def *new_offset = ir3_nir_try_propagate_bit_shift(b, offset, -2);
+       nir_ssa_def *new_offset = ir3_nir_try_propagate_bit_shift(b, offset, -shift);
 
        /* The new source that will hold the dword-offset is always the last
         * one for every intrinsic.
@@ -211,20 +217,17 @@ lower_offset_for_ssbo(nir_intrinsic_instr *intrinsic, nir_builder *b,
        for (unsigned i = 0; i < num_srcs; i++)
                new_intrinsic->src[i] = nir_src_for_ssa(intrinsic->src[i].ssa);
 
-       for (unsigned i = 0; i < NIR_INTRINSIC_MAX_CONST_INDEX; i++)
-               new_intrinsic->const_index[i] = intrinsic->const_index[i];
+       nir_intrinsic_copy_const_indices(new_intrinsic, intrinsic);
 
        new_intrinsic->num_components = intrinsic->num_components;
 
-       b->cursor = nir_before_instr(&intrinsic->instr);
-
        /* If we managed to propagate the division by 4, just use the new offset
         * register and don't emit the SHR.
         */
        if (new_offset)
                offset = new_offset;
        else
-               offset = nir_ushr(b, offset, nir_imm_int(b, 2));
+               offset = nir_ushr(b, offset, nir_imm_int(b, shift));
 
        /* Insert the new intrinsic right before the old one. */
        nir_builder_instr_insert(b, &new_intrinsic->instr);
@@ -251,15 +254,12 @@ lower_offset_for_ssbo(nir_intrinsic_instr *intrinsic, nir_builder *b,
 }
 
 static bool
-lower_offset_for_ubo(nir_intrinsic_instr *intrinsic, nir_builder *b)
+lower_offset_for_ubo(nir_intrinsic_instr *intrinsic, nir_builder *b, int gpu_id)
 {
-       /* We only need to lower offset if using LDC. Currently, we only use LDC
-        * in the bindless mode. Also, LDC is introduced on A6xx, but currently we
-        * only use bindless in turnip which is A6xx only.
-        *
-        * TODO: We should be using LDC always on A6xx+.
+       /* We only need to lower offset if using LDC, which takes an offset in
+        * vec4 units and has the start component baked into the instruction.
         */
-       if (!ir3_bindless_resource(intrinsic->src[0]))
+       if (gpu_id < 600)
                return false;
 
        /* TODO handle other bitsizes, including non-dword-aligned loads */
@@ -271,7 +271,7 @@ lower_offset_for_ubo(nir_intrinsic_instr *intrinsic, nir_builder *b)
                nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_ubo_ir3);
 
        debug_assert(intrinsic->dest.is_ssa);
-       new_intrinsic->src[0] = nir_src_for_ssa(intrinsic->src[0].ssa);
+       new_intrinsic->src[0] = intrinsic->src[0];
 
        nir_ssa_def *offset = intrinsic->src[1].ssa;
        nir_ssa_def *new_offset = ir3_nir_try_propagate_bit_shift(b, offset, -4);
@@ -329,7 +329,7 @@ lower_offset_for_ubo(nir_intrinsic_instr *intrinsic, nir_builder *b)
 }
 
 static bool
-lower_io_offsets_block(nir_block *block, nir_builder *b, void *mem_ctx)
+lower_io_offsets_block(nir_block *block, nir_builder *b, void *mem_ctx, int gpu_id)
 {
        bool progress = false;
 
@@ -341,7 +341,7 @@ lower_io_offsets_block(nir_block *block, nir_builder *b, void *mem_ctx)
 
                /* UBO */
                if (intr->intrinsic == nir_intrinsic_load_ubo) {
-                       progress |= lower_offset_for_ubo(intr, b);
+                       progress |= lower_offset_for_ubo(intr, b, gpu_id);
                        continue;
                }
 
@@ -360,7 +360,7 @@ lower_io_offsets_block(nir_block *block, nir_builder *b, void *mem_ctx)
 }
 
 static bool
-lower_io_offsets_func(nir_function_impl *impl)
+lower_io_offsets_func(nir_function_impl *impl, int gpu_id)
 {
        void *mem_ctx = ralloc_parent(impl);
        nir_builder b;
@@ -368,7 +368,7 @@ lower_io_offsets_func(nir_function_impl *impl)
 
        bool progress = false;
        nir_foreach_block_safe (block, impl) {
-               progress |= lower_io_offsets_block(block, &b, mem_ctx);
+               progress |= lower_io_offsets_block(block, &b, mem_ctx, gpu_id);
        }
 
        if (progress) {
@@ -380,13 +380,13 @@ lower_io_offsets_func(nir_function_impl *impl)
 }
 
 bool
-ir3_nir_lower_io_offsets(nir_shader *shader)
+ir3_nir_lower_io_offsets(nir_shader *shader, int gpu_id)
 {
        bool progress = false;
 
        nir_foreach_function (function, shader) {
                if (function->impl)
-                       progress |= lower_io_offsets_func(function->impl);
+                       progress |= lower_io_offsets_func(function->impl, gpu_id);
        }
 
        return progress;