From ce9c44d357d43e59f2dc04eb29fd9ac8c2cef5fc Mon Sep 17 00:00:00 2001 From: Iago Toral Quiroga Date: Mon, 26 May 2014 13:11:41 +0200 Subject: [PATCH 1/2] i965: Always set a valid block end pointer When a instruction stream ends in a block structure (like a IF/ELSE/ENDIF) the last block's end pointer will not be set, leading to a crash later on in fs_live_variables::setup_def_use(). If we have not assigned the end pointer of the last block, set it to the last instruction. --- src/mesa/drivers/dri/i965/brw_cfg.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/mesa/drivers/dri/i965/brw_cfg.cpp b/src/mesa/drivers/dri/i965/brw_cfg.cpp index 6bf99f1..d4647c4 100644 --- a/src/mesa/drivers/dri/i965/brw_cfg.cpp +++ b/src/mesa/drivers/dri/i965/brw_cfg.cpp @@ -257,6 +257,11 @@ cfg_t::cfg_t(exec_list *instructions) } } + /* If the instruction stream ended with a block structure we need to + set the block's end pointer to the last instruction here */ + if (!cur->end) + cur->end = (backend_instruction *)instructions->get_tail(); + cur->end_ip = ip; make_block_array(); -- 1.9.2 From 7259513227ba612272cc3924b786608ce4644648 Mon Sep 17 00:00:00 2001 From: Iago Toral Quiroga Date: Mon, 26 May 2014 13:23:27 +0200 Subject: [PATCH 2/2] i965: Add runtime checks for line antialiasing in Gen < 6. In Gen < 6 the hardware generates a runtime bit that indicates whether AA data has to be sent as part of the framebuffer write SEND message. This affects the specific case where we have setup antialiased line rendering and we render polygons which have one face setup in GL_LINE mode (line antialiasing will be used) and the other one in GL_FILL mode (no line antialiasing needed). Currently we are not doing this runtime test and instead we always send AA data, which produces incorrect rendering of the GL_FILL face of the polygon in in the aforementioned scenario (verified in ironlake and gm45). In Gen4 this is, likely, a regression introduced with commit 098acf6c843. In Gen5 this has never worked properly. Gen > 5 are not affected by this. The patch fixes the problem by adding the appropriate runtime check and adjusting the framebuffer write message accordingly in the conflictive scenario (detected with fs_visitor::runtime_check_aads_emit == TRUE). Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=78679 --- src/mesa/drivers/dri/i965/brw_fs.h | 4 ++ src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 86 +++++++++++++++++----------- 2 files changed, 58 insertions(+), 32 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h index 60a4906..ab8912f 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.h +++ b/src/mesa/drivers/dri/i965/brw_fs.h @@ -452,6 +452,10 @@ public: void emit_color_write(int target, int index, int first_color_mrf); void emit_alpha_test(); + void do_emit_fb_write(int target, int base_mrf, int mlen, bool eot, + bool header_present); + void emit_fb_write(int target, int base_mrf, int mlen, bool eot, + bool header_present); void emit_fb_writes(); void emit_shader_time_begin(); diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp index 171f063..4c3897b 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp @@ -2731,6 +2731,54 @@ fs_visitor::emit_alpha_test() } void +fs_visitor::do_emit_fb_write(int target, int base_mrf, int mlen, bool eot, + bool header_present) +{ + fs_inst *inst = emit(FS_OPCODE_FB_WRITE); + inst->target = target; + inst->base_mrf = base_mrf; + inst->mlen = mlen; + inst->eot = eot; + inst->header_present = header_present; + if ((brw->gen >= 8 || brw->is_haswell) && fp->UsesKill) { + inst->predicate = BRW_PREDICATE_NORMAL; + inst->flag_subreg = 1; + } +} + +void +fs_visitor::emit_fb_write(int target, int base_mrf, int mlen, bool eot, + bool header_present) +{ + if (!runtime_check_aads_emit) { + do_emit_fb_write(target, base_mrf, mlen, eot, header_present); + } else { + /* This can only happen in Gen < 6 + */ + fs_reg reg_tmp_ud = fs_reg(this, glsl_type::uint_type); + emit(AND(reg_tmp_ud, + fs_reg(get_element_ud(brw_vec8_grf(1,0), 6)), + fs_reg(brw_imm_ud(1<<26)))); + emit(CMP(reg_null_ud, + reg_tmp_ud, + fs_reg(brw_imm_ud(0)), + BRW_CONDITIONAL_Z)); + emit(IF(BRW_PREDICATE_NORMAL)); + { + /* Shift message header one register since we are not sending + * AA data stored in base_mrf+2 + */ + do_emit_fb_write(target, base_mrf + 1, mlen - 1, eot, header_present); + } + emit(BRW_OPCODE_ELSE); + { + do_emit_fb_write(target, base_mrf, mlen, eot, header_present); + } + emit(BRW_OPCODE_ENDIF); + } +} + +void fs_visitor::emit_fb_writes() { this->current_annotation = "FB write header"; @@ -2848,16 +2896,7 @@ fs_visitor::emit_fb_writes() if (INTEL_DEBUG & DEBUG_SHADER_TIME) emit_shader_time_end(); - fs_inst *inst = emit(FS_OPCODE_FB_WRITE); - inst->target = 0; - inst->base_mrf = base_mrf; - inst->mlen = nr - base_mrf; - inst->eot = true; - inst->header_present = header_present; - if ((brw->gen >= 8 || brw->is_haswell) && fp->UsesKill) { - inst->predicate = BRW_PREDICATE_NORMAL; - inst->flag_subreg = 1; - } + emit_fb_write(0, base_mrf, nr - base_mrf, true, header_present); prog_data->dual_src_blend = true; this->current_annotation = NULL; @@ -2894,19 +2933,10 @@ fs_visitor::emit_fb_writes() emit_shader_time_end(); } - fs_inst *inst = emit(FS_OPCODE_FB_WRITE); - inst->target = target; - inst->base_mrf = base_mrf; - if (src0_alpha_to_render_target && target == 0) - inst->mlen = nr - base_mrf - reg_width; - else - inst->mlen = nr - base_mrf; - inst->eot = eot; - inst->header_present = header_present; - if ((brw->gen >= 8 || brw->is_haswell) && fp->UsesKill) { - inst->predicate = BRW_PREDICATE_NORMAL; - inst->flag_subreg = 1; - } + int mlen = (src0_alpha_to_render_target && target == 0) ? + nr - base_mrf - reg_width : nr - base_mrf; + + emit_fb_write(target, base_mrf, mlen, eot, header_present); } if (key->nr_color_regions == 0) { @@ -2919,15 +2949,7 @@ fs_visitor::emit_fb_writes() if (INTEL_DEBUG & DEBUG_SHADER_TIME) emit_shader_time_end(); - fs_inst *inst = emit(FS_OPCODE_FB_WRITE); - inst->base_mrf = base_mrf; - inst->mlen = nr - base_mrf; - inst->eot = true; - inst->header_present = header_present; - if ((brw->gen >= 8 || brw->is_haswell) && fp->UsesKill) { - inst->predicate = BRW_PREDICATE_NORMAL; - inst->flag_subreg = 1; - } + emit_fb_write(0, base_mrf, nr - base_mrf, true, header_present); } this->current_annotation = NULL; -- 1.9.2