brw: encode the offset into the message descriptor for Xe2

Signed-off-by: Rohan Garg <rohan.garg@intel.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35252>
This commit is contained in:
Rohan Garg
2024-10-22 17:00:13 +02:00
committed by Marge Bot
parent 937d37f0b1
commit 0186113640
6 changed files with 113 additions and 21 deletions
+30 -2
View File
@@ -1295,11 +1295,12 @@ lsc_fence_msg_desc_backup_routing(UNUSED const struct intel_device_info *devinfo
}
static inline uint32_t
lsc_bti_ex_desc(const struct intel_device_info *devinfo, unsigned bti)
lsc_bti_ex_desc(const struct intel_device_info *devinfo, unsigned bti,
unsigned base_offset)
{
assert(devinfo->has_lsc);
return SET_BITS(bti, 31, 24) |
SET_BITS(0, 23, 12); /* base offset */
SET_BITS(base_offset, 23, 12); /* base offset */
}
static inline unsigned
@@ -1318,6 +1319,14 @@ lsc_bti_ex_desc_index(const struct intel_device_info *devinfo,
return GET_BITS(ex_desc, 31, 24);
}
static inline unsigned
lsc_flat_ex_desc(const struct intel_device_info *devinfo,
uint32_t base_offset)
{
assert(devinfo->has_lsc);
return SET_BITS(base_offset, 31, 12);
}
static inline unsigned
lsc_flat_ex_desc_base_offset(const struct intel_device_info *devinfo,
uint32_t ex_desc)
@@ -1460,6 +1469,7 @@ brw_send_indirect_split_message(struct brw_codegen *p,
struct brw_reg payload1,
struct brw_reg desc,
struct brw_reg ex_desc,
uint32_t ex_desc_imm_inst,
unsigned ex_mlen,
bool ex_bso,
bool eot,
@@ -1612,6 +1622,24 @@ next_offset(struct brw_codegen *p, void *store, int offset)
/** Maximum SEND message length */
#define BRW_MAX_MSG_LENGTH 15
/** Offset encoding signed size limits (top bit is the sign) */
#define LSC_ADDRESS_OFFSET_FLAT_BITS 20
#define LSC_ADDRESS_OFFSET_SS_BITS 17
#define LSC_ADDRESS_OFFSET_BTI_BITS 12
static inline unsigned
brw_max_immediate_offset_bits(enum lsc_addr_surface_type binding_type)
{
static const unsigned max_bits[] = {
[LSC_ADDR_SURFTYPE_FLAT] = LSC_ADDRESS_OFFSET_FLAT_BITS,
[LSC_ADDR_SURFTYPE_BSS] = LSC_ADDRESS_OFFSET_SS_BITS,
[LSC_ADDR_SURFTYPE_SS] = LSC_ADDRESS_OFFSET_SS_BITS,
[LSC_ADDR_SURFTYPE_BTI] = LSC_ADDRESS_OFFSET_BTI_BITS,
};
assert(binding_type <= LSC_ADDR_SURFTYPE_BTI);
return max_bits[binding_type];
}
#ifdef __cplusplus
}
#endif
+14
View File
@@ -1490,6 +1490,7 @@ brw_send_indirect_split_message(struct brw_codegen *p,
struct brw_reg payload1,
struct brw_reg desc,
struct brw_reg ex_desc,
uint32_t ex_desc_imm_inst,
unsigned ex_mlen,
bool ex_bso,
bool eot,
@@ -1517,6 +1518,7 @@ brw_send_indirect_split_message(struct brw_codegen *p,
}
if (ex_desc.file == IMM) {
assert(ex_desc_imm_inst == 0);
brw_eu_inst_set_send_sel_reg32_ex_desc(devinfo, send, 0);
brw_eu_inst_set_sends_ex_desc(devinfo, send, ex_desc.ud, gather);
} else {
@@ -1525,6 +1527,18 @@ brw_send_indirect_split_message(struct brw_codegen *p,
brw_eu_inst_set_send_sel_reg32_ex_desc(devinfo, send, 1);
brw_eu_inst_set_send_ex_desc_ia_subreg_nr(devinfo, send, phys_subnr(devinfo, ex_desc) >> 2);
if (ex_desc_imm_inst) {
/* Write the immediate extended descriptor immediate value, but only
* the part used for encoding an offset. This matches to bits
* 12:15-19:31 as described in BSpec 70586.
*/
assert(devinfo->ver >= 20);
brw_eu_inst_set_bits(send, 127, 124, GET_BITS(ex_desc_imm_inst, 31, 28));
brw_eu_inst_set_bits(send, 97, 96, GET_BITS(ex_desc_imm_inst, 27, 26));
brw_eu_inst_set_bits(send, 65, 64, GET_BITS(ex_desc_imm_inst, 25, 24));
brw_eu_inst_set_bits(send, 47, 43, GET_BITS(ex_desc_imm_inst, 23, 19));
brw_eu_inst_set_bits(send, 39, 36, GET_BITS(ex_desc_imm_inst, 15, 12));
}
if (devinfo->ver >= 20 && sfid == BRW_SFID_UGM)
brw_eu_inst_set_bits(send, 103, 99, ex_mlen / reg_unit(devinfo));
}
+9 -2
View File
@@ -177,6 +177,11 @@ brw_generator::generate_send(brw_inst *inst,
}
if (ex_desc.file == IMM && ex_desc.ud == 0) {
/* An immediate extended descriptor value only happens when the extended
* descriptor is written indirectly (it already contains a SS/BSS
* surface handle)
*/
assert(!inst->send_ex_desc_imm);
brw_send_indirect_message(p, inst->sfid, dst, payload, desc, inst->eot, gather);
if (inst->check_tdr)
brw_eu_inst_set_opcode(p->isa, brw_last_inst, BRW_OPCODE_SENDC);
@@ -185,8 +190,10 @@ brw_generator::generate_send(brw_inst *inst,
* also covers the dual-payload case because ex_mlen goes in ex_desc.
*/
brw_send_indirect_split_message(p, inst->sfid, dst, payload, payload2,
desc, ex_desc, inst->ex_mlen,
inst->send_ex_bso, inst->eot, gather);
desc, ex_desc,
inst->send_ex_desc_imm ? inst->offset : 0,
inst->ex_mlen, inst->send_ex_bso,
inst->eot, gather);
if (inst->check_tdr)
brw_eu_inst_set_opcode(p->isa, brw_last_inst,
devinfo->ver >= 12 ? BRW_OPCODE_SENDC : BRW_OPCODE_SENDSC);
+7 -1
View File
@@ -190,7 +190,7 @@ public:
*/
unsigned rcount:4;
unsigned pad:5;
unsigned pad:4;
bool predicate_inverse:1;
bool writes_accumulator:1; /**< instruction implicitly writes accumulator */
@@ -205,6 +205,12 @@ public:
* bindless surface offset (26bits instead of
* 20bits)
*/
/**
* Only for SHADER_OPCODE_SEND, @offset field contains an immediate
* part of the extended descriptor that must be encoded in the
* instruction.
*/
bool send_ex_desc_imm:1;
/**
* The predication mask applied to this instruction is guaranteed to
* be uniform and a superset of the execution mask of the present block.
+50 -16
View File
@@ -29,6 +29,8 @@
#include "brw_shader.h"
#include "brw_builder.h"
#include "util/bitpack_helpers.h"
static void
lower_urb_read_logical_send(const brw_builder &bld, brw_inst *inst)
{
@@ -1396,14 +1398,26 @@ setup_surface_descriptors(const brw_builder &bld, brw_inst *inst, uint32_t desc,
static void
setup_lsc_surface_descriptors(const brw_builder &bld, brw_inst *inst,
uint32_t desc, const brw_reg &surface)
uint32_t desc, const brw_reg &surface,
int32_t base_offset)
{
const ASSERTED intel_device_info *devinfo = bld.shader->devinfo;
const brw_compiler *compiler = bld.shader->compiler;
assert(base_offset == 0 || devinfo->ver >= 20);
inst->src[0] = brw_imm_ud(0); /* desc */
inst->src[1] = brw_imm_ud(0);
enum lsc_addr_surface_type surf_type = lsc_msg_desc_addr_type(devinfo, desc);
unsigned max_imm_bits = brw_max_immediate_offset_bits(surf_type);
assert(base_offset >= u_intN_min(max_imm_bits));
assert(base_offset <= u_intN_max(max_imm_bits));
const unsigned base_offset_bits =
util_bitpack_sint(base_offset, 0, max_imm_bits - 1);
switch (surf_type) {
case LSC_ADDR_SURFTYPE_BSS:
inst->send_ex_bso = compiler->extended_bindless_surface_offset;
@@ -1417,22 +1431,40 @@ setup_lsc_surface_descriptors(const brw_builder &bld, brw_inst *inst,
/* Gfx20+ assumes ExBSO with UGM */
if (devinfo->ver >= 20 && inst->sfid == BRW_SFID_UGM)
inst->send_ex_bso = true;
/* We're already using the extended descriptor to hold the surface
* handle. But now the immediate extended descriptor bits in the
* instruction are unused, so this is where the HW design team thought
* it would be a good idea to store the immediate offset.
*
* This doesn't play well with the rest of our compiler that considers
* there is only one value for the extended descriptor. So here we stash
* the base offset in brw_inst::offset and flag the instruction for the
* generator to do the right thing with it.
*/
if (base_offset) {
inst->send_ex_desc_imm = true;
inst->offset = SET_BITS(GET_BITS(base_offset_bits, 16, 4), 31, 19) |
SET_BITS(GET_BITS(base_offset_bits, 3, 0), 15, 12);
}
break;
case LSC_ADDR_SURFTYPE_BTI:
assert(surface.file != BAD_FILE);
if (surface.file == IMM) {
inst->src[1] = brw_imm_ud(lsc_bti_ex_desc(devinfo, surface.ud));
inst->src[1] = brw_imm_ud(lsc_bti_ex_desc(devinfo, surface.ud,
base_offset_bits));
} else {
const brw_builder ubld = bld.uniform();
brw_reg tmp = ubld.vgrf(BRW_TYPE_UD);
ubld.SHL(tmp, surface, brw_imm_ud(24));
brw_reg tmp = ubld.OR(
ubld.SHL(surface, brw_imm_ud(24)),
brw_imm_ud(base_offset << 12));
inst->src[1] = component(tmp, 0);
}
break;
case LSC_ADDR_SURFTYPE_FLAT:
inst->src[1] = brw_imm_ud(0);
inst->src[1] = brw_imm_ud(lsc_flat_ex_desc(devinfo, base_offset_bits));
break;
default:
@@ -1490,11 +1522,14 @@ lower_lsc_memory_logical_send(const brw_builder &bld, brw_inst *inst)
brw_type_with_size(data0.type, data_size_B * 8);
const enum lsc_addr_size addr_size = lsc_addr_size_for_type(addr.type);
assert(inst->src[MEMORY_LOGICAL_ADDRESS_OFFSET].file == IMM);
const int32_t base_offset = inst->src[MEMORY_LOGICAL_ADDRESS_OFFSET].d;
const brw_reg base_offset =
retype(inst->src[MEMORY_LOGICAL_ADDRESS_OFFSET], BRW_TYPE_UD);
/* TODO: setup the offset */
assert(base_offset.ud == 0);
/**
* TGM messages cannot have a base offset
*/
if (mode == MEMORY_MODE_TYPED)
assert(base_offset == 0);
brw_reg payload = addr;
@@ -1596,7 +1631,7 @@ lower_lsc_memory_logical_send(const brw_builder &bld, brw_inst *inst)
transpose, cache_mode);
/* Set up extended descriptors, fills src[0] and src[1]. */
setup_lsc_surface_descriptors(bld, inst, inst->desc, binding);
setup_lsc_surface_descriptors(bld, inst, inst->desc, binding, base_offset);
inst->opcode = SHADER_OPCODE_SEND;
inst->mlen = lsc_msg_addr_len(devinfo, addr_size,
@@ -1678,9 +1713,8 @@ lower_hdc_memory_logical_send(const brw_builder &bld, brw_inst *inst)
const brw_reg data1 = inst->src[MEMORY_LOGICAL_DATA1];
const bool has_side_effects = inst->has_side_effects();
const bool has_dest = inst->dst.file != BAD_FILE && !inst->dst.is_null();
const brw_reg base_offset =
retype(inst->src[MEMORY_LOGICAL_ADDRESS_OFFSET], BRW_TYPE_UD);
assert(base_offset.ud == 0);
assert(inst->src[MEMORY_LOGICAL_ADDRESS_OFFSET].file == IMM &&
inst->src[MEMORY_LOGICAL_ADDRESS_OFFSET].d == 0);
/* Don't predicate scratch writes on the sample mask. Otherwise,
* FS helper invocations would load undefined values from scratch memory.
@@ -1986,7 +2020,7 @@ lower_lsc_varying_pull_constant_logical_send(const brw_builder &bld,
setup_lsc_surface_descriptors(bld, inst, inst->desc,
surface.file != BAD_FILE ?
surface : surface_handle);
surface : surface_handle, 0);
} else {
inst->desc =
lsc_msg_desc(devinfo, LSC_OP_LOAD,
@@ -1999,7 +2033,7 @@ lower_lsc_varying_pull_constant_logical_send(const brw_builder &bld,
setup_lsc_surface_descriptors(bld, inst, inst->desc,
surface.file != BAD_FILE ?
surface : surface_handle);
surface : surface_handle, 0);
/* The byte scattered messages can only read one dword at a time so
* we have to duplicate the message 4 times to read the full vec4.
@@ -2746,7 +2780,7 @@ brw_lower_uniform_pull_constant_loads(brw_shader &s)
inst->resize_sources(3);
setup_lsc_surface_descriptors(ubld, inst, inst->desc,
surface.file != BAD_FILE ?
surface : surface_handle);
surface : surface_handle, 0);
inst->src[2] = payload;
s.invalidate_analysis(BRW_DEPENDENCY_INSTRUCTIONS |
+3
View File
@@ -671,6 +671,9 @@ brw_print_instruction(const brw_shader &s, const brw_inst *inst, FILE *file, con
if (is_send && inst->ex_desc)
fprintf(file, "ExDesc 0x%08x ", inst->ex_desc);
if (is_send && inst->send_ex_desc_imm)
fprintf(file, "ExDescImmInst 0x%08x ", inst->offset);
if (inst->sched.regdist || inst->sched.mode) {
fprintf(file, "{ ");
brw_print_swsb(file, s.devinfo, inst->sched);