summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/i965/brw_eu_emit.c
diff options
context:
space:
mode:
authorBrian Paul <brianp@vmware.com>2009-04-15 16:49:18 -0600
committerBrian Paul <brianp@vmware.com>2009-04-16 11:08:23 -0600
commitee32e9b4753eca62e360f96ce61ef7ff683e6bb7 (patch)
treedd44f98c9d30cd94f512f8b99391b18b288e7a15 /src/mesa/drivers/dri/i965/brw_eu_emit.c
parent19ac3e2729abd85346f88fd69c6bc72938d26101 (diff)
i965: implement relative addressing for VS constant buffer reads
A scatter-read should be possible, but we're just using two READs for the time being.
Diffstat (limited to 'src/mesa/drivers/dri/i965/brw_eu_emit.c')
-rw-r--r--src/mesa/drivers/dri/i965/brw_eu_emit.c59
1 files changed, 55 insertions, 4 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c
index c731a93a8d..df2141660c 100644
--- a/src/mesa/drivers/dri/i965/brw_eu_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c
@@ -1003,15 +1003,18 @@ void brw_dp_READ_4( struct brw_compile *p,
/**
- * Read float[4] constant from VS constant buffer.
+ * Read float[4] constant(s) from VS constant buffer.
+ * For relative addressing, two float[4] constants will be read into 'dest'.
+ * Otherwise, one float[4] constant will be read into the lower half of 'dest'.
*/
void brw_dp_READ_4_vs(struct brw_compile *p,
struct brw_reg dest,
GLboolean relAddr,
+ struct brw_reg addrReg,
GLuint location,
GLuint bind_table_index)
{
- const GLuint msg_reg_nr = 1;
+ GLuint msg_reg_nr = 1;
/*
printf("vs const read msg, location %u, msg_reg_nr %d\n",
@@ -1034,7 +1037,12 @@ void brw_dp_READ_4_vs(struct brw_compile *p,
b = brw_message_reg(msg_reg_nr);
b = retype(b, BRW_REGISTER_TYPE_UD);
/*b = get_element_ud(b, 2);*/
- brw_MOV(p, b, brw_imm_ud(location));
+ if (relAddr) {
+ brw_ADD(p, b, addrReg, brw_imm_ud(location));
+ }
+ else {
+ brw_MOV(p, b, brw_imm_ud(location));
+ }
brw_pop_insn_state(p);
}
@@ -1053,13 +1061,56 @@ void brw_dp_READ_4_vs(struct brw_compile *p,
brw_set_dp_read_message(insn,
bind_table_index,
- 0, /* msg_control (0 means 1 Oword) */
+ 0, /* msg_control (0 means 1 Oword, lower half) */
BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ, /* msg_type */
0, /* source cache = data cache */
1, /* msg_length */
1, /* response_length (1 Oword) */
0); /* eot */
}
+
+ if (relAddr) {
+ /* second read to get second constant */
+ msg_reg_nr++;
+ {
+ /* Setup MRF[1] with location/offset into const buffer */
+ struct brw_reg b;
+
+ brw_push_insn_state(p);
+ brw_set_compression_control(p, BRW_COMPRESSION_NONE);
+ brw_set_mask_control(p, BRW_MASK_DISABLE);
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+
+ b = brw_message_reg(msg_reg_nr);
+ b = retype(b, BRW_REGISTER_TYPE_UD);
+ addrReg = suboffset(addrReg, 1); /* upper half of addrReg */
+ brw_ADD(p, b, addrReg, brw_imm_ud(location));
+
+ brw_pop_insn_state(p);
+ }
+
+ {
+ struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND);
+
+ insn->header.predicate_control = BRW_PREDICATE_NONE;
+ insn->header.compression_control = BRW_COMPRESSION_NONE;
+ insn->header.destreg__conditonalmod = msg_reg_nr;
+ insn->header.mask_control = BRW_MASK_DISABLE;
+ /*insn->header.access_mode = BRW_ALIGN_16;*/
+
+ brw_set_dest(insn, dest);
+ brw_set_src0(insn, brw_null_reg());
+
+ brw_set_dp_read_message(insn,
+ bind_table_index,
+ 1, /* msg_control (1 means 1 Oword, upper half) */
+ BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ, /* msg_type */
+ 0, /* source cache = data cache */
+ 1, /* msg_length */
+ 1, /* response_length (1 Oword) */
+ 0); /* eot */
+ }
+ }
}