mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 13:10:10 +01:00
i965: Factor out logic to build a send message instruction with indirect descriptor.
This is going to be useful because the Gen7+ uniform and varying pull
constant, texturing, typed and untyped surface read, write, and atomic
generation code on the vec4 and fs back-end all require the same logic
to handle conditionally indirect surface indices. In pseudocode:
| if (surface.file == BRW_IMMEDIATE_VALUE) {
| inst = brw_SEND(p, dst, payload);
| set_descriptor_control_bits(inst, surface, ...);
| } else {
| inst = brw_OR(p, addr, surface, 0);
| set_descriptor_control_bits(inst, ...);
| inst = brw_SEND(p, dst, payload);
| set_indirect_send_descriptor(inst, addr);
| }
This patch abstracts out this frequently recurring pattern so we can
now write:
| inst = brw_send_indirect_message(p, sfid, dst, payload, surface)
| set_descriptor_control_bits(inst, ...);
without worrying about handling the immediate and indirect surface
index cases explicitly.
v2: Rebase. Improve documentatation and commit message. (Topi)
Preserve UW destination type cargo-cult. (Topi, Ken, Matt)
Reviewed-by: Topi Pohjolainen <topi.pohjolainen@intel.com>
Acked-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
parent
fd149628e1
commit
a902a5d6ba
4 changed files with 83 additions and 96 deletions
|
|
@ -205,11 +205,6 @@ void brw_set_sampler_message(struct brw_compile *p,
|
|||
unsigned simd_mode,
|
||||
unsigned return_format);
|
||||
|
||||
void brw_set_indirect_send_descriptor(struct brw_compile *p,
|
||||
brw_inst *insn,
|
||||
unsigned sfid,
|
||||
struct brw_reg descriptor);
|
||||
|
||||
void brw_set_dp_read_message(struct brw_compile *p,
|
||||
brw_inst *insn,
|
||||
unsigned binding_table_index,
|
||||
|
|
@ -242,6 +237,22 @@ void brw_urb_WRITE(struct brw_compile *p,
|
|||
unsigned offset,
|
||||
unsigned swizzle);
|
||||
|
||||
/**
|
||||
* Send message to shared unit \p sfid with a possibly indirect descriptor \p
|
||||
* desc. If \p desc is not an immediate it will be transparently loaded to an
|
||||
* address register using an OR instruction. The returned instruction can be
|
||||
* passed as argument to the usual brw_set_*_message() functions in order to
|
||||
* specify any additional descriptor bits -- If \p desc is an immediate this
|
||||
* will be the SEND instruction itself, otherwise it will be the OR
|
||||
* instruction.
|
||||
*/
|
||||
struct brw_inst *
|
||||
brw_send_indirect_message(struct brw_compile *p,
|
||||
unsigned sfid,
|
||||
struct brw_reg dst,
|
||||
struct brw_reg payload,
|
||||
struct brw_reg desc);
|
||||
|
||||
void brw_ff_sync(struct brw_compile *p,
|
||||
struct brw_reg dest,
|
||||
unsigned msg_reg_nr,
|
||||
|
|
|
|||
|
|
@ -772,21 +772,6 @@ brw_set_sampler_message(struct brw_compile *p,
|
|||
}
|
||||
}
|
||||
|
||||
void brw_set_indirect_send_descriptor(struct brw_compile *p,
|
||||
brw_inst *insn,
|
||||
unsigned sfid,
|
||||
struct brw_reg descriptor)
|
||||
{
|
||||
/* Only a0.0 may be used as SEND's descriptor operand. */
|
||||
assert(descriptor.file == BRW_ARCHITECTURE_REGISTER_FILE);
|
||||
assert(descriptor.type == BRW_REGISTER_TYPE_UD);
|
||||
assert(descriptor.nr == BRW_ARF_ADDRESS);
|
||||
assert(descriptor.subnr == 0);
|
||||
|
||||
brw_set_message_descriptor(p, insn, sfid, 0, 0, false, false);
|
||||
brw_set_src1(p, insn, descriptor);
|
||||
}
|
||||
|
||||
static void
|
||||
gen7_set_dp_scratch_message(struct brw_compile *p,
|
||||
brw_inst *inst,
|
||||
|
|
@ -2496,6 +2481,49 @@ void brw_urb_WRITE(struct brw_compile *p,
|
|||
swizzle);
|
||||
}
|
||||
|
||||
struct brw_inst *
|
||||
brw_send_indirect_message(struct brw_compile *p,
|
||||
unsigned sfid,
|
||||
struct brw_reg dst,
|
||||
struct brw_reg payload,
|
||||
struct brw_reg desc)
|
||||
{
|
||||
const struct brw_context *brw = p->brw;
|
||||
struct brw_inst *send, *setup;
|
||||
|
||||
assert(desc.type == BRW_REGISTER_TYPE_UD);
|
||||
|
||||
if (desc.file == BRW_IMMEDIATE_VALUE) {
|
||||
setup = send = next_insn(p, BRW_OPCODE_SEND);
|
||||
brw_set_src1(p, send, desc);
|
||||
|
||||
} else {
|
||||
struct brw_reg addr = retype(brw_address_reg(0), BRW_REGISTER_TYPE_UD);
|
||||
|
||||
brw_push_insn_state(p);
|
||||
brw_set_default_access_mode(p, BRW_ALIGN_1);
|
||||
brw_set_default_mask_control(p, BRW_MASK_DISABLE);
|
||||
brw_set_default_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
|
||||
/* Load the indirect descriptor to an address register using OR so the
|
||||
* caller can specify additional descriptor bits with the usual
|
||||
* brw_set_*_message() helper functions.
|
||||
*/
|
||||
setup = brw_OR(p, addr, desc, brw_imm_ud(0));
|
||||
|
||||
brw_pop_insn_state(p);
|
||||
|
||||
send = next_insn(p, BRW_OPCODE_SEND);
|
||||
brw_set_src1(p, send, addr);
|
||||
}
|
||||
|
||||
brw_set_dest(p, send, dst);
|
||||
brw_set_src0(p, send, retype(payload, BRW_REGISTER_TYPE_UD));
|
||||
brw_inst_set_sfid(brw, send, sfid);
|
||||
|
||||
return setup;
|
||||
}
|
||||
|
||||
static int
|
||||
brw_find_next_block_end(struct brw_compile *p, int start_offset)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -762,9 +762,10 @@ fs_generator::generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src
|
|||
brw_AND(p, addr, addr, brw_imm_ud(0x0ff));
|
||||
brw_OR(p, addr, addr, temp);
|
||||
|
||||
/* a0.0 |= <descriptor> */
|
||||
brw_inst *insn_or = brw_next_insn(p, BRW_OPCODE_OR);
|
||||
brw_set_sampler_message(p, insn_or,
|
||||
/* dst = send(offset, a0.0 | <descriptor>) */
|
||||
brw_inst *insn = brw_send_indirect_message(
|
||||
p, BRW_SFID_SAMPLER, dst, src, addr);
|
||||
brw_set_sampler_message(p, insn,
|
||||
0 /* surface */,
|
||||
0 /* sampler */,
|
||||
msg_type,
|
||||
|
|
@ -773,17 +774,6 @@ fs_generator::generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src
|
|||
inst->header_present /* header */,
|
||||
simd_mode,
|
||||
return_format);
|
||||
brw_inst_set_exec_size(p->brw, insn_or, BRW_EXECUTE_1);
|
||||
brw_inst_set_src1_reg_type(p->brw, insn_or, BRW_REGISTER_TYPE_UD);
|
||||
brw_set_src0(p, insn_or, addr);
|
||||
brw_set_dest(p, insn_or, addr);
|
||||
|
||||
|
||||
/* dst = send(offset, a0.0) */
|
||||
brw_inst *insn_send = brw_next_insn(p, BRW_OPCODE_SEND);
|
||||
brw_set_dest(p, insn_send, dst);
|
||||
brw_set_src0(p, insn_send, src);
|
||||
brw_set_indirect_send_descriptor(p, insn_send, BRW_SFID_SAMPLER, addr);
|
||||
|
||||
brw_pop_insn_state(p);
|
||||
|
||||
|
|
@ -1091,29 +1081,18 @@ fs_generator::generate_uniform_pull_constant_load_gen7(fs_inst *inst,
|
|||
brw_set_src0(p, insn_and, vec1(retype(index, BRW_REGISTER_TYPE_UD)));
|
||||
brw_set_src1(p, insn_and, brw_imm_ud(0x0ff));
|
||||
|
||||
|
||||
/* a0.0 |= <descriptor> */
|
||||
brw_inst *insn_or = brw_next_insn(p, BRW_OPCODE_OR);
|
||||
brw_set_sampler_message(p, insn_or,
|
||||
0 /* surface */,
|
||||
0 /* sampler */,
|
||||
/* dst = send(payload, a0.0 | <descriptor>) */
|
||||
brw_inst *insn = brw_send_indirect_message(
|
||||
p, BRW_SFID_SAMPLER, dst, src, addr);
|
||||
brw_set_sampler_message(p, insn,
|
||||
0,
|
||||
0, /* LD message ignores sampler unit */
|
||||
GEN5_SAMPLER_MESSAGE_SAMPLE_LD,
|
||||
1 /* rlen */,
|
||||
1, /* rlen */
|
||||
mlen,
|
||||
header_present,
|
||||
BRW_SAMPLER_SIMD_MODE_SIMD4X2,
|
||||
0);
|
||||
brw_inst_set_exec_size(p->brw, insn_or, BRW_EXECUTE_1);
|
||||
brw_inst_set_src1_reg_type(p->brw, insn_or, BRW_REGISTER_TYPE_UD);
|
||||
brw_set_src0(p, insn_or, addr);
|
||||
brw_set_dest(p, insn_or, addr);
|
||||
|
||||
|
||||
/* dst = send(offset, a0.0) */
|
||||
brw_inst *insn_send = brw_next_insn(p, BRW_OPCODE_SEND);
|
||||
brw_set_dest(p, insn_send, dst);
|
||||
brw_set_src0(p, insn_send, src);
|
||||
brw_set_indirect_send_descriptor(p, insn_send, BRW_SFID_SAMPLER, addr);
|
||||
|
||||
brw_pop_insn_state(p);
|
||||
|
||||
|
|
@ -1250,10 +1229,11 @@ fs_generator::generate_varying_pull_constant_load_gen7(fs_inst *inst,
|
|||
brw_set_src0(p, insn_and, vec1(retype(index, BRW_REGISTER_TYPE_UD)));
|
||||
brw_set_src1(p, insn_and, brw_imm_ud(0x0ff));
|
||||
|
||||
|
||||
/* a0.0 |= <descriptor> */
|
||||
brw_inst *insn_or = brw_next_insn(p, BRW_OPCODE_OR);
|
||||
brw_set_sampler_message(p, insn_or,
|
||||
/* dst = send(offset, a0.0 | <descriptor>) */
|
||||
brw_inst *insn = brw_send_indirect_message(
|
||||
p, BRW_SFID_SAMPLER, retype(dst, BRW_REGISTER_TYPE_UW),
|
||||
offset, addr);
|
||||
brw_set_sampler_message(p, insn,
|
||||
0 /* surface */,
|
||||
0 /* sampler */,
|
||||
GEN5_SAMPLER_MESSAGE_SAMPLE_LD,
|
||||
|
|
@ -1262,17 +1242,6 @@ fs_generator::generate_varying_pull_constant_load_gen7(fs_inst *inst,
|
|||
false /* header */,
|
||||
simd_mode,
|
||||
0);
|
||||
brw_inst_set_exec_size(p->brw, insn_or, BRW_EXECUTE_1);
|
||||
brw_inst_set_src1_reg_type(p->brw, insn_or, BRW_REGISTER_TYPE_UD);
|
||||
brw_set_src0(p, insn_or, addr);
|
||||
brw_set_dest(p, insn_or, addr);
|
||||
|
||||
|
||||
/* dst = send(offset, a0.0) */
|
||||
brw_inst *insn_send = brw_next_insn(p, BRW_OPCODE_SEND);
|
||||
brw_set_dest(p, insn_send, retype(dst, BRW_REGISTER_TYPE_UW));
|
||||
brw_set_src0(p, insn_send, offset);
|
||||
brw_set_indirect_send_descriptor(p, insn_send, BRW_SFID_SAMPLER, addr);
|
||||
|
||||
brw_pop_insn_state(p);
|
||||
|
||||
|
|
|
|||
|
|
@ -419,9 +419,10 @@ vec4_generator::generate_tex(vec4_instruction *inst,
|
|||
brw_AND(p, addr, addr, brw_imm_ud(0x0ff));
|
||||
brw_OR(p, addr, addr, temp);
|
||||
|
||||
/* a0.0 |= <descriptor> */
|
||||
brw_inst *insn_or = brw_next_insn(p, BRW_OPCODE_OR);
|
||||
brw_set_sampler_message(p, insn_or,
|
||||
/* dst = send(offset, a0.0 | <descriptor>) */
|
||||
brw_inst *insn = brw_send_indirect_message(
|
||||
p, BRW_SFID_SAMPLER, dst, src, addr);
|
||||
brw_set_sampler_message(p, insn,
|
||||
0 /* surface */,
|
||||
0 /* sampler */,
|
||||
msg_type,
|
||||
|
|
@ -430,17 +431,6 @@ vec4_generator::generate_tex(vec4_instruction *inst,
|
|||
inst->header_present /* header */,
|
||||
BRW_SAMPLER_SIMD_MODE_SIMD4X2,
|
||||
return_format);
|
||||
brw_inst_set_exec_size(p->brw, insn_or, BRW_EXECUTE_1);
|
||||
brw_inst_set_src1_reg_type(p->brw, insn_or, BRW_REGISTER_TYPE_UD);
|
||||
brw_set_src0(p, insn_or, addr);
|
||||
brw_set_dest(p, insn_or, addr);
|
||||
|
||||
|
||||
/* dst = send(offset, a0.0) */
|
||||
brw_inst *insn_send = brw_next_insn(p, BRW_OPCODE_SEND);
|
||||
brw_set_dest(p, insn_send, dst);
|
||||
brw_set_src0(p, insn_send, src);
|
||||
brw_set_indirect_send_descriptor(p, insn_send, BRW_SFID_SAMPLER, addr);
|
||||
|
||||
brw_pop_insn_state(p);
|
||||
|
||||
|
|
@ -1101,10 +1091,10 @@ vec4_generator::generate_pull_constant_load_gen7(vec4_instruction *inst,
|
|||
brw_set_src0(p, insn_and, vec1(retype(surf_index, BRW_REGISTER_TYPE_UD)));
|
||||
brw_set_src1(p, insn_and, brw_imm_ud(0x0ff));
|
||||
|
||||
|
||||
/* a0.0 |= <descriptor> */
|
||||
brw_inst *insn_or = brw_next_insn(p, BRW_OPCODE_OR);
|
||||
brw_set_sampler_message(p, insn_or,
|
||||
/* dst = send(offset, a0.0 | <descriptor>) */
|
||||
brw_inst *insn = brw_send_indirect_message(
|
||||
p, BRW_SFID_SAMPLER, dst, src, addr);
|
||||
brw_set_sampler_message(p, insn,
|
||||
0 /* surface */,
|
||||
0 /* sampler */,
|
||||
GEN5_SAMPLER_MESSAGE_SAMPLE_LD,
|
||||
|
|
@ -1113,17 +1103,6 @@ vec4_generator::generate_pull_constant_load_gen7(vec4_instruction *inst,
|
|||
header_present /* header */,
|
||||
BRW_SAMPLER_SIMD_MODE_SIMD4X2,
|
||||
0);
|
||||
brw_inst_set_exec_size(p->brw, insn_or, BRW_EXECUTE_1);
|
||||
brw_inst_set_src1_reg_type(p->brw, insn_or, BRW_REGISTER_TYPE_UD);
|
||||
brw_set_src0(p, insn_or, addr);
|
||||
brw_set_dest(p, insn_or, addr);
|
||||
|
||||
|
||||
/* dst = send(offset, a0.0) */
|
||||
brw_inst *insn_send = brw_next_insn(p, BRW_OPCODE_SEND);
|
||||
brw_set_dest(p, insn_send, dst);
|
||||
brw_set_src0(p, insn_send, src);
|
||||
brw_set_indirect_send_descriptor(p, insn_send, BRW_SFID_SAMPLER, addr);
|
||||
|
||||
brw_pop_insn_state(p);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue