freedreno/ir3: add generic get_barycentric()
[mesa.git] / src / freedreno / ir3 / ir3_compiler_nir.c
index 91ef00b9c92a32f80cfad0820df4eac2f3c63be5..096611a297504f0eb3c577727ace91730e6cf5df 100644 (file)
@@ -98,7 +98,7 @@ create_frag_input(struct ir3_context *ctx, bool use_ldlv, unsigned n)
                instr->cat6.type = TYPE_U32;
                instr->cat6.iim_val = 1;
        } else {
-               instr = ir3_BARY_F(block, inloc, 0, ctx->ij_pixel, 0);
+               instr = ir3_BARY_F(block, inloc, 0, ctx->ij[IJ_PERSP_PIXEL], 0);
                instr->regs[2]->wrmask = 0x3;
        }
 
@@ -110,7 +110,7 @@ create_driver_param(struct ir3_context *ctx, enum ir3_driver_param dp)
 {
        /* first four vec4 sysval's reserved for UBOs: */
        /* NOTE: dp is in scalar, but there can be >4 dp components: */
-       struct ir3_const_state *const_state = &ctx->so->shader->const_state;
+       struct ir3_const_state *const_state = ir3_const_state(ctx->so);
        unsigned n = const_state->offsets.driver_param;
        unsigned r = regid(n + dp / 4, dp % 4);
        return create_uniform(ctx->block, r);
@@ -772,7 +772,7 @@ emit_intrinsic_load_ubo(struct ir3_context *ctx, nir_intrinsic_instr *intr,
 {
        struct ir3_block *b = ctx->block;
        struct ir3_instruction *base_lo, *base_hi, *addr, *src0, *src1;
-       struct ir3_const_state *const_state = &ctx->so->shader->const_state;
+       const struct ir3_const_state *const_state = ir3_const_state(ctx->so);
        unsigned ubo = regid(const_state->offsets.ubo, 0);
        const unsigned ptrsz = ir3_pointer_size(ctx->compiler);
 
@@ -848,7 +848,7 @@ emit_intrinsic_ssbo_size(struct ir3_context *ctx, nir_intrinsic_instr *intr,
                struct ir3_instruction **dst)
 {
        /* SSBO size stored as a const starting at ssbo_sizes: */
-       struct ir3_const_state *const_state = &ctx->so->shader->const_state;
+       const struct ir3_const_state *const_state = ir3_const_state(ctx->so);
        unsigned blk_idx = nir_src_as_uint(intr->src[0]);
        unsigned idx = regid(const_state->offsets.ssbo_sizes, 0) +
                const_state->ssbo_size.off[blk_idx];
@@ -1219,7 +1219,8 @@ emit_intrinsic_image_size_tex(struct ir3_context *ctx, nir_intrinsic_instr *intr
                 * bytes-per-pixel should have been emitted in 2nd slot of
                 * image_dims. See ir3_shader::emit_image_dims().
                 */
-               struct ir3_const_state *const_state = &ctx->so->shader->const_state;
+               const struct ir3_const_state *const_state =
+                               ir3_const_state(ctx->so);
                unsigned cb = regid(const_state->offsets.image_dims, 0) +
                        const_state->image_dims.off[nir_src_as_uint(intr->src[0])];
                struct ir3_instruction *aux = create_uniform(b, cb + 1);
@@ -1345,44 +1346,47 @@ create_sysval_input(struct ir3_context *ctx, gl_system_value slot,
 }
 
 static struct ir3_instruction *
-get_barycentric_centroid(struct ir3_context *ctx)
+get_barycentric(struct ir3_context *ctx, enum ir3_bary bary)
 {
-       if (!ctx->ij_centroid) {
+       static const gl_system_value sysval_base = SYSTEM_VALUE_BARYCENTRIC_PERSP_PIXEL;
+
+       STATIC_ASSERT(sysval_base + IJ_PERSP_PIXEL == SYSTEM_VALUE_BARYCENTRIC_PERSP_PIXEL);
+       STATIC_ASSERT(sysval_base + IJ_PERSP_SAMPLE == SYSTEM_VALUE_BARYCENTRIC_PERSP_SAMPLE);
+       STATIC_ASSERT(sysval_base + IJ_PERSP_CENTROID == SYSTEM_VALUE_BARYCENTRIC_PERSP_CENTROID);
+       STATIC_ASSERT(sysval_base + IJ_PERSP_SIZE == SYSTEM_VALUE_BARYCENTRIC_PERSP_SIZE);
+       STATIC_ASSERT(sysval_base + IJ_LINEAR_PIXEL == SYSTEM_VALUE_BARYCENTRIC_LINEAR_PIXEL);
+       STATIC_ASSERT(sysval_base + IJ_LINEAR_CENTROID == SYSTEM_VALUE_BARYCENTRIC_LINEAR_CENTROID);
+       STATIC_ASSERT(sysval_base + IJ_LINEAR_SAMPLE == SYSTEM_VALUE_BARYCENTRIC_LINEAR_SAMPLE);
+
+       if (!ctx->ij[bary]) {
                struct ir3_instruction *xy[2];
                struct ir3_instruction *ij;
 
-               ij = create_sysval_input(ctx, SYSTEM_VALUE_BARYCENTRIC_PERSP_CENTROID, 0x3);
+               ij = create_sysval_input(ctx, sysval_base + bary, 0x3);
                ir3_split_dest(ctx->block, xy, ij, 0, 2);
 
-               ctx->ij_centroid = ir3_create_collect(ctx, xy, 2);
+               ctx->ij[bary] = ir3_create_collect(ctx, xy, 2);
        }
 
-       return ctx->ij_centroid;
+       return ctx->ij[bary];
 }
 
 static struct ir3_instruction *
-get_barycentric_sample(struct ir3_context *ctx)
+get_barycentric_centroid(struct ir3_context *ctx)
 {
-       if (!ctx->ij_sample) {
-               struct ir3_instruction *xy[2];
-               struct ir3_instruction *ij;
-
-               ij = create_sysval_input(ctx, SYSTEM_VALUE_BARYCENTRIC_PERSP_SAMPLE, 0x3);
-               ir3_split_dest(ctx->block, xy, ij, 0, 2);
-
-               ctx->ij_sample = ir3_create_collect(ctx, xy, 2);
-       }
+       return get_barycentric(ctx, IJ_PERSP_CENTROID);
+}
 
-       return ctx->ij_sample;
+static struct ir3_instruction *
+get_barycentric_sample(struct ir3_context *ctx)
+{
+       return get_barycentric(ctx, IJ_PERSP_SAMPLE);
 }
 
 static struct ir3_instruction  *
 get_barycentric_pixel(struct ir3_context *ctx)
 {
-       /* TODO when tgsi_to_nir supports "new-style" FS inputs switch
-        * this to create ij_pixel only on demand:
-        */
-       return ctx->ij_pixel;
+       return get_barycentric(ctx, IJ_PERSP_PIXEL);
 }
 
 static struct ir3_instruction *
@@ -1435,8 +1439,9 @@ emit_intrinsic(struct ir3_context *ctx, nir_intrinsic_instr *intr)
                dst = NULL;
        }
 
-       const unsigned primitive_param = ctx->so->shader->const_state.offsets.primitive_param * 4;
-       const unsigned primitive_map = ctx->so->shader->const_state.offsets.primitive_map * 4;
+       const struct ir3_const_state *const_state = ir3_const_state(ctx->so);
+       const unsigned primitive_param = const_state->offsets.primitive_param * 4;
+       const unsigned primitive_map = const_state->offsets.primitive_map * 4;
 
        switch (intr->intrinsic) {
        case nir_intrinsic_load_uniform:
@@ -1459,7 +1464,7 @@ emit_intrinsic(struct ir3_context *ctx, nir_intrinsic_instr *intr)
                         * addr reg value can be:
                         */
                        ctx->so->constlen = MAX2(ctx->so->constlen,
-                                       ctx->so->shader->ubo_state.size / 16);
+                                       const_state->ubo_state.size / 16);
                }
                break;
 
@@ -1592,11 +1597,11 @@ emit_intrinsic(struct ir3_context *ctx, nir_intrinsic_instr *intr)
                break;
        }
        case nir_intrinsic_load_size_ir3:
-               if (!ctx->ij_size) {
-                       ctx->ij_size =
+               if (!ctx->ij[IJ_PERSP_SIZE]) {
+                       ctx->ij[IJ_PERSP_SIZE] =
                                create_sysval_input(ctx, SYSTEM_VALUE_BARYCENTRIC_PERSP_SIZE, 0x1);
                }
-               dst[0] = ctx->ij_size;
+               dst[0] = ctx->ij[IJ_PERSP_SIZE];
                break;
        case nir_intrinsic_load_barycentric_centroid:
                ir3_split_dest(b, dst, get_barycentric_centroid(ctx), 0, 2);
@@ -1783,6 +1788,12 @@ emit_intrinsic(struct ir3_context *ctx, nir_intrinsic_instr *intr)
                }
                dst[0] = ctx->basevertex;
                break;
+       case nir_intrinsic_load_draw_id:
+               if (!ctx->draw_id) {
+                       ctx->draw_id = create_driver_param(ctx, IR3_DP_DRAWID);
+               }
+               dst[0] = ctx->draw_id;
+               break;
        case nir_intrinsic_load_base_instance:
                if (!ctx->base_instance) {
                        ctx->base_instance = create_driver_param(ctx, IR3_DP_INSTID_BASE);
@@ -2805,7 +2816,8 @@ emit_stream_out(struct ir3_context *ctx)
         * stripped out in the backend.
         */
        for (unsigned i = 0; i < IR3_MAX_SO_BUFFERS; i++) {
-               struct ir3_const_state *const_state = &ctx->so->shader->const_state;
+               const struct ir3_const_state *const_state =
+                               ir3_const_state(ctx->so);
                unsigned stride = strmout->stride[i];
                struct ir3_instruction *base, *off;
 
@@ -3245,7 +3257,7 @@ emit_instructions(struct ir3_context *ctx)
        ctx->inputs  = rzalloc_array(ctx, struct ir3_instruction *, ctx->ninputs);
        ctx->outputs = rzalloc_array(ctx, struct ir3_instruction *, ctx->noutputs);
 
-       ctx->ir = ir3_create(ctx->compiler, ctx->so->type);
+       ctx->ir = ir3_create(ctx->compiler, ctx->so);
 
        /* Create inputs in first block: */
        ctx->block = get_block(ctx, nir_start_block(fxn));
@@ -3261,7 +3273,7 @@ emit_instructions(struct ir3_context *ctx)
         * tgsi_to_nir)
         */
        if (ctx->so->type == MESA_SHADER_FRAGMENT) {
-               ctx->ij_pixel = create_input(ctx, 0x3);
+               ctx->ij[IJ_PERSP_PIXEL] = create_input(ctx, 0x3);
        }
 
        /* Setup inputs: */
@@ -3272,9 +3284,9 @@ emit_instructions(struct ir3_context *ctx)
        /* Defer add_sysval_input() stuff until after setup_inputs(),
         * because sysvals need to be appended after varyings:
         */
-       if (ctx->ij_pixel) {
+       if (ctx->ij[IJ_PERSP_PIXEL]) {
                add_sysval_input_compmask(ctx, SYSTEM_VALUE_BARYCENTRIC_PERSP_PIXEL,
-                               0x3, ctx->ij_pixel);
+                               0x3, ctx->ij[IJ_PERSP_PIXEL]);
        }