i965/vec4: Generate indirect sends for nonconstant UBO array access

Signed-off-by: Chris Forbes <chrisf@ijw.co.nz>
This commit is contained in:
Chris Forbes
2014-07-13 11:43:11 +12:00
parent ad9fce6811
commit a55eae9b6d
@@ -840,23 +840,70 @@ vec4_generator::generate_pull_constant_load_gen7(vec4_instruction *inst,
struct brw_reg surf_index,
struct brw_reg offset)
{
assert(surf_index.file == BRW_IMMEDIATE_VALUE &&
surf_index.type == BRW_REGISTER_TYPE_UD);
assert(surf_index.type == BRW_REGISTER_TYPE_UD);
brw_inst *insn = brw_next_insn(p, BRW_OPCODE_SEND);
brw_set_dest(p, insn, dst);
brw_set_src0(p, insn, offset);
brw_set_sampler_message(p, insn,
surf_index.dw1.ud,
0, /* LD message ignores sampler unit */
GEN5_SAMPLER_MESSAGE_SAMPLE_LD,
1, /* rlen */
1, /* mlen */
false, /* no header */
BRW_SAMPLER_SIMD_MODE_SIMD4X2,
0);
if (surf_index.file == BRW_IMMEDIATE_VALUE) {
brw_mark_surface_used(&prog_data->base, surf_index.dw1.ud);
brw_inst *insn = brw_next_insn(p, BRW_OPCODE_SEND);
brw_set_dest(p, insn, dst);
brw_set_src0(p, insn, offset);
brw_set_sampler_message(p, insn,
surf_index.dw1.ud,
0, /* LD message ignores sampler unit */
GEN5_SAMPLER_MESSAGE_SAMPLE_LD,
1, /* rlen */
1, /* mlen */
false, /* no header */
BRW_SAMPLER_SIMD_MODE_SIMD4X2,
0);
brw_mark_surface_used(&prog_data->base, surf_index.dw1.ud);
} else {
struct brw_reg addr = vec1(retype(brw_address_reg(0), BRW_REGISTER_TYPE_UD));
brw_push_insn_state(p);
brw_set_default_mask_control(p, BRW_MASK_DISABLE);
brw_set_default_access_mode(p, BRW_ALIGN_1);
/* a0.0 = surf_index & 0xff */
brw_inst *insn_and = brw_next_insn(p, BRW_OPCODE_AND);
brw_inst_set_exec_size(p->brw, insn_and, BRW_EXECUTE_1);
brw_set_dest(p, insn_and, addr);
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,
0 /* surface */,
0 /* sampler */,
GEN5_SAMPLER_MESSAGE_SAMPLE_LD,
1 /* rlen */,
1 /* mlen */,
false /* 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, offset);
brw_set_indirect_send_descriptor(p, insn_send, BRW_SFID_SAMPLER, addr);
brw_pop_insn_state(p);
/* visitor knows more than we do about the surface limit required,
* so has already done marking.
*/
}
}
void