summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZhenyu Wang <[email protected]>2010-08-20 15:02:19 -0700
committerEric Anholt <[email protected]>2010-08-20 16:17:40 -0700
commit5266c0a0c82de625ccac57e7559f57399f761e9e (patch)
treec2bba88a98351a0e49eeb8cd6162461be472f7fa
parent3ce2eccbfb925a3af0b91a89a9f7a3603fa45d2d (diff)
i965: Add support for FB writes on Sandybridge.
-rw-r--r--src/mesa/drivers/dri/i965/brw_eu_emit.c52
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_emit.c34
2 files changed, 74 insertions, 12 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c
index 523f119f435..c9b4770fd9a 100644
--- a/src/mesa/drivers/dri/i965/brw_eu_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c
@@ -372,9 +372,23 @@ static void brw_set_dp_write_message( struct brw_context *brw,
GLuint send_commit_msg)
{
struct intel_context *intel = &brw->intel;
- brw_set_src1(insn, brw_imm_d(0));
+ brw_set_src1(insn, brw_imm_ud(0));
- if (intel->gen == 5) {
+ if (intel->gen >= 6) {
+ insn->bits3.dp_render_cache.binding_table_index = binding_table_index;
+ insn->bits3.dp_render_cache.msg_control = msg_control;
+ insn->bits3.dp_render_cache.pixel_scoreboard_clear = pixel_scoreboard_clear;
+ insn->bits3.dp_render_cache.msg_type = msg_type;
+ insn->bits3.dp_render_cache.send_commit_msg = send_commit_msg;
+ insn->bits3.dp_render_cache.header_present = 0; /* XXX */
+ insn->bits3.dp_render_cache.response_length = response_length;
+ insn->bits3.dp_render_cache.msg_length = msg_length;
+ insn->bits3.dp_render_cache.end_of_thread = end_of_thread;
+ insn->header.destreg__conditionalmod = BRW_MESSAGE_TARGET_DATAPORT_WRITE;
+ /* XXX really need below? */
+ insn->bits2.send_gen5.sfid = BRW_MESSAGE_TARGET_DATAPORT_WRITE;
+ insn->bits2.send_gen5.end_of_thread = end_of_thread;
+ } else if (intel->gen == 5) {
insn->bits3.dp_write_gen5.binding_table_index = binding_table_index;
insn->bits3.dp_write_gen5.msg_control = msg_control;
insn->bits3.dp_write_gen5.pixel_scoreboard_clear = pixel_scoreboard_clear;
@@ -1344,22 +1358,40 @@ void brw_fb_WRITE(struct brw_compile *p,
GLuint response_length,
GLboolean eot)
{
- struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND);
-
+ struct intel_context *intel = &p->brw->intel;
+ struct brw_instruction *insn;
+ GLuint msg_control, msg_type;
+
+ insn = next_insn(p, BRW_OPCODE_SEND);
insn->header.predicate_control = 0; /* XXX */
- insn->header.compression_control = BRW_COMPRESSION_NONE;
- insn->header.destreg__conditionalmod = msg_reg_nr;
-
+ insn->header.compression_control = BRW_COMPRESSION_NONE;
+
+ if (intel->gen >= 6) {
+ /* headerless version, just submit color payload */
+ src0 = brw_message_reg(msg_reg_nr);
+
+ if (msg_length >= 8)
+ msg_control = BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE;
+ else
+ msg_control = BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_SINGLE_SOURCE_SUBSPAN01;
+ msg_type = BRW_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE_GEN6;
+ } else {
+ insn->header.destreg__conditionalmod = msg_reg_nr;
+
+ msg_control = BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE;
+ msg_type = BRW_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE;
+ }
+
brw_set_dest(insn, dest);
brw_set_src0(insn, src0);
brw_set_dp_write_message(p->brw,
insn,
binding_table_index,
- BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE, /* msg_control */
- BRW_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE, /* msg_type */
+ msg_control,
+ msg_type,
msg_length,
1, /* pixel scoreboard */
- response_length,
+ response_length,
eot,
0 /* send_commit_msg */);
}
diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c
index f2ace7d13d6..78de2ceda95 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c
@@ -1230,6 +1230,7 @@ static void fire_fb_write( struct brw_wm_compile *c,
GLuint eot )
{
struct brw_compile *p = &c->func;
+ struct intel_context *intel = &p->brw->intel;
struct brw_reg dst;
if (c->dispatch_width == 16)
@@ -1240,6 +1241,7 @@ static void fire_fb_write( struct brw_wm_compile *c,
/* Pass through control information:
*/
/* mov (8) m1.0<1>:ud r1.0<8;8,1>:ud { Align1 NoMask } */
+ if (intel->gen < 6) /* gen6, use headerless for fb write */
{
brw_push_insn_state(p);
brw_set_mask_control(p, BRW_MASK_DISABLE); /* ? */
@@ -1297,6 +1299,8 @@ void emit_fb_write(struct brw_wm_compile *c,
struct intel_context *intel = &brw->intel;
GLuint nr = 2;
GLuint channel;
+ int step = 0;
+ int base_reg; /* For gen6 fb write with no header, starting from color payload directly!. */
/* Reserve a space for AA - may not be needed:
*/
@@ -1308,6 +1312,11 @@ void emit_fb_write(struct brw_wm_compile *c,
*/
brw_push_insn_state(p);
+ if (intel->gen >= 6)
+ base_reg = nr;
+ else
+ base_reg = 0;
+
for (channel = 0; channel < 4; channel++) {
if (intel->gen >= 6) {
/* gen6 SIMD16 single source DP write looks like:
@@ -1339,6 +1348,16 @@ void emit_fb_write(struct brw_wm_compile *c,
brw_MOV(p,
brw_message_reg(nr + channel + BRW_MRF_COMPR4),
arg0[channel]);
+ } else if (intel->gen >= 6) {
+ brw_set_compression_control(p, BRW_COMPRESSION_NONE);
+ brw_MOV(p, brw_message_reg(nr + channel + step), arg0[channel]);
+ if (c->dispatch_width == 16) {
+ brw_set_compression_control(p, BRW_COMPRESSION_NONE);
+ brw_MOV(p,
+ brw_message_reg(nr + channel + step + 1),
+ sechalf(arg0[channel]));
+ ++step;
+ }
} else {
/* mov (8) m2.0<1>:ud r28.0<8;8,1>:ud { Align1 } */
/* mov (8) m6.0<1>:ud r29.0<8;8,1>:ud { Align1 SecHalf } */
@@ -1357,7 +1376,18 @@ void emit_fb_write(struct brw_wm_compile *c,
}
/* skip over the regs populated above:
*/
- nr += 8;
+ if (intel->gen < 6) {
+ nr += 8; /* XXX: always uses SIMD16 write currently. */
+ } else {
+ if (c->dispatch_width == 16)
+ nr += 8;
+ else
+ nr += 4;
+
+ /* Subtract off the message header, since we send headerless. */
+ nr -= 2;
+ }
+
brw_pop_insn_state(p);
if (c->key.source_depth_to_render_target)
@@ -1394,7 +1424,7 @@ void emit_fb_write(struct brw_wm_compile *c,
if (c->key.aa_dest_stencil_reg)
emit_aa(c, arg1, 2);
- fire_fb_write(c, 0, nr, target, eot);
+ fire_fb_write(c, base_reg, nr, target, eot);
}
else {
struct brw_reg v1_null_ud = vec1(retype(brw_null_reg(), BRW_REGISTER_TYPE_UD));