nir: Drop imov/fmov in favor of one mov instruction
[mesa.git] / src / freedreno / ir3 / ir3_context.c
index d121559833b7f5cfb615886c32bf70aea5c539c9..7cd87de0f29d06bbd7307c6eea577d31b85acf86 100644 (file)
  *    Rob Clark <robclark@freedesktop.org>
  */
 
-#include "util/u_math.h"
-
 #include "ir3_compiler.h"
 #include "ir3_context.h"
+#include "ir3_image.h"
 #include "ir3_shader.h"
 #include "ir3_nir.h"
 
@@ -52,7 +51,9 @@ ir3_context_init(struct ir3_compiler *compiler,
                }
        }
 
-       if (compiler->gpu_id >= 400) {
+       if (compiler->gpu_id >= 600) {
+               ctx->funcs = &ir3_a6xx_funcs;
+       } else if (compiler->gpu_id >= 400) {
                ctx->funcs = &ir3_a4xx_funcs;
        }
 
@@ -98,67 +99,7 @@ ir3_context_init(struct ir3_compiler *compiler,
                nir_print_shader(ctx->s, stderr);
        }
 
-       ir3_nir_scan_driver_consts(ctx->s, &so->const_layout);
-
-       so->num_uniforms = ctx->s->num_uniforms;
-       so->num_ubos = ctx->s->info.num_ubos;
-
-       /* Layout of constant registers, each section aligned to vec4.  Note
-        * that pointer size (ubo, etc) changes depending on generation.
-        *
-        *    user consts
-        *    UBO addresses
-        *    SSBO sizes
-        *    if (vertex shader) {
-        *        driver params (IR3_DP_*)
-        *        if (stream_output.num_outputs > 0)
-        *           stream-out addresses
-        *    }
-        *    immediates
-        *
-        * Immediates go last mostly because they are inserted in the CP pass
-        * after the nir -> ir3 frontend.
-        */
-       unsigned constoff = align(ctx->s->num_uniforms, 4);
-       unsigned ptrsz = ir3_pointer_size(ctx);
-
-       memset(&so->constbase, ~0, sizeof(so->constbase));
-
-       if (so->num_ubos > 0) {
-               so->constbase.ubo = constoff;
-               constoff += align(ctx->s->info.num_ubos * ptrsz, 4) / 4;
-       }
-
-       if (so->const_layout.ssbo_size.count > 0) {
-               unsigned cnt = so->const_layout.ssbo_size.count;
-               so->constbase.ssbo_sizes = constoff;
-               constoff += align(cnt, 4) / 4;
-       }
-
-       if (so->const_layout.image_dims.count > 0) {
-               unsigned cnt = so->const_layout.image_dims.count;
-               so->constbase.image_dims = constoff;
-               constoff += align(cnt, 4) / 4;
-       }
-
-       unsigned num_driver_params = 0;
-       if (so->type == MESA_SHADER_VERTEX) {
-               num_driver_params = IR3_DP_VS_COUNT;
-       } else if (so->type == MESA_SHADER_COMPUTE) {
-               num_driver_params = IR3_DP_CS_COUNT;
-       }
-
-       so->constbase.driver_param = constoff;
-       constoff += align(num_driver_params, 4) / 4;
-
-       if ((so->type == MESA_SHADER_VERTEX) &&
-                       (compiler->gpu_id < 500) &&
-                       so->shader->stream_output.num_outputs > 0) {
-               so->constbase.tfbo = constoff;
-               constoff += align(IR3_MAX_SO_BUFFERS * ptrsz, 4) / 4;
-       }
-
-       so->constbase.immediate = constoff;
+       ir3_ibo_mapping_init(&so->image_mapping, ctx->s->info.num_textures);
 
        return ctx;
 }
@@ -237,10 +178,22 @@ ir3_get_src(struct ir3_context *ctx, nir_src *src)
 }
 
 void
-put_dst(struct ir3_context *ctx, nir_dest *dst)
+ir3_put_dst(struct ir3_context *ctx, nir_dest *dst)
 {
        unsigned bit_size = nir_dest_bit_size(*dst);
 
+       /* add extra mov if dst value is HIGH reg.. in some cases not all
+        * instructions can read from HIGH regs, in cases where they can
+        * ir3_cp will clean up the extra mov:
+        */
+       for (unsigned i = 0; i < ctx->last_dst_n; i++) {
+               if (!ctx->last_dst[i])
+                       continue;
+               if (ctx->last_dst[i]->regs[0]->flags & IR3_REG_HIGH) {
+                       ctx->last_dst[i] = ir3_MOV(ctx->block, ctx->last_dst[i], TYPE_U32);
+               }
+       }
+
        if (bit_size < 32) {
                for (unsigned i = 0; i < ctx->last_dst_n; i++) {
                        struct ir3_instruction *dst = ctx->last_dst[i];
@@ -270,6 +223,7 @@ put_dst(struct ir3_context *ctx, nir_dest *dst)
 
                ralloc_free(ctx->last_dst);
        }
+
        ctx->last_dst = NULL;
        ctx->last_dst_n = 0;
 }
@@ -324,6 +278,8 @@ ir3_create_collect(struct ir3_context *ctx, struct ir3_instruction *const *arr,
                ir3_reg_create(collect, 0, IR3_REG_SSA | flags)->instr = elem;
        }
 
+       collect->regs[0]->wrmask = MASK(arrsz);
+
        return collect;
 }
 
@@ -341,10 +297,12 @@ ir3_split_dest(struct ir3_block *block, struct ir3_instruction **dst,
                return;
        }
 
+       unsigned flags = src->regs[0]->flags & (IR3_REG_HALF | IR3_REG_HIGH);
+
        for (int i = 0, j = 0; i < n; i++) {
                struct ir3_instruction *split = ir3_instr_create(block, OPC_META_FO);
-               ir3_reg_create(split, 0, IR3_REG_SSA);
-               ir3_reg_create(split, 0, IR3_REG_SSA)->instr = src;
+               ir3_reg_create(split, 0, IR3_REG_SSA | flags);
+               ir3_reg_create(split, 0, IR3_REG_SSA | flags)->instr = src;
                split->fo.off = i + base;
 
                if (prev) {
@@ -360,7 +318,7 @@ ir3_split_dest(struct ir3_block *block, struct ir3_instruction **dst,
        }
 }
 
-void
+NORETURN void
 ir3_context_error(struct ir3_context *ctx, const char *format, ...)
 {
        struct hash_table *errors = NULL;
@@ -379,7 +337,7 @@ ir3_context_error(struct ir3_context *ctx, const char *format, ...)
        nir_print_shader_annotated(ctx->s, stdout, errors);
        ralloc_free(errors);
        ctx->error = true;
-       debug_assert(0);
+       unreachable("");
 }
 
 static struct ir3_instruction *