mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-04-25 17:50:39 +02:00
i965/fs: Add support for sub-register byte offsets to the FS back-end IR.
It would be nice if we could have a single 'reg_offset' field expressed in bytes that would serve the purpose of both, but the semantics of 'reg_offset' are quite complex currently (it's measured in units of one, eight or sixteen dwords depending on the register file and the dispatch width) and changing it to bytes would be a very intrusive change at this stage. Add a separate 'subreg_offset' field for now. Reviewed-by: Matt Turner <mattst88@gmail.com> Reviewed-by: Paul Berry <stereotype441@gmail.com>
This commit is contained in:
parent
248606a5f0
commit
4c7206bafd
5 changed files with 46 additions and 21 deletions
|
|
@ -432,6 +432,7 @@ fs_reg::equals(const fs_reg &r) const
|
|||
return (file == r.file &&
|
||||
reg == r.reg &&
|
||||
reg_offset == r.reg_offset &&
|
||||
subreg_offset == r.subreg_offset &&
|
||||
type == r.type &&
|
||||
negate == r.negate &&
|
||||
abs == r.abs &&
|
||||
|
|
@ -1407,7 +1408,9 @@ fs_visitor::assign_curb_setup()
|
|||
constant_nr % 8);
|
||||
|
||||
inst->src[i].file = HW_REG;
|
||||
inst->src[i].fixed_hw_reg = retype(brw_reg, inst->src[i].type);
|
||||
inst->src[i].fixed_hw_reg = byte_offset(
|
||||
retype(brw_reg, inst->src[i].type),
|
||||
inst->src[i].subreg_offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2473,7 +2476,8 @@ fs_visitor::compute_to_mrf()
|
|||
inst->is_partial_write() ||
|
||||
inst->dst.file != MRF || inst->src[0].file != GRF ||
|
||||
inst->dst.type != inst->src[0].type ||
|
||||
inst->src[0].abs || inst->src[0].negate || inst->src[0].smear != -1)
|
||||
inst->src[0].abs || inst->src[0].negate ||
|
||||
inst->src[0].smear != -1 || inst->src[0].subreg_offset)
|
||||
continue;
|
||||
|
||||
/* Work out which hardware MRF registers are written by this
|
||||
|
|
@ -3008,8 +3012,9 @@ fs_visitor::dump_instruction(backend_instruction *be_inst)
|
|||
switch (inst->dst.file) {
|
||||
case GRF:
|
||||
printf("vgrf%d", inst->dst.reg);
|
||||
if (virtual_grf_sizes[inst->dst.reg] != 1)
|
||||
printf("+%d", inst->dst.reg_offset);
|
||||
if (virtual_grf_sizes[inst->dst.reg] != 1 ||
|
||||
inst->dst.subreg_offset)
|
||||
printf("+%d.%d", inst->dst.reg_offset, inst->dst.subreg_offset);
|
||||
break;
|
||||
case MRF:
|
||||
printf("m%d", inst->dst.reg);
|
||||
|
|
@ -3061,16 +3066,20 @@ fs_visitor::dump_instruction(backend_instruction *be_inst)
|
|||
switch (inst->src[i].file) {
|
||||
case GRF:
|
||||
printf("vgrf%d", inst->src[i].reg);
|
||||
if (virtual_grf_sizes[inst->src[i].reg] != 1)
|
||||
printf("+%d", inst->src[i].reg_offset);
|
||||
if (virtual_grf_sizes[inst->src[i].reg] != 1 ||
|
||||
inst->src[i].subreg_offset)
|
||||
printf("+%d.%d", inst->src[i].reg_offset,
|
||||
inst->src[i].subreg_offset);
|
||||
break;
|
||||
case MRF:
|
||||
printf("***m%d***", inst->src[i].reg);
|
||||
break;
|
||||
case UNIFORM:
|
||||
printf("u%d", inst->src[i].reg);
|
||||
if (virtual_grf_sizes[inst->src[i].reg] != 1)
|
||||
printf(".%d", inst->src[i].reg_offset);
|
||||
if (virtual_grf_sizes[inst->src[i].reg] != 1 ||
|
||||
inst->src[i].subreg_offset)
|
||||
printf("+%d.%d", inst->src[i].reg_offset,
|
||||
inst->src[i].subreg_offset);
|
||||
break;
|
||||
case BAD_FILE:
|
||||
printf("(null)");
|
||||
|
|
|
|||
|
|
@ -114,9 +114,23 @@ public:
|
|||
float f;
|
||||
} imm;
|
||||
|
||||
/**
|
||||
* Offset in bytes from the start of the register. Values up to a
|
||||
* backend_reg::reg_offset unit are valid.
|
||||
*/
|
||||
int subreg_offset;
|
||||
|
||||
fs_reg *reladdr;
|
||||
};
|
||||
|
||||
static inline fs_reg
|
||||
byte_offset(fs_reg reg, unsigned delta)
|
||||
{
|
||||
assert(delta == 0 || (reg.file != HW_REG && reg.file != IMM));
|
||||
reg.subreg_offset += delta;
|
||||
return reg;
|
||||
}
|
||||
|
||||
static const fs_reg reg_undef;
|
||||
static const fs_reg reg_null_f(retype(brw_null_reg(), BRW_REGISTER_TYPE_F));
|
||||
static const fs_reg reg_null_d(retype(brw_null_reg(), BRW_REGISTER_TYPE_D));
|
||||
|
|
|
|||
|
|
@ -284,7 +284,8 @@ fs_visitor::try_copy_propagate(fs_inst *inst, int arg, acp_entry *entry)
|
|||
|
||||
if (inst->src[arg].file != entry->dst.file ||
|
||||
inst->src[arg].reg != entry->dst.reg ||
|
||||
inst->src[arg].reg_offset != entry->dst.reg_offset) {
|
||||
inst->src[arg].reg_offset != entry->dst.reg_offset ||
|
||||
inst->src[arg].subreg_offset != entry->dst.subreg_offset) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -308,6 +309,7 @@ fs_visitor::try_copy_propagate(fs_inst *inst, int arg, acp_entry *entry)
|
|||
inst->src[arg].reg_offset = entry->src.reg_offset;
|
||||
if (entry->src.smear != -1)
|
||||
inst->src[arg].smear = entry->src.smear;
|
||||
inst->src[arg].subreg_offset = entry->src.subreg_offset;
|
||||
|
||||
if (!inst->src[arg].abs) {
|
||||
inst->src[arg].abs = entry->src.abs;
|
||||
|
|
@ -329,7 +331,8 @@ fs_visitor::try_constant_propagate(fs_inst *inst, acp_entry *entry)
|
|||
for (int i = 2; i >= 0; i--) {
|
||||
if (inst->src[i].file != entry->dst.file ||
|
||||
inst->src[i].reg != entry->dst.reg ||
|
||||
inst->src[i].reg_offset != entry->dst.reg_offset)
|
||||
inst->src[i].reg_offset != entry->dst.reg_offset ||
|
||||
inst->src[i].subreg_offset != entry->dst.subreg_offset)
|
||||
continue;
|
||||
|
||||
/* Don't bother with cases that should have been taken care of by the
|
||||
|
|
|
|||
|
|
@ -1038,6 +1038,7 @@ brw_reg_from_fs_reg(fs_reg *reg)
|
|||
brw_reg = retype(brw_reg, reg->type);
|
||||
if (reg->sechalf)
|
||||
brw_reg = sechalf(brw_reg);
|
||||
brw_reg = byte_offset(brw_reg, reg->subreg_offset);
|
||||
break;
|
||||
case IMM:
|
||||
switch (reg->type) {
|
||||
|
|
|
|||
|
|
@ -686,11 +686,12 @@ fs_visitor::spill_reg(int spill_reg)
|
|||
int regs_read = inst->regs_read(this, i);
|
||||
int subset_spill_offset = (spill_offset +
|
||||
reg_size * inst->src[i].reg_offset);
|
||||
fs_reg unspill_dst(GRF, virtual_grf_alloc(regs_read));
|
||||
|
||||
inst->src[i].reg = virtual_grf_alloc(regs_read);
|
||||
inst->src[i].reg = unspill_dst.reg;
|
||||
inst->src[i].reg_offset = 0;
|
||||
|
||||
emit_unspill(inst, inst->src[i], subset_spill_offset, regs_read);
|
||||
emit_unspill(inst, unspill_dst, subset_spill_offset, regs_read);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -698,24 +699,21 @@ fs_visitor::spill_reg(int spill_reg)
|
|||
inst->dst.reg == spill_reg) {
|
||||
int subset_spill_offset = (spill_offset +
|
||||
reg_size * inst->dst.reg_offset);
|
||||
inst->dst.reg = virtual_grf_alloc(inst->regs_written);
|
||||
fs_reg spill_src(GRF, virtual_grf_alloc(inst->regs_written));
|
||||
|
||||
inst->dst.reg = spill_src.reg;
|
||||
inst->dst.reg_offset = 0;
|
||||
|
||||
/* If our write is going to affect just part of the
|
||||
* inst->regs_written(), then we need to unspill the destination
|
||||
* since we write back out all of the regs_written().
|
||||
*/
|
||||
if (inst->predicate || inst->force_uncompressed || inst->force_sechalf) {
|
||||
emit_unspill(inst, inst->dst, subset_spill_offset,
|
||||
if (inst->predicate || inst->force_uncompressed ||
|
||||
inst->force_sechalf || inst->dst.subreg_offset) {
|
||||
emit_unspill(inst, spill_src, subset_spill_offset,
|
||||
inst->regs_written);
|
||||
}
|
||||
|
||||
fs_reg spill_src = inst->dst;
|
||||
spill_src.reg_offset = 0;
|
||||
spill_src.abs = false;
|
||||
spill_src.negate = false;
|
||||
spill_src.smear = -1;
|
||||
|
||||
for (int chan = 0; chan < inst->regs_written; chan++) {
|
||||
fs_inst *spill_inst =
|
||||
new(mem_ctx) fs_inst(SHADER_OPCODE_GEN4_SCRATCH_WRITE,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue