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:
@@ -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];
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user