intel/eu: Add a mechanism for emitting relocatable constant MOVs
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6244>
This commit is contained in:

committed by
Marge Bot

parent
272ab2823d
commit
8d8a3815ef
@@ -267,3 +267,22 @@ brw_prog_key_size(gl_shader_stage stage)
|
||||
assert((int)stage >= 0 && stage < ARRAY_SIZE(stage_sizes));
|
||||
return stage_sizes[stage];
|
||||
}
|
||||
|
||||
void
|
||||
brw_write_shader_relocs(const struct gen_device_info *devinfo,
|
||||
void *program,
|
||||
const struct brw_stage_prog_data *prog_data,
|
||||
struct brw_shader_reloc_value *values,
|
||||
unsigned num_values)
|
||||
{
|
||||
for (unsigned i = 0; i < prog_data->num_relocs; i++) {
|
||||
assert(prog_data->relocs[i].offset % 8 == 0);
|
||||
brw_inst *inst = (brw_inst *)(program + prog_data->relocs[i].offset);
|
||||
for (unsigned j = 0; j < num_values; j++) {
|
||||
if (prog_data->relocs[i].id == values[j].id) {
|
||||
brw_update_reloc_imm(devinfo, inst, values[j].value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -642,6 +642,32 @@ enum brw_param_builtin {
|
||||
#define BRW_PARAM_BUILTIN_CLIP_PLANE_COMP(param) \
|
||||
(((param) - BRW_PARAM_BUILTIN_CLIP_PLANE_0_X) & 0x3)
|
||||
|
||||
/** Represents a code relocation
|
||||
*
|
||||
* Relocatable constants are immediates in the code which we want to be able
|
||||
* to replace post-compile with the actual value.
|
||||
*/
|
||||
struct brw_shader_reloc {
|
||||
/** The 32-bit ID of the relocatable constant */
|
||||
uint32_t id;
|
||||
|
||||
/** The offset in the shader to the relocatable instruction
|
||||
*
|
||||
* This is the offset to the instruction rather than the immediate value
|
||||
* itself. This allows us to do some sanity checking while we relocate.
|
||||
*/
|
||||
uint32_t offset;
|
||||
};
|
||||
|
||||
/** A value to write to a relocation */
|
||||
struct brw_shader_reloc_value {
|
||||
/** The 32-bit ID of the relocatable constant */
|
||||
uint32_t id;
|
||||
|
||||
/** The value with which to replace the relocated immediate */
|
||||
uint32_t value;
|
||||
};
|
||||
|
||||
struct brw_stage_prog_data {
|
||||
struct {
|
||||
/** size of our binding table. */
|
||||
@@ -688,6 +714,9 @@ struct brw_stage_prog_data {
|
||||
unsigned const_data_size;
|
||||
unsigned const_data_offset;
|
||||
|
||||
unsigned num_relocs;
|
||||
const struct brw_shader_reloc *relocs;
|
||||
|
||||
/** Does this program pull from any UBO or other constant buffers? */
|
||||
bool has_ubo_pull;
|
||||
|
||||
@@ -1535,6 +1564,13 @@ brw_cs_simd_size_for_group_size(const struct gen_device_info *devinfo,
|
||||
const struct brw_cs_prog_data *cs_prog_data,
|
||||
unsigned group_size);
|
||||
|
||||
void
|
||||
brw_write_shader_relocs(const struct gen_device_info *devinfo,
|
||||
void *program,
|
||||
const struct brw_stage_prog_data *prog_data,
|
||||
struct brw_shader_reloc_value *values,
|
||||
unsigned num_values);
|
||||
|
||||
/**
|
||||
* Calculate the RightExecutionMask field used in GPGPU_WALKER.
|
||||
*/
|
||||
|
@@ -363,6 +363,13 @@ const unsigned *brw_get_program( struct brw_codegen *p,
|
||||
return (const unsigned *)p->store;
|
||||
}
|
||||
|
||||
const brw_shader_reloc *
|
||||
brw_get_shader_relocs(struct brw_codegen *p, unsigned *num_relocs)
|
||||
{
|
||||
*num_relocs = p->num_relocs;
|
||||
return p->relocs;
|
||||
}
|
||||
|
||||
bool brw_try_override_assembly(struct brw_codegen *p, int start_offset,
|
||||
const char *identifier)
|
||||
{
|
||||
|
@@ -136,6 +136,10 @@ struct brw_codegen {
|
||||
int *if_depth_in_loop;
|
||||
int loop_stack_depth;
|
||||
int loop_stack_array_size;
|
||||
|
||||
struct brw_shader_reloc *relocs;
|
||||
int num_relocs;
|
||||
int reloc_array_size;
|
||||
};
|
||||
|
||||
struct brw_label {
|
||||
@@ -184,6 +188,8 @@ void brw_disassemble_with_labels(const struct gen_device_info *devinfo,
|
||||
void brw_disassemble(const struct gen_device_info *devinfo,
|
||||
const void *assembly, int start, int end,
|
||||
const struct brw_label *root_label, FILE *out);
|
||||
const struct brw_shader_reloc *brw_get_shader_relocs(struct brw_codegen *p,
|
||||
unsigned *num_relocs);
|
||||
const unsigned *brw_get_program( struct brw_codegen *p, unsigned *sz );
|
||||
|
||||
bool brw_try_override_assembly(struct brw_codegen *p, int start_offset,
|
||||
@@ -1238,6 +1244,17 @@ void
|
||||
brw_float_controls_mode(struct brw_codegen *p,
|
||||
unsigned mode, unsigned mask);
|
||||
|
||||
void
|
||||
brw_update_reloc_imm(const struct gen_device_info *devinfo,
|
||||
brw_inst *inst,
|
||||
uint32_t value);
|
||||
|
||||
void
|
||||
brw_MOV_reloc_imm(struct brw_codegen *p,
|
||||
struct brw_reg dst,
|
||||
enum brw_reg_type src_type,
|
||||
uint32_t id);
|
||||
|
||||
/***********************************************************************
|
||||
* brw_eu_util.c:
|
||||
*/
|
||||
|
@@ -2446,6 +2446,15 @@ brw_compact_instructions(struct brw_codegen *p, int start_offset,
|
||||
}
|
||||
p->nr_insn = p->next_insn_offset / sizeof(brw_inst);
|
||||
|
||||
for (int i = 0; i < p->num_relocs; i++) {
|
||||
if (p->relocs[i].offset < (uint32_t)start_offset)
|
||||
continue;
|
||||
|
||||
assert(p->relocs[i].offset % 16 == 0);
|
||||
unsigned idx = (p->relocs[i].offset - start_offset) / 16;
|
||||
p->relocs[i].offset -= compacted_counts[idx] * 8;
|
||||
}
|
||||
|
||||
/* Update the instruction offsets for each group. */
|
||||
if (disasm) {
|
||||
int offset = 0;
|
||||
|
@@ -3641,3 +3641,46 @@ brw_float_controls_mode(struct brw_codegen *p,
|
||||
if (p->devinfo->gen >= 12)
|
||||
brw_SYNC(p, TGL_SYNC_NOP);
|
||||
}
|
||||
|
||||
void
|
||||
brw_update_reloc_imm(const struct gen_device_info *devinfo,
|
||||
brw_inst *inst,
|
||||
uint32_t value)
|
||||
{
|
||||
/* Sanity check that the instruction is a MOV of an immediate */
|
||||
assert(brw_inst_opcode(devinfo, inst) == BRW_OPCODE_MOV);
|
||||
assert(brw_inst_src0_reg_file(devinfo, inst) == BRW_IMMEDIATE_VALUE);
|
||||
|
||||
/* If it was compacted, we can't safely rewrite */
|
||||
assert(brw_inst_cmpt_control(devinfo, inst) == 0);
|
||||
|
||||
brw_inst_set_imm_ud(devinfo, inst, value);
|
||||
}
|
||||
|
||||
/* A default value for constants that will be patched at run-time.
|
||||
* We pick an arbitrary value that prevents instruction compaction.
|
||||
*/
|
||||
#define DEFAULT_PATCH_IMM 0x4a7cc037
|
||||
|
||||
void
|
||||
brw_MOV_reloc_imm(struct brw_codegen *p,
|
||||
struct brw_reg dst,
|
||||
enum brw_reg_type src_type,
|
||||
uint32_t id)
|
||||
{
|
||||
assert(type_sz(src_type) == 4);
|
||||
assert(type_sz(dst.type) == 4);
|
||||
|
||||
if (p->num_relocs + 1 > p->reloc_array_size) {
|
||||
p->reloc_array_size = MAX2(16, p->reloc_array_size * 2);
|
||||
p->relocs = reralloc(p->mem_ctx, p->relocs,
|
||||
struct brw_shader_reloc, p->reloc_array_size);
|
||||
}
|
||||
|
||||
p->relocs[p->num_relocs++] = (struct brw_shader_reloc) {
|
||||
.id = id,
|
||||
.offset = p->next_insn_offset,
|
||||
};
|
||||
|
||||
brw_MOV(p, dst, retype(brw_imm_ud(DEFAULT_PATCH_IMM), src_type));
|
||||
}
|
||||
|
Reference in New Issue
Block a user