freedreno/ir3: handle input/output component
authorRob Clark <robdclark@gmail.com>
Tue, 5 Dec 2017 13:40:18 +0000 (08:40 -0500)
committerRob Clark <robdclark@gmail.com>
Tue, 5 Dec 2017 21:03:38 +0000 (16:03 -0500)
After the mesa/st nir linking support, we start to see inputs/outputs
like:

   decl_var shader_out INTERP_MODE_NONE float packed:uv (VARYING_SLOT_VAR9.x, 1, 0)
   decl_var shader_out INTERP_MODE_NONE float packed:uv@0 (VARYING_SLOT_VAR9.y, 1, 0)

(ie. were location_frac != .x)

Unfortunately I overlooked the addition of the component parameter to
load_input/store_output, so when we started encountering inputs/outputs
with component other than .x, we'd end up loading/storing the wrong
input/output.

Signed-off-by: Rob Clark <robdclark@gmail.com>
src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c

index c97df4f1d63d1d2d9225e57d7060037a18c386ad..15a3aa4c8026cef07110a2d9244de132296340c4 100644 (file)
@@ -1928,7 +1928,7 @@ emit_intrinsic(struct ir3_context *ctx, nir_intrinsic_instr *intr)
        struct ir3_instruction * const *src;
        struct ir3_block *b = ctx->block;
        nir_const_value *const_offset;
-       int idx;
+       int idx, comp;
 
        if (info->has_dest) {
                unsigned n;
@@ -1971,11 +1971,12 @@ emit_intrinsic(struct ir3_context *ctx, nir_intrinsic_instr *intr)
                break;
        case nir_intrinsic_load_input:
                idx = nir_intrinsic_base(intr);
+               comp = nir_intrinsic_component(intr);
                const_offset = nir_src_as_const_value(intr->src[0]);
                if (const_offset) {
                        idx += const_offset->u32[0];
                        for (int i = 0; i < intr->num_components; i++) {
-                               unsigned n = idx * 4 + i;
+                               unsigned n = idx * 4 + i + comp;
                                dst[i] = ctx->ir->inputs[n];
                        }
                } else {
@@ -1984,7 +1985,7 @@ emit_intrinsic(struct ir3_context *ctx, nir_intrinsic_instr *intr)
                                        create_collect(b, ctx->ir->inputs, ctx->ir->ninputs);
                        struct ir3_instruction *addr = get_addr(ctx, src[0], 4);
                        for (int i = 0; i < intr->num_components; i++) {
-                               unsigned n = idx * 4 + i;
+                               unsigned n = idx * 4 + i + comp;
                                dst[i] = create_indirect_load(ctx, ctx->ir->ninputs,
                                                n, addr, collect);
                        }
@@ -2061,13 +2062,14 @@ emit_intrinsic(struct ir3_context *ctx, nir_intrinsic_instr *intr)
                break;
        case nir_intrinsic_store_output:
                idx = nir_intrinsic_base(intr);
+               comp = nir_intrinsic_component(intr);
                const_offset = nir_src_as_const_value(intr->src[1]);
                compile_assert(ctx, const_offset != NULL);
                idx += const_offset->u32[0];
 
                src = get_src(ctx, &intr->src[0]);
                for (int i = 0; i < intr->num_components; i++) {
-                       unsigned n = idx * 4 + i;
+                       unsigned n = idx * 4 + i + comp;
                        ctx->ir->outputs[n] = src[i];
                }
                break;