diff options
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_context.h | 5 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_defines.h | 18 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs.cpp | 25 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs.h | 4 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp | 11 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 29 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_wm.c | 42 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_wm.h | 1 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/gen6_wm_state.c | 3 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/gen7_wm_state.c | 3 |
10 files changed, 103 insertions, 38 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index ff25b093b47..4ae8580ac57 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -976,6 +976,11 @@ void brw_compute_vue_map(struct brw_vue_map *vue_map, GLbitfield64 outputs_written); gl_clip_plane *brw_select_clip_planes(struct gl_context *ctx); +/* brw_wm.c */ +unsigned +brw_compute_barycentric_interp_modes(void); + + /*====================================================================== * Inline conversion functions. These are better-typed than the diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h index 61a739c3a98..d302a61cdbc 100644 --- a/src/mesa/drivers/dri/i965/brw_defines.h +++ b/src/mesa/drivers/dri/i965/brw_defines.h @@ -1215,6 +1215,16 @@ enum brw_message_target { /* DW12: attr 0-7 wrap shortest enables */ /* DW13: attr 8-16 wrap shortest enables */ +enum brw_wm_barycentric_interp_mode { + BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC = 0, + BRW_WM_PERSPECTIVE_CENTROID_BARYCENTRIC = 1, + BRW_WM_PERSPECTIVE_SAMPLE_BARYCENTRIC = 2, + BRW_WM_NONPERSPECTIVE_PIXEL_BARYCENTRIC = 3, + BRW_WM_NONPERSPECTIVE_CENTROID_BARYCENTRIC = 4, + BRW_WM_NONPERSPECTIVE_SAMPLE_BARYCENTRIC = 5, + BRW_WM_BARYCENTRIC_INTERP_MODE_COUNT = 6 +}; + #define _3DSTATE_WM 0x7814 /* GEN6+ */ /* DW1: kernel pointer */ /* DW2 */ @@ -1269,6 +1279,7 @@ enum brw_message_target { # define GEN6_WM_PERSPECTIVE_SAMPLE_BARYCENTRIC (1 << 12) # define GEN6_WM_PERSPECTIVE_CENTROID_BARYCENTRIC (1 << 11) # define GEN6_WM_PERSPECTIVE_PIXEL_BARYCENTRIC (1 << 10) +# define GEN6_WM_BARYCENTRIC_INTERPOLATION_MODE_SHIFT 10 # define GEN6_WM_POINT_RASTRULE_UPPER_RIGHT (1 << 9) # define GEN6_WM_MSRAST_OFF_PIXEL (0 << 1) # define GEN6_WM_MSRAST_OFF_PATTERN (1 << 1) @@ -1306,12 +1317,7 @@ enum brw_message_target { # define GEN7_WM_POSITION_ZW_PIXEL (0 << 17) # define GEN7_WM_POSITION_ZW_CENTROID (2 << 17) # define GEN7_WM_POSITION_ZW_SAMPLE (3 << 17) -# define GEN7_WM_NONPERSPECTIVE_SAMPLE_BARYCENTRIC (1 << 16) -# define GEN7_WM_NONPERSPECTIVE_CENTROID_BARYCENTRIC (1 << 15) -# define GEN7_WM_NONPERSPECTIVE_PIXEL_BARYCENTRIC (1 << 14) -# define GEN7_WM_PERSPECTIVE_SAMPLE_BARYCENTRIC (1 << 13) -# define GEN7_WM_PERSPECTIVE_CENTROID_BARYCENTRIC (1 << 12) -# define GEN7_WM_PERSPECTIVE_PIXEL_BARYCENTRIC (1 << 11) +# define GEN7_WM_BARYCENTRIC_INTERPOLATION_MODE_SHIFT 11 # define GEN7_WM_USES_INPUT_COVERAGE_MASK (1 << 10) # define GEN7_WM_LINE_END_CAP_AA_WIDTH_0_5 (0 << 8) # define GEN7_WM_LINE_END_CAP_AA_WIDTH_1_0 (1 << 8) diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp index 3848915cf80..b3ad505b71e 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp @@ -407,8 +407,10 @@ fs_visitor::emit_fragcoord_interpolation(ir_variable *ir) emit(BRW_OPCODE_MOV, wpos, fs_reg(brw_vec8_grf(c->source_depth_reg, 0))); } else { - emit(FS_OPCODE_LINTERP, wpos, this->delta_x, this->delta_y, - interp_reg(FRAG_ATTRIB_WPOS, 2)); + emit(FS_OPCODE_LINTERP, wpos, + this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC], + this->delta_y[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC], + interp_reg(FRAG_ATTRIB_WPOS, 2)); } wpos.reg_offset++; @@ -481,8 +483,11 @@ fs_visitor::emit_general_interpolation(ir_variable *ir) emit(BRW_OPCODE_MOV, attr, fs_reg(1.0f)); } else { struct brw_reg interp = interp_reg(location, k); - emit(FS_OPCODE_LINTERP, attr, - this->delta_x, this->delta_y, fs_reg(interp)); + brw_wm_barycentric_interp_mode barycoord_mode = + BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC; + emit(FS_OPCODE_LINTERP, attr, + this->delta_x[barycoord_mode], + this->delta_y[barycoord_mode], fs_reg(interp)); } attr.reg_offset++; } @@ -768,9 +773,15 @@ fs_visitor::split_virtual_grfs() split_grf[i] = false; } - if (brw->has_pln && this->delta_x.file == GRF) { - /* PLN opcodes rely on the delta_xy being contiguous. */ - split_grf[this->delta_x.reg] = false; + if (brw->has_pln && + this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC].file == GRF) { + /* PLN opcodes rely on the delta_xy being contiguous. We only have to + * check this for BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC, because prior to + * Gen6, that was the only supported interpolation mode, and since Gen6, + * delta_x and delta_y are in fixed hardware registers. + */ + split_grf[this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC].reg] = + false; } foreach_list(node, &this->instructions) { diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h index f5af9ea936a..e2ad6499e95 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.h +++ b/src/mesa/drivers/dri/i965/brw_fs.h @@ -594,8 +594,8 @@ public: fs_reg pixel_y; fs_reg wpos_w; fs_reg pixel_w; - fs_reg delta_x; - fs_reg delta_y; + fs_reg delta_x[BRW_WM_BARYCENTRIC_INTERP_MODE_COUNT]; + fs_reg delta_y[BRW_WM_BARYCENTRIC_INTERP_MODE_COUNT]; fs_reg reg_null_cmp; int grf_used; diff --git a/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp b/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp index 6e38cc250e8..3f875cc63d9 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp @@ -202,8 +202,17 @@ fs_visitor::assign_regs() for (int i = 0; i < this->virtual_grf_next; i++) { for (int c = 0; c < class_count; c++) { if (class_sizes[c] == this->virtual_grf_sizes[i]) { + /* Special case: on pre-GEN6 hardware that supports PLN, the + * second operand of a PLN instruction needs to be an + * even-numbered register, so we have a special register class + * wm_aligned_pairs_class to handle this case. pre-GEN6 always + * uses this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC] as the + * second operand of a PLN instruction (since it doesn't support + * any other interpolation modes). So all we need to do is find + * that register and set it to the appropriate class. + */ if (brw->wm.aligned_pairs_class >= 0 && - this->delta_x.reg == i) { + this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC].reg == i) { ra_set_node_class(g, i, brw->wm.aligned_pairs_class); } else { ra_set_node_class(g, i, brw->wm.classes[c]); diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp index 215cdcdb022..2f95014d2a2 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp @@ -1754,16 +1754,20 @@ fs_visitor::emit_interpolation_setup_gen4() this->current_annotation = "compute pixel deltas from v0"; if (brw->has_pln) { - this->delta_x = fs_reg(this, glsl_type::vec2_type); - this->delta_y = this->delta_x; - this->delta_y.reg_offset++; + this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC] = + fs_reg(this, glsl_type::vec2_type); + this->delta_y[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC] = + this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC]; + this->delta_y[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC].reg_offset++; } else { - this->delta_x = fs_reg(this, glsl_type::float_type); - this->delta_y = fs_reg(this, glsl_type::float_type); + this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC] = + fs_reg(this, glsl_type::float_type); + this->delta_y[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC] = + fs_reg(this, glsl_type::float_type); } - emit(BRW_OPCODE_ADD, this->delta_x, + emit(BRW_OPCODE_ADD, this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC], this->pixel_x, fs_reg(negate(brw_vec1_grf(1, 0)))); - emit(BRW_OPCODE_ADD, this->delta_y, + emit(BRW_OPCODE_ADD, this->delta_y[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC], this->pixel_y, fs_reg(negate(brw_vec1_grf(1, 1)))); this->current_annotation = "compute pos.w and 1/pos.w"; @@ -1771,7 +1775,9 @@ fs_visitor::emit_interpolation_setup_gen4() * interpolate the other attributes. */ this->wpos_w = fs_reg(this, glsl_type::float_type); - emit(FS_OPCODE_LINTERP, wpos_w, this->delta_x, this->delta_y, + emit(FS_OPCODE_LINTERP, wpos_w, + this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC], + this->delta_y[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC], interp_reg(FRAG_ATTRIB_WPOS, 3)); /* Compute the pixel 1/W value from wpos.w. */ this->pixel_w = fs_reg(this, glsl_type::float_type); @@ -1814,8 +1820,11 @@ fs_visitor::emit_interpolation_setup_gen6() this->wpos_w = fs_reg(this, glsl_type::float_type); emit_math(SHADER_OPCODE_RCP, this->wpos_w, this->pixel_w); - this->delta_x = fs_reg(brw_vec8_grf(2, 0)); - this->delta_y = fs_reg(brw_vec8_grf(3, 0)); + for (int i = 0; i < BRW_WM_BARYCENTRIC_INTERP_MODE_COUNT; ++i) { + uint8_t reg = c->barycentric_coord_reg[i]; + this->delta_x[i] = fs_reg(brw_vec8_grf(reg, 0)); + this->delta_y[i] = fs_reg(brw_vec8_grf(reg + 1, 0)); + } this->current_annotation = NULL; } diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c index b60173ed4bf..81dad4f76da 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.c +++ b/src/mesa/drivers/dri/i965/brw_wm.c @@ -123,6 +123,19 @@ brw_wm_non_glsl_emit(struct brw_context *brw, struct brw_wm_compile *c) brw_wm_emit(c); } + +/** + * Return a bitfield where bit n is set if barycentric interpolation mode n + * (see enum brw_wm_barycentric_interp_mode) is needed by the fragment shader. + */ +unsigned +brw_compute_barycentric_interp_modes(void) +{ + /* At the moment the only interpolation mode we support is perspective. */ + return (1 << BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC); +} + + void brw_wm_payload_setup(struct brw_context *brw, struct brw_wm_compile *c) @@ -130,22 +143,31 @@ brw_wm_payload_setup(struct brw_context *brw, struct intel_context *intel = &brw->intel; bool uses_depth = (c->fp->program.Base.InputsRead & (1 << FRAG_ATTRIB_WPOS)) != 0; + unsigned barycentric_interp_modes = + brw_compute_barycentric_interp_modes(); + int i; if (intel->gen >= 6) { /* R0-1: masks, pixel X/Y coordinates. */ c->nr_payload_regs = 2; /* R2: only for 32-pixel dispatch.*/ - /* R3-4: perspective pixel location barycentric */ - c->nr_payload_regs += 2; - /* R5-6: perspective pixel location bary for dispatch width != 8 */ - if (c->dispatch_width == 16) { - c->nr_payload_regs += 2; + + /* R3-26: barycentric interpolation coordinates. These appear in the + * same order that they appear in the brw_wm_barycentric_interp_mode + * enum. Each set of coordinates occupies 2 registers if dispatch width + * == 8 and 4 registers if dispatch width == 16. Coordinates only + * appear if they were enabled using the "Barycentric Interpolation + * Mode" bits in WM_STATE. + */ + for (i = 0; i < BRW_WM_BARYCENTRIC_INTERP_MODE_COUNT; ++i) { + if (barycentric_interp_modes & (1 << i)) { + c->barycentric_coord_reg[i] = c->nr_payload_regs; + c->nr_payload_regs += 2; + if (c->dispatch_width == 16) { + c->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) { diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h index efd18e96bec..76cf4533b56 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.h +++ b/src/mesa/drivers/dri/i965/brw_wm.h @@ -215,6 +215,7 @@ struct brw_wm_compile { uint8_t source_w_reg; uint8_t aa_dest_stencil_reg; uint8_t dest_depth_reg; + uint8_t barycentric_coord_reg[BRW_WM_BARYCENTRIC_INTERP_MODE_COUNT]; uint8_t nr_payload_regs; GLuint computes_depth:1; /* could be derived from program string */ GLuint source_depth_to_render_target:1; diff --git a/src/mesa/drivers/dri/i965/gen6_wm_state.c b/src/mesa/drivers/dri/i965/gen6_wm_state.c index 24fc81dd240..178375f4133 100644 --- a/src/mesa/drivers/dri/i965/gen6_wm_state.c +++ b/src/mesa/drivers/dri/i965/gen6_wm_state.c @@ -178,7 +178,8 @@ upload_wm_state(struct brw_context *brw) dw5 |= GEN6_WM_DISPATCH_ENABLE; } - dw6 |= GEN6_WM_PERSPECTIVE_PIXEL_BARYCENTRIC; + dw6 |= brw_compute_barycentric_interp_modes() << + GEN6_WM_BARYCENTRIC_INTERPOLATION_MODE_SHIFT; dw6 |= _mesa_bitcount_64(brw->fragment_program->Base.InputsRead) << GEN6_WM_NUM_SF_OUTPUTS_SHIFT; diff --git a/src/mesa/drivers/dri/i965/gen7_wm_state.c b/src/mesa/drivers/dri/i965/gen7_wm_state.c index aae3c1164fb..fc23c2e1615 100644 --- a/src/mesa/drivers/dri/i965/gen7_wm_state.c +++ b/src/mesa/drivers/dri/i965/gen7_wm_state.c @@ -72,7 +72,8 @@ upload_wm_state(struct brw_context *brw) dw1 |= GEN7_WM_DISPATCH_ENABLE; } - dw1 |= GEN7_WM_PERSPECTIVE_PIXEL_BARYCENTRIC; + dw1 |= brw_compute_barycentric_interp_modes() << + GEN7_WM_BARYCENTRIC_INTERPOLATION_MODE_SHIFT; BEGIN_BATCH(3); OUT_BATCH(_3DSTATE_WM << 16 | (3 - 2)); |