summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2010-08-20 16:05:04 -0700
committerZhenyu Wang <zhenyuw@linux.intel.com>2010-09-15 16:57:46 +0800
commitb6a68e4d90911804c8799118e027a8fafb051dc6 (patch)
treed1de91c27045710fa6fc1f626c98ec15a5405f83
parent84f7b5d974ba7601a7a43bbe307cc3dc95f221fa (diff)
i965: Add support for attribute interpolation on Sandybridge.
Things are simpler these days thanks to barycentric interpolation parameters being handed in in the payload.
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm.c53
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm.h7
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_emit.c12
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_fp.c26
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_glsl.c2
-rw-r--r--src/mesa/drivers/dri/i965/gen6_wm_state.c2
6 files changed, 88 insertions, 14 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c
index d70be7bda28..353410d72c4 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.c
+++ b/src/mesa/drivers/dri/i965/brw_wm.c
@@ -215,7 +215,8 @@ static void do_wm_prog( struct brw_context *brw,
static void brw_wm_populate_key( struct brw_context *brw,
struct brw_wm_prog_key *key )
{
- GLcontext *ctx = &brw->intel.ctx;
+ struct intel_context *intel = &brw->intel;
+ GLcontext *ctx = &intel->ctx;
/* BRW_NEW_FRAGMENT_PROGRAM */
const struct brw_fragment_program *fp =
(struct brw_fragment_program *)brw->fragment_program;
@@ -278,12 +279,50 @@ static void brw_wm_populate_key( struct brw_context *brw,
}
}
}
-
- brw_wm_lookup_iz(line_aa,
- lookup,
- uses_depth,
- key);
-
+ if (intel->gen >= 6) {
+ /* R0-1: masks, pixel X/Y coordinates. */
+ key->nr_payload_regs = 2;
+ /* R2: only for 32-pixel dispatch.*/
+ /* R3-4: perspective pixel location barycentric */
+ key->nr_payload_regs += 2;
+ /* R5-6: perspective pixel location bary for dispatch width != 8 */
+ if (!fp->isGLSL) { /* dispatch_width != 8 */
+ key->nr_payload_regs += 2;
+ }
+ /* R7-10: perspective centroid barycentric */
+ /* R11-14: perspective sample barycentric */
+ /* R15-18: linear pixel location barycentric */
+ /* R19-22: linear centroid barycentric */
+ /* R23-26: linear sample barycentric */
+
+ /* R27: interpolated depth if uses source depth */
+ if (uses_depth) {
+ key->source_depth_reg = key->nr_payload_regs;
+ key->nr_payload_regs++;
+ if (!fp->isGLSL) { /* dispatch_width != 8 */
+ /* R28: interpolated depth if not 8-wide. */
+ key->nr_payload_regs++;
+ }
+ }
+ /* R29: interpolated W set if GEN6_WM_USES_SOURCE_W.
+ */
+ if (uses_depth) {
+ key->source_w_reg = key->nr_payload_regs;
+ key->nr_payload_regs++;
+ if (!fp->isGLSL) { /* dispatch_width != 8 */
+ /* R30: interpolated W if not 8-wide. */
+ key->nr_payload_regs++;
+ }
+ }
+ /* R31: MSAA position offsets. */
+ /* R32-: bary for 32-pixel. */
+ /* R58-59: interp W for 32-pixel. */
+ } else {
+ brw_wm_lookup_iz(line_aa,
+ lookup,
+ uses_depth,
+ key);
+ }
/* BRW_NEW_WM_INPUT_DIMENSIONS */
key->proj_attrib_mask = brw->wm.input_size_masks[4-1];
diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h
index 2639d4f26b3..9b722f1aeda 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.h
+++ b/src/mesa/drivers/dri/i965/brw_wm.h
@@ -59,6 +59,7 @@
struct brw_wm_prog_key {
GLuint source_depth_reg:3;
+ GLuint source_w_reg:3;
GLuint aa_dest_stencil_reg:3;
GLuint dest_depth_reg:3;
GLuint nr_payload_regs:4;
@@ -182,6 +183,8 @@ struct brw_wm_instruction {
#define PROGRAM_PAYLOAD (PROGRAM_FILE_MAX)
#define PAYLOAD_DEPTH (FRAG_ATTRIB_MAX)
+#define PAYLOAD_W (FRAG_ATTRIB_MAX + 1)
+#define PAYLOAD_FP_REG_MAX (FRAG_ATTRIB_MAX + 2)
struct brw_wm_compile {
struct brw_compile func;
@@ -224,7 +227,7 @@ struct brw_wm_compile {
} payload;
- const struct brw_wm_ref *pass0_fp_reg[PROGRAM_PAYLOAD+1][256][4];
+ const struct brw_wm_ref *pass0_fp_reg[PAYLOAD_FP_REG_MAX][256][4];
struct brw_wm_ref undef_ref;
struct brw_wm_value undef_value;
@@ -252,7 +255,7 @@ struct brw_wm_compile {
struct {
GLboolean inited;
struct brw_reg reg;
- } wm_regs[PROGRAM_PAYLOAD+1][256][4];
+ } wm_regs[PAYLOAD_FP_REG_MAX][256][4];
GLboolean used_grf[BRW_WM_MAX_GRF];
GLuint first_free_grf;
diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c
index f3ad01b3fec..23915e106c8 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c
@@ -254,6 +254,8 @@ void emit_pixel_w(struct brw_wm_compile *c,
struct brw_compile *p = &c->func;
struct intel_context *intel = &p->brw->intel;
+ assert(intel->gen < 6);
+
/* Don't need this if all you are doing is interpolating color, for
* instance.
*/
@@ -288,7 +290,6 @@ void emit_pixel_w(struct brw_wm_compile *c,
}
}
-
void emit_linterp(struct brw_compile *p,
const struct brw_reg *dst,
GLuint mask,
@@ -307,7 +308,9 @@ void emit_linterp(struct brw_compile *p,
for (i = 0; i < 4; i++) {
if (mask & (1<<i)) {
- if (can_do_pln(intel, deltas)) {
+ if (intel->gen >= 6) {
+ brw_PLN(p, dst[i], interp[i], brw_vec8_grf(2, 0));
+ } else if (can_do_pln(intel, deltas)) {
brw_PLN(p, dst[i], interp[i], deltas[0]);
} else {
brw_LINE(p, brw_null_reg(), interp[i], deltas[0]);
@@ -330,6 +333,11 @@ void emit_pinterp(struct brw_compile *p,
GLuint nr = arg0[0].nr;
GLuint i;
+ if (intel->gen >= 6) {
+ emit_linterp(p, dst, mask, arg0, interp);
+ return;
+ }
+
interp[0] = brw_vec1_grf(nr, 0);
interp[1] = brw_vec1_grf(nr, 4);
interp[2] = brw_vec1_grf(nr+1, 0);
diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c
index 3870bf10fcb..a88b7bdea85 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_fp.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c
@@ -336,7 +336,13 @@ static struct prog_src_register get_delta_xy( struct brw_wm_compile *c )
static struct prog_src_register get_pixel_w( struct brw_wm_compile *c )
{
- if (src_is_undef(c->pixel_w)) {
+ /* This is only called for producing 1/w in pre-gen6 interp. for
+ * gen6, the interp opcodes don't use this argument.
+ */
+ if (c->func.brw->intel.gen >= 6)
+ return src_undef();
+
+ if (!src_is_undef(c->pixel_w)) {
struct prog_dst_register pixel_w = get_temp(c);
struct prog_src_register deltas = get_delta_xy(c);
struct prog_src_register interp_wpos = src_reg(PROGRAM_PAYLOAD, FRAG_ATTRIB_WPOS);
@@ -363,7 +369,13 @@ static void emit_interp( struct brw_wm_compile *c,
{
struct prog_dst_register dst = dst_reg(PROGRAM_INPUT, idx);
struct prog_src_register interp = src_reg(PROGRAM_PAYLOAD, idx);
- struct prog_src_register deltas = get_delta_xy(c);
+ struct prog_src_register deltas;
+
+ if (c->func.brw->intel.gen < 6) {
+ deltas = get_delta_xy(c);
+ } else {
+ deltas = src_undef();
+ }
/* Need to use PINTERP on attributes which have been
* multiplied by 1/W in the SF program, and LINTERP on those
@@ -1056,6 +1068,7 @@ static void print_insns( const struct prog_instruction *insn,
*/
void brw_wm_pass_fp( struct brw_wm_compile *c )
{
+ struct intel_context *intel = &c->func.brw->intel;
struct brw_fragment_program *fp = c->fp;
GLuint insn;
@@ -1067,7 +1080,14 @@ void brw_wm_pass_fp( struct brw_wm_compile *c )
}
c->pixel_xy = src_undef();
- c->delta_xy = src_undef();
+ if (intel->gen >= 6) {
+ /* The interpolation deltas come in as the perspective pixel
+ * location barycentric params.
+ */
+ c->delta_xy = src_reg(PROGRAM_PAYLOAD, PAYLOAD_DEPTH);
+ } else {
+ c->delta_xy = src_undef();
+ }
c->pixel_w = src_undef();
c->nr_fp_insns = 0;
c->fp->tex_units_used = 0x0;
diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
index 7d6724dc1c1..16617ab50ef 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
@@ -296,6 +296,8 @@ static void prealloc_reg(struct brw_wm_compile *c)
reg = brw_vec8_grf(0, 0);
set_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, i, reg);
}
+ set_reg(c, PROGRAM_PAYLOAD, PAYLOAD_W, 0,
+ brw_vec8_grf(c->key.source_w_reg, 0));
reg_index += c->key.nr_payload_regs;
/* constants */
diff --git a/src/mesa/drivers/dri/i965/gen6_wm_state.c b/src/mesa/drivers/dri/i965/gen6_wm_state.c
index 2cd640de175..afce1da6669 100644
--- a/src/mesa/drivers/dri/i965/gen6_wm_state.c
+++ b/src/mesa/drivers/dri/i965/gen6_wm_state.c
@@ -151,6 +151,8 @@ upload_wm_state(struct brw_context *brw)
if (fp->program.UsesKill || ctx->Color.AlphaEnabled)
dw5 |= GEN6_WM_KILL_ENABLE;
+ dw6 |= GEN6_WM_PERSPECTIVE_PIXEL_BARYCENTRIC;
+
/* This should probably be FS inputs read */
dw6 |= brw_count_bits(brw->vs.prog_data->outputs_written) <<
GEN6_WM_NUM_SF_OUTPUTS_SHIFT;