diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h index 053046b..b7a9d14 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.h +++ b/src/mesa/drivers/dri/i965/brw_fs.h @@ -588,6 +588,10 @@ public: private: void generate_code(exec_list *instructions, FILE *dump_file); + void fire_fb_write(fs_inst *inst, + GLuint base_reg, + struct brw_reg implied_header, + GLuint nr); void generate_fb_write(fs_inst *inst); void generate_blorp_fb_write(fs_inst *inst); void generate_pixel_xy(struct brw_reg dst, bool is_x); diff --git a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp index ff85171..5dc630e 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp @@ -92,11 +92,47 @@ fs_generator::patch_discard_jumps_to_fb_writes() } void +fs_generator::fire_fb_write(fs_inst *inst, + GLuint base_reg, + struct brw_reg implied_header, + GLuint nr) +{ + uint32_t msg_control; + + if (brw->gen < 6) { + brw_MOV(p, + brw_message_reg(base_reg + 1), + brw_vec8_grf(1, 0)); + } + + if (this->dual_source_output) + msg_control = BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_DUAL_SOURCE_SUBSPAN01; + else if (dispatch_width == 16) + msg_control = BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE; + else + msg_control = BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_SINGLE_SOURCE_SUBSPAN01; + + uint32_t surf_index = + c->prog_data.binding_table.render_target_start + inst->target; + + brw_fb_WRITE(p, + dispatch_width, + base_reg, + implied_header, + msg_control, + surf_index, + nr, + 0, + inst->eot, + inst->header_present); + + brw_mark_surface_used(&c->prog_data.base, surf_index); +} + +void fs_generator::generate_fb_write(fs_inst *inst) { - bool eot = inst->eot; struct brw_reg implied_header; - uint32_t msg_control; /* Header is 2 regs, g0 and g1 are the contents. g0 will be implied * move, here's g1. @@ -149,38 +185,66 @@ fs_generator::generate_fb_write(fs_inst *inst) implied_header = brw_null_reg(); } else { implied_header = retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW); - - brw_MOV(p, - brw_message_reg(inst->base_mrf + 1), - brw_vec8_grf(1, 0)); } } else { implied_header = brw_null_reg(); } - if (this->dual_source_output) - msg_control = BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_DUAL_SOURCE_SUBSPAN01; - else if (dispatch_width == 16) - msg_control = BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE; - else - msg_control = BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_SINGLE_SOURCE_SUBSPAN01; + if (!c->runtime_check_aads_emit) { + fire_fb_write(inst, inst->base_mrf, implied_header, inst->mlen); + } else { + /* This can only happen in Gen < 6 + */ + bool tryJMPI = getenv("INTEL_AA_TRY_JMPI") != NULL; + if (tryJMPI) { + fprintf(stderr, "Using JMPI to do AA runtime checks...\n"); + struct brw_reg v1_null_ud = vec1(retype(brw_null_reg(), BRW_REGISTER_TYPE_UD)); + struct brw_reg ip = brw_ip_reg(); + int jmp; - brw_pop_insn_state(p); + brw_set_compression_control(p, BRW_COMPRESSION_NONE); + brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); + brw_AND(p, + v1_null_ud, + get_element_ud(brw_vec8_grf(1,0), 6), + brw_imm_ud(1<<26)); + jmp = brw_JMPI(p, ip, ip, brw_imm_ud(0)) - p->store; + { + fire_fb_write(inst, inst->base_mrf+1, implied_header, inst->mlen-1); + } + brw_land_fwd_jump(p, jmp); + fire_fb_write(inst, inst->base_mrf, implied_header, inst->mlen); + } else { + fprintf(stderr, "Using IF/ELSE/ENDIF to do AA runtime checks...\n"); + struct brw_reg v1_null_ud = vec1(retype(brw_null_reg(), BRW_REGISTER_TYPE_UD)); + struct brw_reg tmp_reg_ud = brw_vec1_grf(BRW_MAX_GRF-1, 0); - uint32_t surf_index = - c->prog_data.binding_table.render_target_start + inst->target; - brw_fb_WRITE(p, - dispatch_width, - inst->base_mrf, - implied_header, - msg_control, - surf_index, - inst->mlen, - 0, - eot, - inst->header_present); + brw_set_compression_control(p, BRW_COMPRESSION_NONE); + brw_AND(p, + tmp_reg_ud, + get_element_ud(brw_vec8_grf(1,0), 6), + brw_imm_ud(1<<26)); + brw_CMP(p, + v1_null_ud, + BRW_CONDITIONAL_Z, + tmp_reg_ud, + brw_imm_ud(0)); + brw_IF(p, BRW_EXECUTE_1); + { + /* Shift message header one register since we are not sending + * AA data stored in inst->base_mrf+2 + */ + fire_fb_write(inst, inst->base_mrf+1, implied_header, inst->mlen-1); + } + brw_ELSE(p); + { + fire_fb_write(inst, inst->base_mrf, implied_header, inst->mlen); + } + brw_ENDIF(p); + } + } - brw_mark_surface_used(&c->prog_data.base, surf_index); + brw_pop_insn_state(p); } void