/* Kill pixel - set execution mask to zero for those pixels which * fail. */ static void emit_kil( struct brw_wm_compile *c, struct brw_reg *arg0) { struct brw_compile *p = &c->func; struct intel_context *intel = &p->brw->intel; struct brw_reg pixelmask; GLuint i, j; if (intel->gen >= 6) pixelmask = retype(brw_vec1_grf(1, 7), BRW_REGISTER_TYPE_UW); else pixelmask = retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_UW); for (i = 0; i < 4; i++) { /* Check if we've already done the comparison for this reg * -- common when someone does KIL TEMP.wwww. */ for (j = 0; j < i; j++) { if (memcmp(&arg0[j], &arg0[i], sizeof(arg0[0])) == 0) break; } if (j != i) continue; brw_push_insn_state(p); brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_GE, arg0[i], brw_imm_f(0)); brw_set_predicate_control_flag_value(p, 0xff); brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_AND(p, pixelmask, brw_flag_reg(), pixelmask); brw_pop_insn_state(p); } }
/* How does predicate control work when execution_size != 8? Do I * need to test/set for 0xffff when execution_size is 16? */ void brw_set_predicate_control_flag_value( struct brw_compile *p, unsigned value ) { p->current->header.predicate_control = BRW_PREDICATE_NONE; if (value != 0xff) { if (value != p->flag_value) { brw_MOV(p, brw_flag_reg(), brw_imm_uw(value)); p->flag_value = value; } p->current->header.predicate_control = BRW_PREDICATE_NORMAL; } }
/* How does predicate control work when execution_size != 8? Do I * need to test/set for 0xffff when execution_size is 16? */ void brw_set_predicate_control_flag_value( struct brw_compile *p, GLuint value ) { p->current->header.predicate_control = BRW_PREDICATE_NONE; if (value != 0xff) { if (value != p->flag_value) { brw_push_insn_state(p); brw_MOV(p, brw_flag_reg(), brw_imm_uw(value)); p->flag_value = value; brw_pop_insn_state(p); } p->current->header.predicate_control = BRW_PREDICATE_NORMAL; } }
static void set_predicate_control_flag_value(struct brw_compile *p, struct brw_sf_compile *c, unsigned value) { brw_set_default_predicate_control(p, BRW_PREDICATE_NONE); if (value != 0xff) { if (value != c->flag_value) { brw_MOV(p, brw_flag_reg(0, 0), brw_imm_uw(value)); c->flag_value = value; } brw_set_default_predicate_control(p, BRW_PREDICATE_NORMAL); } }
void vec4_generator::generate_unpack_flags(vec4_instruction *inst, struct brw_reg dst) { brw_push_insn_state(p); brw_set_mask_control(p, BRW_MASK_DISABLE); brw_set_access_mode(p, BRW_ALIGN_1); struct brw_reg flags = brw_flag_reg(0, 0); struct brw_reg dst_0 = suboffset(vec1(dst), 0); struct brw_reg dst_4 = suboffset(vec1(dst), 4); brw_AND(p, dst_0, flags, brw_imm_ud(0x0f)); brw_AND(p, dst_4, flags, brw_imm_ud(0xf0)); brw_SHR(p, dst_4, dst_4, brw_imm_ud(4)); brw_pop_insn_state(p); }
/* Kill pixel - set execution mask to zero for those pixels which * fail. */ static void emit_kil( struct brw_wm_compile *c, struct brw_reg *arg0) { struct brw_compile *p = &c->func; struct brw_reg r0uw = retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_UW); GLuint i; /* XXX - usually won't need 4 compares! */ for (i = 0; i < 4; i++) { brw_push_insn_state(p); brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_GE, arg0[i], brw_imm_f(0)); brw_set_predicate_control_flag_value(p, 0xff); brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_AND(p, r0uw, brw_flag_reg(), r0uw); brw_pop_insn_state(p); } }
/** * Emit code that kills pixels whose X and Y coordinates are outside the * boundary of the rectangle defined by the push constants (dst_x0, dst_y0, * dst_x1, dst_y1). */ void brw_blorp_eu_emitter::emit_kill_if_outside_rect(const struct brw_reg &x, const struct brw_reg &y, const struct brw_reg &dst_x0, const struct brw_reg &dst_x1, const struct brw_reg &dst_y0, const struct brw_reg &dst_y1) { struct brw_reg f0 = brw_flag_reg(0, 0); struct brw_reg g1 = retype(brw_vec1_grf(1, 7), BRW_REGISTER_TYPE_UW); emit_cmp(BRW_CONDITIONAL_GE, x, dst_x0); emit_cmp(BRW_CONDITIONAL_GE, y, dst_y0)->predicate = BRW_PREDICATE_NORMAL; emit_cmp(BRW_CONDITIONAL_L, x, dst_x1)->predicate = BRW_PREDICATE_NORMAL; emit_cmp(BRW_CONDITIONAL_L, y, dst_y1)->predicate = BRW_PREDICATE_NORMAL; fs_inst *inst = new (mem_ctx) fs_inst(BRW_OPCODE_AND, 16, g1, f0, g1); inst->force_writemask_all = true; insts.push_tail(inst); }
brw_blorp_eu_emitter::brw_blorp_eu_emitter(struct brw_context *brw) : brw_ctx (brw), mem_ctx(ralloc_context(NULL)), c(rzalloc(mem_ctx, struct brw_wm_compile)), generator(brw, c, NULL, NULL, false) { } brw_blorp_eu_emitter::~brw_blorp_eu_emitter() { ralloc_free(mem_ctx); } const unsigned * brw_blorp_eu_emitter::get_program(unsigned *program_size, FILE *dump_file) { const unsigned *res; if (unlikely(INTEL_DEBUG & DEBUG_BLORP)) { fprintf(stderr, "Native code for BLORP blit:\n"); res = generator.generate_assembly(NULL, &insts, program_size, dump_file); fprintf(stderr, "\n"); } else { res = generator.generate_assembly(NULL, &insts, program_size); } return res; } /** * Emit code that kills pixels whose X and Y coordinates are outside the * boundary of the rectangle defined by the push constants (dst_x0, dst_y0, * dst_x1, dst_y1). */ void brw_blorp_eu_emitter::emit_kill_if_outside_rect(const struct brw_reg &x, const struct brw_reg &y, const struct brw_reg &dst_x0, const struct brw_reg &dst_x1, const struct brw_reg &dst_y0, const struct brw_reg &dst_y1) { struct brw_reg f0 = brw_flag_reg(0, 0); struct brw_reg g1 = retype(brw_vec1_grf(1, 7), BRW_REGISTER_TYPE_UW); emit_cmp(BRW_CONDITIONAL_GE, x, dst_x0); emit_cmp(BRW_CONDITIONAL_GE, y, dst_y0)->predicate = BRW_PREDICATE_NORMAL; emit_cmp(BRW_CONDITIONAL_L, x, dst_x1)->predicate = BRW_PREDICATE_NORMAL; emit_cmp(BRW_CONDITIONAL_L, y, dst_y1)->predicate = BRW_PREDICATE_NORMAL; fs_inst *inst = new (mem_ctx) fs_inst(BRW_OPCODE_AND, g1, f0, g1); inst->force_writemask_all = true; insts.push_tail(inst); } void brw_blorp_eu_emitter::emit_texture_lookup(const struct brw_reg &dst, enum opcode op, unsigned base_mrf, unsigned msg_length) { fs_inst *inst = new (mem_ctx) fs_inst(op, dst, brw_message_reg(base_mrf)); inst->base_mrf = base_mrf; inst->mlen = msg_length; inst->sampler = 0; inst->header_present = false; insts.push_tail(inst); }