pan/bi: Fix LD_VAR with non-constant index
src0 and src1 were mixed leading to invalid varying indices. In order to fix that properly, we first extend load_vary to pass the immediate index through a dedicated field and add a special boolean. This way, we don't have to make sure src0 always contains the index, and can instead match the src numbering defined in ISA.xml. Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7636>
This commit is contained in:
@@ -713,18 +713,16 @@ bi_pack_add_special(bi_clause *clause, bi_instruction *ins, bi_registers *regs)
|
||||
static unsigned
|
||||
bi_pack_add_ld_var(bi_clause *clause, bi_instruction *ins, bi_registers *regs)
|
||||
{
|
||||
bool imm = ins->src[0] & BIR_INDEX_CONSTANT;
|
||||
|
||||
if (ins->load_vary.special)
|
||||
return pan_pack_add_ld_var_special(clause, ins, regs);
|
||||
|
||||
if (ins->load_vary.flat) {
|
||||
return imm ?
|
||||
return ins->load_vary.immediate ?
|
||||
pan_pack_add_ld_var_flat_imm(clause, ins, regs) :
|
||||
pan_pack_add_ld_var_flat(clause, ins, regs);
|
||||
}
|
||||
|
||||
return imm ?
|
||||
return ins->load_vary.immediate ?
|
||||
pan_pack_add_ld_var_imm(clause, ins, regs) :
|
||||
pan_pack_add_ld_var(clause, ins, regs);
|
||||
}
|
||||
|
||||
@@ -255,6 +255,9 @@ bi_print_load_vary(struct bi_load_vary *load, FILE *fp)
|
||||
if (load->flat)
|
||||
fprintf(fp, ".flat");
|
||||
|
||||
if (load->immediate)
|
||||
fprintf(fp, ".imm(%d)", load->index);
|
||||
|
||||
switch (load->update_mode) {
|
||||
case BIFROST_UPDATE_STORE: fprintf(fp, ".store"); break;
|
||||
case BIFROST_UPDATE_RETRIEVE: fprintf(fp, ".retrieve"); break;
|
||||
|
||||
@@ -161,12 +161,19 @@ bi_interp_for_intrinsic(nir_intrinsic_op op)
|
||||
static void
|
||||
bi_emit_ld_vary(bi_context *ctx, nir_intrinsic_instr *instr)
|
||||
{
|
||||
bi_instruction ins = bi_load(BI_LOAD_VAR, instr);
|
||||
ins.load_vary.interp_mode = BIFROST_INTERP_CENTER; /* TODO */
|
||||
ins.load_vary.reuse = false; /* TODO */
|
||||
ins.load_vary.flat = instr->intrinsic != nir_intrinsic_load_interpolated_input;
|
||||
ins.dest_type = nir_dest_bit_size(instr->dest);
|
||||
ins.format = ins.dest_type;
|
||||
bi_instruction ins = {
|
||||
.type = BI_LOAD_VAR,
|
||||
.load_vary = {
|
||||
.interp_mode = BIFROST_INTERP_CENTER,
|
||||
.update_mode = BIFROST_UPDATE_STORE,
|
||||
.reuse = false,
|
||||
.flat = instr->intrinsic != nir_intrinsic_load_interpolated_input,
|
||||
},
|
||||
.dest = pan_dest_index(&instr->dest),
|
||||
.dest_type = nir_dest_bit_size(instr->dest),
|
||||
.src_types = { nir_type_uint32, nir_type_uint32, nir_type_uint32 },
|
||||
.vector_channels = instr->num_components,
|
||||
};
|
||||
|
||||
if (instr->intrinsic == nir_intrinsic_load_interpolated_input) {
|
||||
nir_intrinsic_instr *parent = nir_src_as_intrinsic(instr->src[0]);
|
||||
@@ -176,12 +183,28 @@ bi_emit_ld_vary(bi_context *ctx, nir_intrinsic_instr *instr)
|
||||
}
|
||||
}
|
||||
|
||||
if (nir_src_is_const(*nir_get_io_offset_src(instr))) {
|
||||
/* Zero it out for direct */
|
||||
ins.src[1] = BIR_INDEX_ZERO;
|
||||
if (ins.load_vary.interp_mode == BIFROST_INTERP_CENTER) {
|
||||
/* Zero it out for center interpolation */
|
||||
ins.src[0] = BIR_INDEX_ZERO;
|
||||
} else {
|
||||
/* R61 contains sample mask stuff, TODO RA XXX */
|
||||
ins.src[1] = BIR_INDEX_REGISTER | 61;
|
||||
ins.src[0] = BIR_INDEX_REGISTER | 61;
|
||||
}
|
||||
|
||||
nir_src *offset = nir_get_io_offset_src(instr);
|
||||
if (nir_src_is_const(*offset)) {
|
||||
unsigned offset_val = nir_intrinsic_base(instr) +
|
||||
nir_src_as_uint(*offset);
|
||||
|
||||
if (offset_val < 20) {
|
||||
ins.load_vary.immediate = true;
|
||||
ins.load_vary.index = offset_val;
|
||||
} else {
|
||||
ins.src[1] = BIR_INDEX_CONSTANT | 0;
|
||||
ins.constant.u64 = offset_val;
|
||||
}
|
||||
} else {
|
||||
ins.src[1] = pan_src_index(offset);
|
||||
}
|
||||
|
||||
bi_emit(ctx, ins);
|
||||
|
||||
@@ -136,6 +136,8 @@ struct bi_load_vary {
|
||||
enum bifrost_interp_mode interp_mode;
|
||||
enum bifrost_update_mode update_mode;
|
||||
enum bifrost_special_var_id var_id;
|
||||
unsigned index;
|
||||
bool immediate;
|
||||
bool special;
|
||||
bool reuse;
|
||||
bool flat;
|
||||
|
||||
@@ -393,7 +393,7 @@ def pack_derived(pos, exprs, imm_map, body, pack_exprs):
|
||||
IMMEDIATE_TABLE = {
|
||||
'attribute_index': 'bi_get_immediate(ins, 0)',
|
||||
'varying_index': 'bi_get_immediate(ins, 0)',
|
||||
'index': 'bi_get_immediate(ins, 0)',
|
||||
'index': 'ins->load_vary.index',
|
||||
'texture_index': 'ins->texture.texture_index',
|
||||
'sampler_index': 'ins->texture.sampler_index',
|
||||
'table': '63', # Bindless (flat addressing) mode for DTSEL_IMM
|
||||
@@ -452,7 +452,7 @@ def pack_variant(opname, states):
|
||||
if staging in ["r", "rw"]:
|
||||
offset += 1
|
||||
|
||||
offset += len(set(["attribute_index", "varying_index", "index"]) & set([x[0] for x in states[0][1].get("immediates", [])]))
|
||||
offset += len(set(["attribute_index", "varying_index"]) & set([x[0] for x in states[0][1].get("immediates", [])]))
|
||||
|
||||
pack_sources(states[0][1].get("srcs", []), common_body, pack_exprs, offset)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user