diff options
-rw-r--r-- | src/gallium/drivers/freedreno/ir3/ir3.c | 17 | ||||
-rw-r--r-- | src/gallium/drivers/freedreno/ir3/ir3.h | 17 | ||||
-rw-r--r-- | src/gallium/drivers/freedreno/ir3/ir3_sched.c | 8 |
3 files changed, 23 insertions, 19 deletions
diff --git a/src/gallium/drivers/freedreno/ir3/ir3.c b/src/gallium/drivers/freedreno/ir3/ir3.c index 01cdd8ad57a..25d7c7af065 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3.c +++ b/src/gallium/drivers/freedreno/ir3/ir3.c @@ -588,21 +588,10 @@ static void insert_instr(struct ir3 *shader, static uint32_t serialno = 0; instr->serialno = ++serialno; #endif - if (shader->instrs_count == shader->instrs_sz) { - shader->instrs_sz = MAX2(2 * shader->instrs_sz, 16); - shader->instrs = realloc(shader->instrs, - shader->instrs_sz * sizeof(shader->instrs[0])); - } - shader->instrs[shader->instrs_count++] = instr; + array_insert(shader->instrs, instr); - if (is_input(instr)) { - if (shader->baryfs_count == shader->baryfs_sz) { - shader->baryfs_sz = MAX2(2 * shader->baryfs_sz, 16); - shader->baryfs = realloc(shader->baryfs, - shader->baryfs_sz * sizeof(shader->baryfs[0])); - } - shader->baryfs[shader->baryfs_count++] = instr; - } + if (is_input(instr)) + array_insert(shader->baryfs, instr); } struct ir3_block * ir3_block_create(struct ir3 *shader, diff --git a/src/gallium/drivers/freedreno/ir3/ir3.h b/src/gallium/drivers/freedreno/ir3/ir3.h index 430bcf22d6f..fa866a29850 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3.h +++ b/src/gallium/drivers/freedreno/ir3/ir3.h @@ -38,8 +38,6 @@ struct ir3; struct ir3_instruction; struct ir3_block; -struct ir3 * fd_asm_parse(const char *src); - struct ir3_info { uint16_t sizedwords; uint16_t instrs_count; /* expanded to account for rpt's */ @@ -313,8 +311,16 @@ struct ir3_heap_chunk; struct ir3 { unsigned instrs_count, instrs_sz; struct ir3_instruction **instrs; + + /* Track bary.f (and ldlv) instructions.. this is needed in + * scheduling to ensure that all varying fetches happen before + * any potential kill instructions. The hw gets grumpy if all + * threads in a group are killed before the last bary.f gets + * a chance to signal end of input (ei). + */ unsigned baryfs_count, baryfs_sz; struct ir3_instruction **baryfs; + struct ir3_block *block; unsigned heap_idx; struct ir3_heap_chunk *chunk; @@ -503,6 +509,13 @@ static inline bool reg_gpr(struct ir3_register *r) return true; } +#define array_insert(arr, val) do { \ + if (arr ## _count == arr ## _sz) { \ + arr ## _sz = MAX2(2 * arr ## _sz, 16); \ + arr = realloc(arr, arr ## _sz * sizeof(arr[0])); \ + } \ + arr[arr ##_count++] = val; \ + } while (0) /* iterator for an instructions's sources (reg), also returns src #: */ #define foreach_src_n(__srcreg, __n, __instr) \ diff --git a/src/gallium/drivers/freedreno/ir3/ir3_sched.c b/src/gallium/drivers/freedreno/ir3/ir3_sched.c index 909ecc23449..7938c1f9bea 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_sched.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_sched.c @@ -199,7 +199,8 @@ static unsigned delay_calc(struct ir3_sched_ctx *ctx, } /* A negative return value signals that an instruction has been newly - * scheduled, return back up to the top of the stack (to block_sched()) + * SCHEDULED (or DELAYED due to address or predicate register already + * in use), return back up to the top of the stack (to block_sched()) */ static int trysched(struct ir3_sched_ctx *ctx, struct ir3_instruction *instr) @@ -252,9 +253,10 @@ static int trysched(struct ir3_sched_ctx *ctx, unsigned i; for (i = 0; i < ir->baryfs_count; i++) { - if (ir->baryfs[i]->depth == DEPTH_UNUSED) + struct ir3_instruction *baryf = ir->baryfs[i]; + if (baryf->depth == DEPTH_UNUSED) continue; - delay = trysched(ctx, ir->baryfs[i]); + delay = trysched(ctx, baryf); if (delay) return delay; } |