From: Alyssa Rosenzweig Date: Thu, 18 Feb 2021 14:49:57 +0000 (-0500) Subject: pan/bi: Materialize *DTSEL_IMM in the scheduler X-Git-Tag: upstream/21.2.3~7622 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1c495323ce137e0201dca58b299f10db41276752;p=platform%2Fupstream%2Fmesa.git pan/bi: Materialize *DTSEL_IMM in the scheduler We want to be able to set a descriptor table and have the instruction pair "magically" come to be. To do so, we adjust the definition of DTSEL_IMM (deviating a bit from the architectural definition but in practice simplifying disassembly immensely) and add a scheduler lowering. This ensures DTSEL is always paired correctly. Signed-off-by: Alyssa Rosenzweig Part-of: --- diff --git a/src/panfrost/bifrost/ISA.xml b/src/panfrost/bifrost/ISA.xml index 6b3bd69..e974f72 100644 --- a/src/panfrost/bifrost/ISA.xml +++ b/src/panfrost/bifrost/ISA.xml @@ -606,9 +606,14 @@ - + - + + attribute_1 + attribute_2 + none + flat + diff --git a/src/panfrost/bifrost/bi_printer.c.py b/src/panfrost/bifrost/bi_printer.c.py index 1175e82..5692633 100644 --- a/src/panfrost/bifrost/bi_printer.c.py +++ b/src/panfrost/bifrost/bi_printer.c.py @@ -163,6 +163,9 @@ bi_print_instr(bi_instr *I, FILE *fp) fprintf(fp, " = %s", bi_opcode_props[I->op].name); + if (I->table) + fprintf(fp, ".%s", bi_table_as_str(I->table)); + switch (I->op) { % for opcode in ops: <% diff --git a/src/panfrost/bifrost/bi_schedule.c b/src/panfrost/bifrost/bi_schedule.c index 61e492e..049d73e 100644 --- a/src/panfrost/bifrost/bi_schedule.c +++ b/src/panfrost/bifrost/bi_schedule.c @@ -113,6 +113,42 @@ struct bi_clause_state { struct bi_const_state consts[8]; }; +/* Determines messsage type by checking the table and a few special cases. Only + * case missing is tilebuffer instructions that access depth/stencil, which + * require a Z_STENCIL message (to implement + * ARM_shader_framebuffer_fetch_depth_stencil) */ + +static enum bifrost_message_type +bi_message_type_for_instr(bi_instr *ins) +{ + enum bifrost_message_type msg = bi_opcode_props[ins->op].message; + bool ld_var_special = (ins->op == BI_OPCODE_LD_VAR_SPECIAL); + + if (ld_var_special && ins->varying_name == BI_VARYING_NAME_FRAG_Z) + return BIFROST_MESSAGE_Z_STENCIL; + + if (msg == BIFROST_MESSAGE_LOAD && ins->seg == BI_SEG_UBO) + return BIFROST_MESSAGE_ATTRIBUTE; + + return msg; +} + +/* Attribute, texture, and UBO load (attribute message) instructions support + * bindless, so just check the message type */ + +ASSERTED static bool +bi_supports_dtsel(bi_instr *ins) +{ + switch (bi_message_type_for_instr(ins)) { + case BIFROST_MESSAGE_ATTRIBUTE: + return ins->op != BI_OPCODE_LD_GCLK_U64; + case BIFROST_MESSAGE_TEX: + return true; + default: + return false; + } +} + /* Scheduler pseudoinstruction lowerings to enable instruction pairings. * Currently only support CUBEFACE -> *CUBEFACE1/+CUBEFACE2 */ @@ -198,6 +234,21 @@ bi_lower_seg_add(bi_context *ctx, return fma; } +static bi_instr * +bi_lower_dtsel(bi_context *ctx, + struct bi_clause_state *clause, struct bi_tuple_state *tuple) +{ + bi_instr *add = tuple->add; + bi_builder b = bi_init_builder(ctx, bi_before_instr(add)); + + bi_instr *dtsel = bi_dtsel_imm_to(&b, bi_temp(b.shader), + add->src[0], add->table); + add->src[0] = dtsel->dest[0]; + + assert(bi_supports_dtsel(add)); + return dtsel; +} + /* Flatten linked list to array for O(1) indexing */ static bi_instr ** @@ -249,26 +300,6 @@ bi_update_worklist(struct bi_worklist st, unsigned idx) BITSET_SET(st.worklist, idx - 1); } -/* Determines messsage type by checking the table and a few special cases. Only - * case missing is tilebuffer instructions that access depth/stencil, which - * require a Z_STENCIL message (to implement - * ARM_shader_framebuffer_fetch_depth_stencil) */ - -static enum bifrost_message_type -bi_message_type_for_instr(bi_instr *ins) -{ - enum bifrost_message_type msg = bi_opcode_props[ins->op].message; - bool ld_var_special = (ins->op == BI_OPCODE_LD_VAR_SPECIAL); - - if (ld_var_special && ins->varying_name == BI_VARYING_NAME_FRAG_Z) - return BIFROST_MESSAGE_Z_STENCIL; - - if (msg == BIFROST_MESSAGE_LOAD && ins->seg == BI_SEG_UBO) - return BIFROST_MESSAGE_ATTRIBUTE; - - return msg; -} - /* To work out the back-to-back flag, we need to detect branches and * "fallthrough" branches, implied in the last clause of a block that falls * through to another block with *multiple predecessors*. */ @@ -857,6 +888,8 @@ bi_take_instr(bi_context *ctx, struct bi_worklist st, return bi_lower_atom_c1(ctx, clause, tuple); else if (tuple->add && tuple->add->op == BI_OPCODE_SEG_ADD_I64) return bi_lower_seg_add(ctx, clause, tuple); + else if (tuple->add && tuple->add->table) + return bi_lower_dtsel(ctx, clause, tuple); unsigned idx = bi_choose_index(st, clause, tuple, fma); diff --git a/src/panfrost/bifrost/bifrost_isa.py b/src/panfrost/bifrost/bifrost_isa.py index f128f9d..a2d7f88 100644 --- a/src/panfrost/bifrost/bifrost_isa.py +++ b/src/panfrost/bifrost/bifrost_isa.py @@ -309,6 +309,11 @@ def order_modifiers(ir_instructions): # Ensure none is false for booleans so the builder makes sense if len(lst) == 2 and lst[1] == "none": lst.reverse() + elif mod == "table": + # We really need a zero sentinel to materialize DTSEL + assert(lst[2] == "none") + lst[2] = lst[0] + lst[0] = "none" out[mod] = lst diff --git a/src/panfrost/bifrost/compiler.h b/src/panfrost/bifrost/compiler.h index 95eb2a6..aa2f4f7 100644 --- a/src/panfrost/bifrost/compiler.h +++ b/src/panfrost/bifrost/compiler.h @@ -286,6 +286,9 @@ typedef struct { * useless double fills */ bool no_spill; + /* Override table, inducing a DTSEL_IMM pair if nonzero */ + enum bi_table table; + /* Everything after this MUST NOT be accessed directly, since * interpretation depends on opcodes */ @@ -302,7 +305,6 @@ typedef struct { uint32_t shift; uint32_t fill; uint32_t index; - uint32_t table; uint32_t attribute_index; struct {