aco: make FLAT_instruction::offset signed

Signed-off-by: Rhys Perry <pendingchaos02@gmail.com>
Reviewed-by: Daniel Schürmann <daniel@schuermann.dev>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17079>
This commit is contained in:
Rhys Perry 2022-05-19 15:18:36 +01:00 committed by Marge Bot
parent 5898afba53
commit cbeb25ce91
6 changed files with 29 additions and 13 deletions

View File

@ -507,16 +507,19 @@ emit_instruction(asm_context& ctx, std::vector<uint32_t>& out, Instruction* inst
FLAT_instruction& flat = instr->flatlike();
uint32_t encoding = (0b110111 << 26);
encoding |= opcode << 18;
if (ctx.gfx_level <= GFX9) {
assert(flat.offset <= 0x1fff);
if (ctx.gfx_level == GFX9 || ctx.gfx_level >= GFX11) {
if (instr->isFlat())
assert(flat.offset <= 0xfff);
else
assert(flat.offset >= -4096 && flat.offset < 4096);
encoding |= flat.offset & 0x1fff;
} else if (instr->isFlat()) {
} else if (ctx.gfx_level <= GFX8 || instr->isFlat()) {
/* GFX10 has a 12-bit immediate OFFSET field,
* but it has a hw bug: it ignores the offset, called FlatSegmentOffsetBug
*/
assert(flat.offset == 0);
} else {
assert(flat.offset <= 0xfff);
assert(flat.offset >= -2048 && flat.offset <= 2047);
encoding |= flat.offset & 0xfff;
}
if (instr->isScratch())

View File

@ -4467,12 +4467,10 @@ lower_global_address(Builder& bld, uint32_t offset_in, Temp* address_inout,
uint64_t max_const_offset_plus_one =
1; /* GFX7/8/9: FLAT loads do not support constant offsets */
if (bld.program->gfx_level >= GFX10)
max_const_offset_plus_one =
2048; /* GLOBAL has a 11-bit signed offset field (12 bits if signed) */
else if (bld.program->gfx_level == GFX6 || bld.program->gfx_level == GFX9)
max_const_offset_plus_one =
4096; /* MUBUF/GLOBAL has a 12-bit unsigned offset field (13 bits if signed for GLOBAL) */
if (bld.program->gfx_level >= GFX9)
max_const_offset_plus_one = bld.program->dev.scratch_global_offset_max;
else if (bld.program->gfx_level == GFX6)
max_const_offset_plus_one = 4096; /* MUBUF has a 12-bit unsigned offset field */
uint64_t excess_offset = const_offset - (const_offset % max_const_offset_plus_one);
const_offset %= max_const_offset_plus_one;

View File

@ -155,6 +155,18 @@ init_program(Program* program, Stage stage, const struct aco_shader_info* info,
program->family == CHIP_ARCTURUS || program->family == CHIP_ALDEBARAN)
program->dev.fused_mad_mix = true;
if (program->gfx_level >= GFX11) {
program->dev.scratch_global_offset_min = -4096;
program->dev.scratch_global_offset_max = 4095;
} else if (program->gfx_level >= GFX10 || program->gfx_level == GFX8) {
program->dev.scratch_global_offset_min = -2048;
program->dev.scratch_global_offset_max = 2047;
} else if (program->gfx_level == GFX9) {
/* The minimum is actually -4096, but negative offsets are broken when SADDR is used. */
program->dev.scratch_global_offset_min = 0;
program->dev.scratch_global_offset_max = 4095;
}
program->wgp_mode = wgp_mode;
program->progress = CompilationProgress::after_isel;

View File

@ -1646,7 +1646,7 @@ struct FLAT_instruction : public Instruction {
bool nv : 1;
bool disable_wqm : 1; /* Require an exec mask without helper invocations */
uint8_t padding0 : 2;
uint16_t offset; /* Vega/Navi only */
int16_t offset; /* Vega/Navi only */
uint16_t padding1;
};
static_assert(sizeof(FLAT_instruction) == sizeof(Instruction) + 8, "Unexpected padding");
@ -2066,6 +2066,9 @@ struct DeviceInfo {
bool fused_mad_mix = false;
bool xnack_enabled = false;
bool sram_ecc_enabled = false;
int16_t scratch_global_offset_min;
int16_t scratch_global_offset_max;
};
enum class CompilationProgress {

View File

@ -158,7 +158,7 @@ class Format(Enum):
return [('uint8_t', 'opsel_lo', None),
('uint8_t', 'opsel_hi', None)]
elif self in [Format.FLAT, Format.GLOBAL, Format.SCRATCH]:
return [('uint16_t', 'offset', 0),
return [('int16_t', 'offset', 0),
('memory_sync_info', 'sync', 'memory_sync_info()'),
('bool', 'glc', 'false'),
('bool', 'slc', 'false'),

View File

@ -484,7 +484,7 @@ print_instr_format_specific(const Instruction* instr, FILE* output)
case Format::SCRATCH: {
const FLAT_instruction& flat = instr->flatlike();
if (flat.offset)
fprintf(output, " offset:%u", flat.offset);
fprintf(output, " offset:%d", flat.offset);
if (flat.glc)
fprintf(output, " glc");
if (flat.dlc)