static void emit_pixel_w( struct brw_compile *p, const struct brw_reg *dst, GLuint mask, const struct brw_reg *arg0, const struct brw_reg *deltas) { /* Don't need this if all you are doing is interpolating color, for * instance. */ if (mask & WRITEMASK_W) { struct brw_reg interp3 = brw_vec1_grf(arg0[0].nr+1, 4); /* Calc 1/w - just linterp wpos[3] optimized by putting the * result straight into a message reg. */ brw_LINE(p, brw_null_reg(), interp3, deltas[0]); brw_MAC(p, brw_message_reg(2), suboffset(interp3, 1), deltas[1]); /* Calc w */ brw_math_16( p, dst[3], BRW_MATH_FUNCTION_INV, BRW_MATH_SATURATE_NONE, 2, brw_null_reg(), BRW_MATH_PRECISION_FULL); } }
static void merge_edgeflags( struct brw_clip_compile *c ) { struct brw_compile *p = &c->func; struct brw_reg tmp0 = get_element_ud(c->reg.tmp0, 0); brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK)); brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ, tmp0, brw_imm_ud(_3DPRIM_POLYGON)); /* Get away with using reg.vertex because we know that this is not * a _3DPRIM_TRISTRIP_REVERSE: */ brw_IF(p, BRW_EXECUTE_1); { brw_set_conditionalmod(p, BRW_CONDITIONAL_EQ); brw_AND(p, vec1(brw_null_reg()), get_element_ud(c->reg.R0, 2), brw_imm_ud(1<<8)); brw_MOV(p, byte_offset(c->reg.vertex[0], brw_varying_to_offset(&c->vue_map, VARYING_SLOT_EDGE)), brw_imm_f(0)); brw_set_predicate_control(p, BRW_PREDICATE_NONE); brw_set_conditionalmod(p, BRW_CONDITIONAL_EQ); brw_AND(p, vec1(brw_null_reg()), get_element_ud(c->reg.R0, 2), brw_imm_ud(1<<9)); brw_MOV(p, byte_offset(c->reg.vertex[2], brw_varying_to_offset(&c->vue_map, VARYING_SLOT_EDGE)), brw_imm_f(0)); brw_set_predicate_control(p, BRW_PREDICATE_NONE); } brw_ENDIF(p); }
static void emit_pixel_w( struct brw_wm_compile *c, struct prog_instruction *inst) { struct brw_compile *p = &c->func; GLuint mask = inst->DstReg.WriteMask; if (mask & WRITEMASK_W) { struct brw_reg dst, src0, delta0, delta1; struct brw_reg interp3; dst = get_dst_reg(c, inst, 3, 1); src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1); delta0 = get_src_reg(c, &inst->SrcReg[1], 0, 1); delta1 = get_src_reg(c, &inst->SrcReg[1], 1, 1); interp3 = brw_vec1_grf(src0.nr+1, 4); /* Calc 1/w - just linterp wpos[3] optimized by putting the * result straight into a message reg. */ brw_LINE(p, brw_null_reg(), interp3, delta0); brw_MAC(p, brw_message_reg(2), suboffset(interp3, 1), delta1); /* Calc w */ brw_math_16( p, dst, BRW_MATH_FUNCTION_INV, BRW_MATH_SATURATE_NONE, 2, brw_null_reg(), BRW_MATH_PRECISION_FULL); } }
void emit_pixel_w(struct brw_wm_compile *c, const struct brw_reg *dst, GLuint mask, const struct brw_reg *arg0, const struct brw_reg *deltas) { struct brw_compile *p = &c->func; struct intel_context *intel = &p->brw->intel; struct brw_reg src; struct brw_reg temp_dst; if (intel->gen >= 6) temp_dst = dst[3]; else temp_dst = brw_message_reg(2); assert(intel->gen < 6); /* Don't need this if all you are doing is interpolating color, for * instance. */ if (mask & WRITEMASK_W) { struct brw_reg interp3 = brw_vec1_grf(arg0[0].nr+1, 4); /* Calc 1/w - just linterp wpos[3] optimized by putting the * result straight into a message reg. */ if (can_do_pln(intel, deltas)) { brw_PLN(p, temp_dst, interp3, deltas[0]); } else { brw_LINE(p, brw_null_reg(), interp3, deltas[0]); brw_MAC(p, temp_dst, suboffset(interp3, 1), deltas[1]); } /* Calc w */ if (intel->gen >= 6) src = temp_dst; else src = brw_null_reg(); if (c->dispatch_width == 16) { brw_math_16(p, dst[3], BRW_MATH_FUNCTION_INV, BRW_MATH_SATURATE_NONE, 2, src, BRW_MATH_PRECISION_FULL); } else { brw_math(p, dst[3], BRW_MATH_FUNCTION_INV, BRW_MATH_SATURATE_NONE, 2, src, BRW_MATH_DATA_VECTOR, BRW_MATH_PRECISION_FULL); } } }
static void emit_math2( struct brw_compile *p, GLuint function, const struct brw_reg *dst, GLuint mask, const struct brw_reg *arg0, const struct brw_reg *arg1) { if (!(mask & WRITEMASK_XYZW)) return; /* Do not emit dead code*/ assert((mask & WRITEMASK_XYZW) == WRITEMASK_X); brw_push_insn_state(p); brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_MOV(p, brw_message_reg(2), arg0[0]); brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF); brw_MOV(p, brw_message_reg(4), sechalf(arg0[0])); brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_MOV(p, brw_message_reg(3), arg1[0]); brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF); brw_MOV(p, brw_message_reg(5), sechalf(arg1[0])); /* Send two messages to perform all 16 operations: */ brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_math(p, dst[0], function, (mask & SATURATE) ? BRW_MATH_SATURATE_SATURATE : BRW_MATH_SATURATE_NONE, 2, brw_null_reg(), BRW_MATH_DATA_VECTOR, BRW_MATH_PRECISION_FULL); brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF); brw_math(p, offset(dst[0],1), function, (mask & SATURATE) ? BRW_MATH_SATURATE_SATURATE : BRW_MATH_SATURATE_NONE, 4, brw_null_reg(), BRW_MATH_DATA_VECTOR, BRW_MATH_PRECISION_FULL); brw_pop_insn_state(p); }
static void emit_lit( struct brw_compile *p, const struct brw_reg *dst, GLuint mask, const struct brw_reg *arg0 ) { assert((mask & WRITEMASK_XW) == 0); if (mask & WRITEMASK_Y) { brw_set_saturate(p, (mask & SATURATE) ? 1 : 0); brw_MOV(p, dst[1], arg0[0]); brw_set_saturate(p, 0); } if (mask & WRITEMASK_Z) { emit_math2(p, BRW_MATH_FUNCTION_POW, &dst[2], WRITEMASK_X | (mask & SATURATE), &arg0[1], &arg0[3]); } /* Ordinarily you'd use an iff statement to skip or shortcircuit * some of the POW calculations above, but 16-wide iff statements * seem to lock c1 hardware, so this is a nasty workaround: */ brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_LE, arg0[0], brw_imm_f(0)); { if (mask & WRITEMASK_Y) brw_MOV(p, dst[1], brw_imm_f(0)); if (mask & WRITEMASK_Z) brw_MOV(p, dst[2], brw_imm_f(0)); } brw_set_predicate_control(p, BRW_PREDICATE_NONE); }
/* 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); } }
static void emit_pinterp(struct brw_wm_compile *c, struct prog_instruction *inst) { struct brw_compile *p = &c->func; GLuint mask = inst->DstReg.WriteMask; struct brw_reg interp[4]; struct brw_reg dst, delta0, delta1; struct brw_reg src0, w; src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1); delta0 = get_src_reg(c, &inst->SrcReg[1], 0, 1); delta1 = get_src_reg(c, &inst->SrcReg[1], 1, 1); w = get_src_reg(c, &inst->SrcReg[2], 3, 1); GLuint nr = src0.nr; int i; interp[0] = brw_vec1_grf(nr, 0); interp[1] = brw_vec1_grf(nr, 4); interp[2] = brw_vec1_grf(nr+1, 0); interp[3] = brw_vec1_grf(nr+1, 4); for(i = 0; i < 4; i++ ) { if (mask & (1<<i)) { dst = get_dst_reg(c, inst, i, 1); brw_LINE(p, brw_null_reg(), interp[i], delta0); brw_MAC(p, dst, suboffset(interp[i],1), delta1); brw_MUL(p, dst, dst, w); } } }
static void do_twoside_color( struct brw_sf_compile *c ) { struct brw_compile *p = &c->func; GLuint backface_conditional = c->key.frontface_ccw ? BRW_CONDITIONAL_G : BRW_CONDITIONAL_L; /* Already done in clip program: */ if (c->key.primitive == SF_UNFILLED_TRIS) return; /* If the vertex shader provides backface color, do the selection. The VS * promises to set up the front color if the backface color is provided, but * it may contain junk if never written to. */ if (!(have_attr(c, VARYING_SLOT_COL0) && have_attr(c, VARYING_SLOT_BFC0)) && !(have_attr(c, VARYING_SLOT_COL1) && have_attr(c, VARYING_SLOT_BFC1))) return; /* Need to use BRW_EXECUTE_4 and also do an 4-wide compare in order * to get all channels active inside the IF. In the clipping code * we run with NoMask, so it's not an option and we can use * BRW_EXECUTE_1 for all comparisions. */ brw_CMP(p, vec4(brw_null_reg()), backface_conditional, c->det, brw_imm_f(0)); brw_IF(p, BRW_EXECUTE_4); { switch (c->nr_verts) { case 3: copy_bfc(c, c->vert[2]); case 2: copy_bfc(c, c->vert[1]); case 1: copy_bfc(c, c->vert[0]); } } brw_ENDIF(p); }
static void cull_direction( struct brw_clip_compile *c ) { struct brw_compile *p = &c->func; GLuint conditional; assert (!(c->key.fill_ccw == CLIP_CULL && c->key.fill_cw == CLIP_CULL)); if (c->key.fill_ccw == CLIP_CULL) conditional = BRW_CONDITIONAL_GE; else conditional = BRW_CONDITIONAL_L; brw_CMP(p, vec1(brw_null_reg()), conditional, get_element(c->reg.dir, 2), brw_imm_f(0)); brw_IF(p, BRW_EXECUTE_1); { brw_clip_kill_thread(c); } brw_ENDIF(p); }
void gen8_vec4_generator::generate_urb_write(vec4_instruction *ir, bool vs) { struct brw_reg header = brw_vec8_grf(GEN7_MRF_HACK_START + ir->base_mrf, 0); /* Copy g0. */ if (vs) MOV_RAW(header, brw_vec8_grf(0, 0)); gen8_instruction *inst; if (!(ir->urb_write_flags & BRW_URB_WRITE_USE_CHANNEL_MASKS)) { /* Enable Channel Masks in the URB_WRITE_OWORD message header */ default_state.access_mode = BRW_ALIGN_1; inst = OR(retype(brw_vec1_grf(GEN7_MRF_HACK_START + ir->base_mrf, 5), BRW_REGISTER_TYPE_UD), retype(brw_vec1_grf(0, 5), BRW_REGISTER_TYPE_UD), brw_imm_ud(0xff00)); gen8_set_mask_control(inst, BRW_MASK_DISABLE); default_state.access_mode = BRW_ALIGN_16; } inst = next_inst(BRW_OPCODE_SEND); gen8_set_urb_message(brw, inst, ir->urb_write_flags, ir->mlen, 0, ir->offset, true); gen8_set_dst(brw, inst, brw_null_reg()); gen8_set_src0(brw, inst, header); }
static void emit_unfilled_primitives( struct brw_clip_compile *c ) { struct brw_compile *p = &c->func; /* Direction culling has already been done. */ if (c->key.fill_ccw != c->key.fill_cw && c->key.fill_ccw != CLIP_CULL && c->key.fill_cw != CLIP_CULL) { brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_GE, get_element(c->reg.dir, 2), brw_imm_f(0)); brw_IF(p, BRW_EXECUTE_1); { emit_primitives(c, c->key.fill_ccw, c->key.offset_ccw); } brw_ELSE(p); { emit_primitives(c, c->key.fill_cw, c->key.offset_cw); } brw_ENDIF(p); } else if (c->key.fill_cw != CLIP_CULL) { emit_primitives(c, c->key.fill_cw, c->key.offset_cw); } else if (c->key.fill_ccw != CLIP_CULL) { emit_primitives(c, c->key.fill_ccw, c->key.offset_ccw); } }
void brw_emit_unfilled_clip( struct brw_clip_compile *c ) { struct brw_compile *p = &c->func; c->need_direction = ((c->key.offset_ccw || c->key.offset_cw) || (c->key.fill_ccw != c->key.fill_cw) || c->key.fill_ccw == CLIP_CULL || c->key.fill_cw == CLIP_CULL || c->key.copy_bfc_cw || c->key.copy_bfc_ccw); brw_clip_tri_alloc_regs(c, 3 + c->key.nr_userclip + 6); brw_clip_tri_init_vertices(c); brw_clip_init_ff_sync(c); assert(brw_clip_have_varying(c, VARYING_SLOT_EDGE)); if (c->key.fill_ccw == CLIP_CULL && c->key.fill_cw == CLIP_CULL) { brw_clip_kill_thread(c); return; } merge_edgeflags(c); /* Need to use the inlist indirection here: */ if (c->need_direction) compute_tri_direction(c); if (c->key.fill_ccw == CLIP_CULL || c->key.fill_cw == CLIP_CULL) cull_direction(c); if (c->key.offset_ccw || c->key.offset_cw) compute_offset(c); if (c->key.copy_bfc_ccw || c->key.copy_bfc_cw) copy_bfc(c); /* Need to do this whether we clip or not: */ if (c->has_flat_shading) brw_clip_tri_flat_shade(c); brw_clip_init_clipmask(c); brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_NZ, c->reg.planemask, brw_imm_ud(0)); brw_IF(p, BRW_EXECUTE_1); { brw_clip_init_planes(c); brw_clip_tri(c); check_nr_verts(c); } brw_ENDIF(p); emit_unfilled_primitives(c); brw_clip_kill_thread(c); }
void emit_linterp(struct brw_compile *p, const struct brw_reg *dst, GLuint mask, const struct brw_reg *arg0, const struct brw_reg *deltas) { struct intel_context *intel = &p->brw->intel; struct brw_reg interp[4]; GLuint nr = arg0[0].nr; GLuint i; interp[0] = brw_vec1_grf(nr, 0); interp[1] = brw_vec1_grf(nr, 4); interp[2] = brw_vec1_grf(nr+1, 0); interp[3] = brw_vec1_grf(nr+1, 4); for (i = 0; i < 4; i++) { if (mask & (1<<i)) { 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]); brw_MAC(p, dst[i], suboffset(interp[i],1), deltas[1]); } } } }
void brw_clip_tri_flat_shade( struct brw_clip_compile *c ) { struct brw_compile *p = &c->func; struct brw_instruction *is_poly; struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */ brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK)); brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ, tmp0, brw_imm_ud(_3DPRIM_POLYGON)); is_poly = brw_IF(p, BRW_EXECUTE_1); { brw_clip_copy_colors(c, 1, 0); brw_clip_copy_colors(c, 2, 0); } is_poly = brw_ELSE(p, is_poly); { brw_clip_copy_colors(c, 0, 2); brw_clip_copy_colors(c, 1, 2); } brw_ENDIF(p, is_poly); }
static void emit_pinterp( struct brw_compile *p, const struct brw_reg *dst, GLuint mask, const struct brw_reg *arg0, const struct brw_reg *deltas, const struct brw_reg *w) { struct brw_reg interp[4]; GLuint nr = arg0[0].nr; GLuint i; interp[0] = brw_vec1_grf(nr, 0); interp[1] = brw_vec1_grf(nr, 4); interp[2] = brw_vec1_grf(nr+1, 0); interp[3] = brw_vec1_grf(nr+1, 4); for(i = 0; i < 4; i++ ) { if (mask & (1<<i)) { brw_LINE(p, brw_null_reg(), interp[i], deltas[0]); brw_MAC(p, dst[i], suboffset(interp[i],1), deltas[1]); } } for(i = 0; i < 4; i++ ) { if (mask & (1<<i)) { brw_MUL(p, dst[i], dst[i], w[3]); } } }
static struct brw_reg get_reg(struct brw_wm_compile *c, int file, int index, int component, int nr, GLuint neg, GLuint abs) { struct brw_reg reg; switch (file) { case PROGRAM_STATE_VAR: case PROGRAM_CONSTANT: case PROGRAM_UNIFORM: file = PROGRAM_STATE_VAR; break; case PROGRAM_UNDEFINED: return brw_null_reg(); default: break; } if(c->wm_regs[file][index][component].inited) reg = c->wm_regs[file][index][component].reg; else reg = brw_vec8_grf(c->reg_index, 0); if(!c->wm_regs[file][index][component].inited) { set_reg(c, file, index, component, reg); c->reg_index++; } if (neg & (1<< component)) { reg = negate(reg); } if (abs) reg = brw_abs(reg); return reg; }
static void emit_min(struct brw_wm_compile *c, struct prog_instruction *inst) { struct brw_compile *p = &c->func; GLuint mask = inst->DstReg.WriteMask; struct brw_reg src0, src1, dst; int i; brw_push_insn_state(p); for (i = 0; i < 4; i++) { if (mask & (1<<i)) { dst = get_dst_reg(c, inst, i, 1); src0 = get_src_reg(c, &inst->SrcReg[0], i, 1); src1 = get_src_reg(c, &inst->SrcReg[1], i, 1); brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0); brw_MOV(p, dst, src0); brw_set_saturate(p, 0); brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, src1, src0); brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0); brw_set_predicate_control(p, BRW_PREDICATE_NORMAL); brw_MOV(p, dst, src1); brw_set_saturate(p, 0); brw_set_predicate_control_flag_value(p, 0xff); } } brw_pop_insn_state(p); }
/* Sets the destination channels to 1.0 or 0.0 according to glFrontFacing. */ void emit_frontfacing(struct brw_compile *p, const struct brw_reg *dst, GLuint mask) { struct brw_reg r1_6ud = retype(brw_vec1_grf(1, 6), BRW_REGISTER_TYPE_UD); GLuint i; if (!(mask & WRITEMASK_XYZW)) return; for (i = 0; i < 4; i++) { if (mask & (1<<i)) { brw_MOV(p, dst[i], brw_imm_f(0.0)); } } /* bit 31 is "primitive is back face", so checking < (1 << 31) gives * us front face */ brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, r1_6ud, brw_imm_ud(1 << 31)); for (i = 0; i < 4; i++) { if (mask & (1<<i)) { brw_MOV(p, dst[i], brw_imm_f(1.0)); } } brw_set_predicate_control_flag_value(p, 0xff); }
static void fire_fb_write( struct brw_wm_compile *c, GLuint base_reg, GLuint nr, GLuint target, GLuint eot ) { struct brw_compile *p = &c->func; /* Pass through control information: */ /* mov (8) m1.0<1>:ud r1.0<8;8,1>:ud { Align1 NoMask } */ { brw_push_insn_state(p); brw_set_mask_control(p, BRW_MASK_DISABLE); /* ? */ brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_MOV(p, brw_message_reg(base_reg + 1), brw_vec8_grf(1, 0)); brw_pop_insn_state(p); } /* Send framebuffer write message: */ /* send (16) null.0<1>:uw m0 r0.0<8;8,1>:uw 0x85a04000:ud { Align1 EOT } */ brw_fb_WRITE(p, retype(vec16(brw_null_reg()), BRW_REGISTER_TYPE_UW), base_reg, retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW), target, nr, 0, eot); }
/* Interpolate between two vertices and put the result into a0.0. * Increment a0.0 accordingly. */ void brw_clip_interp_vertex( struct brw_clip_compile *c, struct brw_indirect dest_ptr, struct brw_indirect v0_ptr, /* from */ struct brw_indirect v1_ptr, /* to */ struct brw_reg t0, GLboolean force_edgeflag) { struct brw_compile *p = &c->func; struct brw_reg tmp = get_tmp(c); GLuint i; /* Just copy the vertex header: */ brw_copy_indirect_to_indirect(p, dest_ptr, v0_ptr, 1); /* Iterate over each attribute (could be done in pairs?) */ for (i = 0; i < c->nr_attrs; i++) { GLuint delta = i*16 + 32; if (delta == c->offset[VERT_RESULT_EDGE]) { if (force_edgeflag) brw_MOV(p, deref_4f(dest_ptr, delta), brw_imm_f(1)); else brw_MOV(p, deref_4f(dest_ptr, delta), deref_4f(v0_ptr, delta)); } else { /* Interpolate: * * New = attr0 + t*attr1 - t*attr0 */ brw_MUL(p, vec4(brw_null_reg()), deref_4f(v1_ptr, delta), t0); brw_MAC(p, tmp, negate(deref_4f(v0_ptr, delta)), t0); brw_ADD(p, deref_4f(dest_ptr, delta), deref_4f(v0_ptr, delta), tmp); } } if (i & 1) { GLuint delta = i*16 + 32; brw_MOV(p, deref_4f(dest_ptr, delta), brw_imm_f(0)); } release_tmp(c, tmp); /* Recreate the projected (NDC) coordinate in the new vertex * header: */ brw_clip_project_vertex(c, dest_ptr ); }
void brw_clip_ff_sync(struct brw_clip_compile *c) { if (c->need_ff_sync) { struct brw_compile *p = &c->func; struct brw_instruction *need_ff_sync; brw_set_conditionalmod(p, BRW_CONDITIONAL_Z); brw_AND(p, brw_null_reg(), c->reg.ff_sync, brw_imm_ud(0x1)); need_ff_sync = brw_IF(p, BRW_EXECUTE_1); { brw_OR(p, c->reg.ff_sync, c->reg.ff_sync, brw_imm_ud(0x1)); brw_ff_sync(p, c->reg.R0, 0, c->reg.R0, 1, 1, /* used */ 1, /* msg length */ 1, /* response length */ 0, /* eot */ 1, /* write compelete */ 0, /* urb offset */ BRW_URB_SWIZZLE_NONE); } brw_ENDIF(p, need_ff_sync); brw_set_predicate_control(p, BRW_PREDICATE_NONE); } }
/* Points setup - several simplifications as all attributes are * constant across the face of the point (point sprites excluded!) */ void brw_emit_point_setup(struct brw_sf_compile *c, bool allocate) { struct brw_compile *p = &c->func; GLuint i; c->flag_value = 0xff; c->nr_verts = 1; if (allocate) alloc_regs(c); copy_z_inv_w(c); brw_MOV(p, c->m1Cx, brw_imm_ud(0)); /* zero - move out of loop */ brw_MOV(p, c->m2Cy, brw_imm_ud(0)); /* zero - move out of loop */ for (i = 0; i < c->nr_setup_regs; i++) { struct brw_reg a0 = offset(c->vert[0], i); GLushort pc, pc_persp, pc_linear; bool last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear); if (pc_persp) { /* This seems odd as the values are all constant, but the * fragment shader will be expecting it: */ set_predicate_control_flag_value(p, c, pc_persp); brw_MUL(p, a0, a0, c->inv_w[0]); } /* The delta values are always zero, just send the starting * coordinate. Again, this is to fit in with the interpolation * code in the fragment shader. */ { set_predicate_control_flag_value(p, c, pc); brw_MOV(p, c->m3C0, a0); /* constant value */ /* Copy m0..m3 to URB. */ brw_urb_WRITE(p, brw_null_reg(), 0, brw_vec8_grf(0, 0), last ? BRW_URB_WRITE_EOT_COMPLETE : BRW_URB_WRITE_NO_FLAGS, 4, /* msg len */ 0, /* response len */ i*4, /* urb destination offset */ BRW_URB_SWIZZLE_TRANSPOSE); } } brw_set_default_predicate_control(p, BRW_PREDICATE_NONE); }
static void emit_dph(struct brw_wm_compile *c, struct prog_instruction *inst) { struct brw_reg src0[4], src1[4], dst; int i; struct brw_compile *p = &c->func; for (i = 0; i < 4; i++) { src0[i] = get_src_reg(c, &inst->SrcReg[0], i, 1); src1[i] = get_src_reg(c, &inst->SrcReg[1], i, 1); } dst = get_dst_reg(c, inst, get_scalar_dst_index(inst), 1); brw_MUL(p, brw_null_reg(), src0[0], src1[0]); brw_MAC(p, brw_null_reg(), src0[1], src1[1]); brw_MAC(p, dst, src0[2], src1[2]); brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0); brw_ADD(p, dst, src0[3], src1[3]); brw_set_saturate(p, 0); }
static void emit_dp3( struct brw_compile *p, const struct brw_reg *dst, GLuint mask, const struct brw_reg *arg0, const struct brw_reg *arg1 ) { if (!(mask & WRITEMASK_XYZW)) return; /* Do not emit dead code*/ assert((mask & WRITEMASK_XYZW) == WRITEMASK_X); brw_MUL(p, brw_null_reg(), arg0[0], arg1[0]); brw_MAC(p, brw_null_reg(), arg0[1], arg1[1]); brw_set_saturate(p, (mask & SATURATE) ? 1 : 0); brw_MAC(p, dst[0], arg0[2], arg1[2]); brw_set_saturate(p, 0); }
void brw_clip_tri_flat_shade( struct brw_clip_compile *c ) { struct brw_codegen *p = &c->func; struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */ brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK)); brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ, tmp0, brw_imm_ud(_3DPRIM_POLYGON)); brw_IF(p, BRW_EXECUTE_1); { brw_clip_copy_flatshaded_attributes(c, 1, 0); brw_clip_copy_flatshaded_attributes(c, 2, 0); } brw_ELSE(p); { if (c->key.pv_first) { brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ, tmp0, brw_imm_ud(_3DPRIM_TRIFAN)); brw_IF(p, BRW_EXECUTE_1); { brw_clip_copy_flatshaded_attributes(c, 0, 1); brw_clip_copy_flatshaded_attributes(c, 2, 1); } brw_ELSE(p); { brw_clip_copy_flatshaded_attributes(c, 1, 0); brw_clip_copy_flatshaded_attributes(c, 2, 0); } brw_ENDIF(p); } else { brw_clip_copy_flatshaded_attributes(c, 0, 2); brw_clip_copy_flatshaded_attributes(c, 1, 2); } } brw_ENDIF(p); }
static void copy_bfc( struct brw_clip_compile *c ) { struct brw_compile *p = &c->func; GLuint conditional; /* Do we have any colors to copy? */ if (!(brw_clip_have_varying(c, VARYING_SLOT_COL0) && brw_clip_have_varying(c, VARYING_SLOT_BFC0)) && !(brw_clip_have_varying(c, VARYING_SLOT_COL1) && brw_clip_have_varying(c, VARYING_SLOT_BFC1))) return; /* In some wierd degnerate cases we can end up testing the * direction twice, once for culling and once for bfc copying. Oh * well, that's what you get for setting wierd GL state. */ if (c->key.copy_bfc_ccw) conditional = BRW_CONDITIONAL_GE; else conditional = BRW_CONDITIONAL_L; brw_CMP(p, vec1(brw_null_reg()), conditional, get_element(c->reg.dir, 2), brw_imm_f(0)); brw_IF(p, BRW_EXECUTE_1); { GLuint i; for (i = 0; i < 3; i++) { if (brw_clip_have_varying(c, VARYING_SLOT_COL0) && brw_clip_have_varying(c, VARYING_SLOT_BFC0)) brw_MOV(p, byte_offset(c->reg.vertex[i], brw_varying_to_offset(&c->vue_map, VARYING_SLOT_COL0)), byte_offset(c->reg.vertex[i], brw_varying_to_offset(&c->vue_map, VARYING_SLOT_BFC0))); if (brw_clip_have_varying(c, VARYING_SLOT_COL1) && brw_clip_have_varying(c, VARYING_SLOT_BFC1)) brw_MOV(p, byte_offset(c->reg.vertex[i], brw_varying_to_offset(&c->vue_map, VARYING_SLOT_COL1)), byte_offset(c->reg.vertex[i], brw_varying_to_offset(&c->vue_map, VARYING_SLOT_BFC1))); } } brw_ENDIF(p); }
static void maybe_do_clip_tri( struct brw_clip_compile *c ) { struct brw_compile *p = &c->func; brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_NZ, c->reg.planemask, brw_imm_ud(0)); brw_IF(p, BRW_EXECUTE_1); { do_clip_tri(c); } brw_ENDIF(p); }
void emit_dp3(struct brw_compile *p, const struct brw_reg *dst, GLuint mask, const struct brw_reg *arg0, const struct brw_reg *arg1) { int dst_chan = _mesa_ffs(mask & WRITEMASK_XYZW) - 1; if (!(mask & WRITEMASK_XYZW)) return; /* Do not emit dead code */ assert(is_power_of_two(mask & WRITEMASK_XYZW)); brw_MUL(p, brw_null_reg(), arg0[0], arg1[0]); brw_MAC(p, brw_null_reg(), arg0[1], arg1[1]); brw_set_saturate(p, (mask & SATURATE) ? 1 : 0); brw_MAC(p, dst[dst_chan], arg0[2], arg1[2]); brw_set_saturate(p, 0); }
static void check_nr_verts( struct brw_clip_compile *c ) { struct brw_compile *p = &c->func; brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.nr_verts, brw_imm_d(3)); brw_IF(p, BRW_EXECUTE_1); { brw_clip_kill_thread(c); } brw_ENDIF(p); }