i965: Add support for attribute interpolation on Sandybridge.

Things are simpler these days thanks to barycentric interpolation
parameters being handed in in the payload.
This commit is contained in:
Eric Anholt
2010-09-26 13:28:51 +08:00
committed by Zhenyu Wang
parent 79d5657770
commit a66e9a4d86
6 changed files with 87 additions and 13 deletions
+45 -6
View File
@@ -279,13 +279,52 @@ static void brw_wm_populate_key( struct brw_context *brw,
}
}
}
brw_wm_lookup_iz(intel,
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(intel,
line_aa,
lookup,
uses_depth,
key);
}
/* BRW_NEW_WM_INPUT_DIMENSIONS */
key->proj_attrib_mask = brw->wm.input_size_masks[4-1];
+5 -2
View File
@@ -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;
+10 -2
View File
@@ -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);
+23 -3
View File
@@ -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;
+2
View File
@@ -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 */
@@ -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;