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(); FLAT_instruction& flat = instr->flatlike();
uint32_t encoding = (0b110111 << 26); uint32_t encoding = (0b110111 << 26);
encoding |= opcode << 18; encoding |= opcode << 18;
if (ctx.gfx_level <= GFX9) { if (ctx.gfx_level == GFX9 || ctx.gfx_level >= GFX11) {
assert(flat.offset <= 0x1fff); if (instr->isFlat())
assert(flat.offset <= 0xfff);
else
assert(flat.offset >= -4096 && flat.offset < 4096);
encoding |= flat.offset & 0x1fff; encoding |= flat.offset & 0x1fff;
} else if (instr->isFlat()) { } else if (ctx.gfx_level <= GFX8 || instr->isFlat()) {
/* GFX10 has a 12-bit immediate OFFSET field, /* GFX10 has a 12-bit immediate OFFSET field,
* but it has a hw bug: it ignores the offset, called FlatSegmentOffsetBug * but it has a hw bug: it ignores the offset, called FlatSegmentOffsetBug
*/ */
assert(flat.offset == 0); assert(flat.offset == 0);
} else { } else {
assert(flat.offset <= 0xfff); assert(flat.offset >= -2048 && flat.offset <= 2047);
encoding |= flat.offset & 0xfff; encoding |= flat.offset & 0xfff;
} }
if (instr->isScratch()) 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 = uint64_t max_const_offset_plus_one =
1; /* GFX7/8/9: FLAT loads do not support constant offsets */ 1; /* GFX7/8/9: FLAT loads do not support constant offsets */
if (bld.program->gfx_level >= GFX10) if (bld.program->gfx_level >= GFX9)
max_const_offset_plus_one = max_const_offset_plus_one = bld.program->dev.scratch_global_offset_max;
2048; /* GLOBAL has a 11-bit signed offset field (12 bits if signed) */ else if (bld.program->gfx_level == GFX6)
else if (bld.program->gfx_level == GFX6 || bld.program->gfx_level == GFX9) max_const_offset_plus_one = 4096; /* MUBUF has a 12-bit unsigned offset field */
max_const_offset_plus_one =
4096; /* MUBUF/GLOBAL has a 12-bit unsigned offset field (13 bits if signed for GLOBAL) */
uint64_t excess_offset = const_offset - (const_offset % max_const_offset_plus_one); uint64_t excess_offset = const_offset - (const_offset % max_const_offset_plus_one);
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->family == CHIP_ARCTURUS || program->family == CHIP_ALDEBARAN)
program->dev.fused_mad_mix = true; 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->wgp_mode = wgp_mode;
program->progress = CompilationProgress::after_isel; program->progress = CompilationProgress::after_isel;

View File

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

View File

@ -158,7 +158,7 @@ class Format(Enum):
return [('uint8_t', 'opsel_lo', None), return [('uint8_t', 'opsel_lo', None),
('uint8_t', 'opsel_hi', None)] ('uint8_t', 'opsel_hi', None)]
elif self in [Format.FLAT, Format.GLOBAL, Format.SCRATCH]: 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()'), ('memory_sync_info', 'sync', 'memory_sync_info()'),
('bool', 'glc', 'false'), ('bool', 'glc', 'false'),
('bool', 'slc', 'false'), ('bool', 'slc', 'false'),

View File

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