/* 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, GLboolean allocate) { struct brw_compile *p = &c->func; GLuint i; 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; GLboolean 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: */ brw_set_predicate_control_flag_value(p, 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. */ { brw_set_predicate_control_flag_value(p, 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), 0, /* allocate */ 1, /* used */ 4, /* msg len */ 0, /* response len */ last, /* eot */ last, /* writes complete */ i*4, /* urb destination offset */ BRW_URB_SWIZZLE_TRANSPOSE); } } }
/* 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); }
/* 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); } }
void brw_init_compile(struct brw_context *brw, struct brw_compile *p, void *mem_ctx) { p->brw = brw; /* * Set the initial instruction store array size to 1024, if found that * isn't enough, then it will double the store size at brw_next_insn() * until out of memory. */ p->store_size = 1024; p->store = rzalloc_array(mem_ctx, struct brw_instruction, p->store_size); p->nr_insn = 0; p->current = p->stack; p->compressed = false; memset(p->current, 0, sizeof(p->current[0])); p->mem_ctx = mem_ctx; /* Some defaults? */ brw_set_mask_control(p, BRW_MASK_ENABLE); /* what does this do? */ brw_set_saturate(p, 0); brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_set_predicate_control_flag_value(p, 0xff); /* Set up control flow stack */ p->if_stack_depth = 0; p->if_stack_array_size = 16; p->if_stack = rzalloc_array(mem_ctx, int, p->if_stack_array_size); p->loop_stack_depth = 0; p->loop_stack_array_size = 16; p->loop_stack = rzalloc_array(mem_ctx, int, p->loop_stack_array_size); p->if_depth_in_loop = rzalloc_array(mem_ctx, int, p->loop_stack_array_size); }
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); }
void brw_init_compile( struct brw_compile *p ) { p->nr_insn = 0; p->current = p->stack; memset(p->current, 0, sizeof(p->current[0])); /* Some defaults? */ brw_set_mask_control(p, BRW_MASK_ENABLE); /* what does this do? */ brw_set_saturate(p, 0); brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_set_predicate_control_flag_value(p, 0xff); }
/** * Extended math function, float[16]. * Use 2 send instructions. */ void brw_math_16( struct brw_compile *p, struct brw_reg dest, GLuint function, GLuint saturate, GLuint msg_reg_nr, struct brw_reg src, GLuint precision ) { struct brw_instruction *insn; GLuint msg_length = (function == BRW_MATH_FUNCTION_POW) ? 2 : 1; GLuint response_length = (function == BRW_MATH_FUNCTION_SINCOS) ? 2 : 1; /* First instruction: */ brw_push_insn_state(p); brw_set_predicate_control_flag_value(p, 0xff); brw_set_compression_control(p, BRW_COMPRESSION_NONE); insn = next_insn(p, BRW_OPCODE_SEND); insn->header.destreg__conditionalmod = msg_reg_nr; brw_set_dest(insn, dest); brw_set_src0(insn, src); brw_set_math_message(p->brw, insn, msg_length, response_length, function, BRW_MATH_INTEGER_UNSIGNED, precision, saturate, BRW_MATH_DATA_VECTOR); /* Second instruction: */ insn = next_insn(p, BRW_OPCODE_SEND); insn->header.compression_control = BRW_COMPRESSION_2NDHALF; insn->header.destreg__conditionalmod = msg_reg_nr+1; brw_set_dest(insn, offset(dest,1)); brw_set_src0(insn, src); brw_set_math_message(p->brw, insn, msg_length, response_length, function, BRW_MATH_INTEGER_UNSIGNED, precision, saturate, BRW_MATH_DATA_VECTOR); brw_pop_insn_state(p); }
static void emit_sop( struct brw_compile *p, const struct brw_reg *dst, GLuint mask, GLuint cond, const struct brw_reg *arg0, const struct brw_reg *arg1 ) { GLuint i; for (i = 0; i < 4; i++) { if (mask & (1<<i)) { brw_MOV(p, dst[i], brw_imm_f(0)); brw_CMP(p, brw_null_reg(), cond, arg0[i], arg1[i]); brw_MOV(p, dst[i], brw_imm_f(1.0)); brw_set_predicate_control_flag_value(p, 0xff); } } }
void emit_min(struct brw_compile *p, const struct brw_reg *dst, GLuint mask, const struct brw_reg *arg0, const struct brw_reg *arg1) { GLuint i; for (i = 0; i < 4; i++) { if (mask & (1<<i)) { brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, arg0[i], arg1[i]); brw_set_saturate(p, (mask & SATURATE) ? 1 : 0); brw_SEL(p, dst[i], arg0[i], arg1[i]); brw_set_saturate(p, 0); brw_set_predicate_control_flag_value(p, 0xff); } } }
/* 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); } }
void brw_compile_init(struct brw_compile *p, int gen, void *store) { assert(gen); p->gen = gen; p->store = store; p->nr_insn = 0; p->current = p->stack; p->compressed = false; memset(p->current, 0, sizeof(p->current[0])); /* Some defaults? */ brw_set_mask_control(p, BRW_MASK_ENABLE); /* what does this do? */ brw_set_saturate(p, 0); brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_set_predicate_control_flag_value(p, 0xff); p->if_stack_depth = 0; p->if_stack_array_size = 0; p->if_stack = NULL; }
void brw_emit_point_sprite_setup( struct brw_sf_compile *c, GLboolean allocate) { struct brw_compile *p = &c->func; GLuint i; c->nr_verts = 1; if (allocate) alloc_regs(c); copy_z_inv_w(c); for (i = 0; i < c->nr_setup_regs; i++) { struct brw_reg a0 = offset(c->vert[0], i); GLushort pc, pc_persp, pc_linear, pc_coord_replace; GLboolean last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear); pc_coord_replace = calculate_point_sprite_mask(c, i); pc_persp &= ~pc_coord_replace; if (pc_persp) { brw_set_predicate_control_flag_value(p, pc_persp); brw_MUL(p, a0, a0, c->inv_w[0]); } /* Point sprite coordinate replacement: A texcoord with this * enabled gets replaced with the value (x, y, 0, 1) where x and * y vary from 0 to 1 across the horizontal and vertical of the * point. */ if (pc_coord_replace) { brw_set_predicate_control_flag_value(p, pc_coord_replace); /* Caculate 1.0/PointWidth */ brw_math(&c->func, c->tmp, BRW_MATH_FUNCTION_INV, BRW_MATH_SATURATE_NONE, 0, c->dx0, BRW_MATH_DATA_SCALAR, BRW_MATH_PRECISION_FULL); brw_set_access_mode(p, BRW_ALIGN_16); /* dA/dx, dA/dy */ brw_MOV(p, c->m1Cx, brw_imm_f(0.0)); brw_MOV(p, c->m2Cy, brw_imm_f(0.0)); brw_MOV(p, brw_writemask(c->m1Cx, WRITEMASK_X), c->tmp); if (c->key.sprite_origin_lower_left) { brw_MOV(p, brw_writemask(c->m2Cy, WRITEMASK_Y), negate(c->tmp)); } else { brw_MOV(p, brw_writemask(c->m2Cy, WRITEMASK_Y), c->tmp); } /* attribute constant offset */ brw_MOV(p, c->m3C0, brw_imm_f(0.0)); if (c->key.sprite_origin_lower_left) { brw_MOV(p, brw_writemask(c->m3C0, WRITEMASK_YW), brw_imm_f(1.0)); } else { brw_MOV(p, brw_writemask(c->m3C0, WRITEMASK_W), brw_imm_f(1.0)); } brw_set_access_mode(p, BRW_ALIGN_1); } if (pc & ~pc_coord_replace) { brw_set_predicate_control_flag_value(p, pc & ~pc_coord_replace); brw_MOV(p, c->m1Cx, brw_imm_ud(0)); brw_MOV(p, c->m2Cy, brw_imm_ud(0)); brw_MOV(p, c->m3C0, a0); /* constant value */ } brw_set_predicate_control_flag_value(p, pc); /* Copy m0..m3 to URB. */ brw_urb_WRITE(p, brw_null_reg(), 0, brw_vec8_grf(0, 0), 0, /* allocate */ 1, /* used */ 4, /* msg len */ 0, /* response len */ last, /* eot */ last, /* writes complete */ i*4, /* urb destination offset */ BRW_URB_SWIZZLE_TRANSPOSE); } }
void brw_emit_line_setup( struct brw_sf_compile *c, GLboolean allocate) { struct brw_compile *p = &c->func; GLuint i; c->nr_verts = 2; if (allocate) alloc_regs(c); invert_det(c); copy_z_inv_w(c); if (c->key.do_flat_shading) do_flatshade_line(c); for (i = 0; i < c->nr_setup_regs; i++) { /* Pair of incoming attributes: */ struct brw_reg a0 = offset(c->vert[0], i); struct brw_reg a1 = offset(c->vert[1], i); GLushort pc, pc_persp, pc_linear; GLboolean last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear); if (pc_persp) { brw_set_predicate_control_flag_value(p, pc_persp); brw_MUL(p, a0, a0, c->inv_w[0]); brw_MUL(p, a1, a1, c->inv_w[1]); } /* Calculate coefficients for position, color: */ if (pc_linear) { brw_set_predicate_control_flag_value(p, pc_linear); brw_ADD(p, c->a1_sub_a0, a1, negate(a0)); brw_MUL(p, c->tmp, c->a1_sub_a0, c->dx0); brw_MUL(p, c->m1Cx, c->tmp, c->inv_det); brw_MUL(p, c->tmp, c->a1_sub_a0, c->dy0); brw_MUL(p, c->m2Cy, c->tmp, c->inv_det); } { brw_set_predicate_control_flag_value(p, pc); /* start point for interpolation */ brw_MOV(p, c->m3C0, a0); /* Copy m0..m3 to URB. */ brw_urb_WRITE(p, brw_null_reg(), 0, brw_vec8_grf(0, 0), 0, /* allocate */ 1, /* used */ 4, /* msg len */ 0, /* response len */ last, /* eot */ last, /* writes complete */ i*4, /* urb destination offset */ BRW_URB_SWIZZLE_TRANSPOSE); } } }
void brw_emit_tri_setup( struct brw_sf_compile *c, GLboolean allocate) { struct brw_compile *p = &c->func; GLuint i; c->nr_verts = 3; if (allocate) alloc_regs(c); invert_det(c); copy_z_inv_w(c); if (c->key.do_twoside_color) do_twoside_color(c); if (c->key.do_flat_shading) do_flatshade_triangle(c); for (i = 0; i < c->nr_setup_regs; i++) { /* Pair of incoming attributes: */ struct brw_reg a0 = offset(c->vert[0], i); struct brw_reg a1 = offset(c->vert[1], i); struct brw_reg a2 = offset(c->vert[2], i); GLushort pc, pc_persp, pc_linear; GLboolean last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear); if (pc_persp) { brw_set_predicate_control_flag_value(p, pc_persp); brw_MUL(p, a0, a0, c->inv_w[0]); brw_MUL(p, a1, a1, c->inv_w[1]); brw_MUL(p, a2, a2, c->inv_w[2]); } /* Calculate coefficients for interpolated values: */ if (pc_linear) { brw_set_predicate_control_flag_value(p, pc_linear); brw_ADD(p, c->a1_sub_a0, a1, negate(a0)); brw_ADD(p, c->a2_sub_a0, a2, negate(a0)); /* calculate dA/dx */ brw_MUL(p, brw_null_reg(), c->a1_sub_a0, c->dy2); brw_MAC(p, c->tmp, c->a2_sub_a0, negate(c->dy0)); brw_MUL(p, c->m1Cx, c->tmp, c->inv_det); /* calculate dA/dy */ brw_MUL(p, brw_null_reg(), c->a2_sub_a0, c->dx0); brw_MAC(p, c->tmp, c->a1_sub_a0, negate(c->dx2)); brw_MUL(p, c->m2Cy, c->tmp, c->inv_det); } { brw_set_predicate_control_flag_value(p, pc); /* start point for interpolation */ brw_MOV(p, c->m3C0, a0); /* Copy m0..m3 to URB. m0 is implicitly copied from r0 in * the send instruction: */ brw_urb_WRITE(p, brw_null_reg(), 0, brw_vec8_grf(0, 0), /* r0, will be copied to m0 */ 0, /* allocate */ 1, /* used */ 4, /* msg len */ 0, /* response len */ last, /* eot */ last, /* writes complete */ i*4, /* offset */ BRW_URB_SWIZZLE_TRANSPOSE); /* XXX: Swizzle control "SF to windower" */ } } }
void brw_emit_point_sprite_setup( struct brw_sf_compile *c, GLboolean allocate) { struct brw_compile *p = &c->func; GLuint i; c->nr_verts = 1; if (allocate) alloc_regs(c); copy_z_inv_w(c); for (i = 0; i < c->nr_setup_regs; i++) { struct brw_sf_point_tex *tex = &c->point_attrs[c->idx_to_attr[2*i]]; struct brw_reg a0 = offset(c->vert[0], i); GLushort pc, pc_persp, pc_linear; GLboolean last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear); if (pc_persp) { if (!tex->CoordReplace) { brw_set_predicate_control_flag_value(p, pc_persp); brw_MUL(p, a0, a0, c->inv_w[0]); } } if (tex->CoordReplace) { /* Caculate 1.0/PointWidth */ brw_math(&c->func, c->tmp, BRW_MATH_FUNCTION_INV, BRW_MATH_SATURATE_NONE, 0, c->dx0, BRW_MATH_DATA_SCALAR, BRW_MATH_PRECISION_FULL); if (c->key.SpriteOrigin == GL_LOWER_LEFT) { brw_MUL(p, c->m1Cx, c->tmp, c->inv_w[0]); brw_MOV(p, vec1(suboffset(c->m1Cx, 1)), brw_imm_f(0.0)); brw_MUL(p, c->m2Cy, c->tmp, negate(c->inv_w[0])); brw_MOV(p, vec1(suboffset(c->m2Cy, 0)), brw_imm_f(0.0)); } else { brw_MUL(p, c->m1Cx, c->tmp, c->inv_w[0]); brw_MOV(p, vec1(suboffset(c->m1Cx, 1)), brw_imm_f(0.0)); brw_MUL(p, c->m2Cy, c->tmp, c->inv_w[0]); brw_MOV(p, vec1(suboffset(c->m2Cy, 0)), brw_imm_f(0.0)); } } else { brw_MOV(p, c->m1Cx, brw_imm_ud(0)); brw_MOV(p, c->m2Cy, brw_imm_ud(0)); } { brw_set_predicate_control_flag_value(p, pc); if (tex->CoordReplace) { if (c->key.SpriteOrigin == GL_LOWER_LEFT) { brw_MUL(p, c->m3C0, c->inv_w[0], brw_imm_f(1.0)); brw_MOV(p, vec1(suboffset(c->m3C0, 0)), brw_imm_f(0.0)); } else brw_MOV(p, c->m3C0, brw_imm_f(0.0)); } else { 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), 0, /* allocate */ 1, /* used */ 4, /* msg len */ 0, /* response len */ last, /* eot */ last, /* writes complete */ i*4, /* urb destination offset */ BRW_URB_SWIZZLE_TRANSPOSE); } } }