brw_vs_emit.c File Reference

Include dependency graph for brw_vs_emit.c:

Go to the source code of this file.

Data Structures

struct  brw_prog_info

Defines

#define MAX_IFSN   32

Functions

static void brw_vs_alloc_regs (struct brw_vs_compile *c, struct brw_prog_info *info)
static struct brw_reg get_tmp (struct brw_vs_compile *c)
static void release_tmp (struct brw_vs_compile *c, struct brw_reg tmp)
static void release_tmps (struct brw_vs_compile *c)
static void unalias1 (struct brw_vs_compile *c, struct brw_reg dst, struct brw_reg arg0, void(*func)(struct brw_vs_compile *, struct brw_reg, struct brw_reg))
static void unalias2 (struct brw_vs_compile *c, struct brw_reg dst, struct brw_reg arg0, struct brw_reg arg1, void(*func)(struct brw_vs_compile *, struct brw_reg, struct brw_reg, struct brw_reg))
static void emit_sop (struct brw_compile *p, struct brw_reg dst, struct brw_reg arg0, struct brw_reg arg1, unsigned cond)
static void emit_seq (struct brw_compile *p, struct brw_reg dst, struct brw_reg arg0, struct brw_reg arg1)
static void emit_sne (struct brw_compile *p, struct brw_reg dst, struct brw_reg arg0, struct brw_reg arg1)
static void emit_slt (struct brw_compile *p, struct brw_reg dst, struct brw_reg arg0, struct brw_reg arg1)
static void emit_sle (struct brw_compile *p, struct brw_reg dst, struct brw_reg arg0, struct brw_reg arg1)
static void emit_sgt (struct brw_compile *p, struct brw_reg dst, struct brw_reg arg0, struct brw_reg arg1)
static void emit_sge (struct brw_compile *p, struct brw_reg dst, struct brw_reg arg0, struct brw_reg arg1)
static void emit_max (struct brw_compile *p, struct brw_reg dst, struct brw_reg arg0, struct brw_reg arg1)
static void emit_min (struct brw_compile *p, struct brw_reg dst, struct brw_reg arg0, struct brw_reg arg1)
static void emit_math1 (struct brw_vs_compile *c, unsigned function, struct brw_reg dst, struct brw_reg arg0, unsigned precision)
static void emit_math2 (struct brw_vs_compile *c, unsigned function, struct brw_reg dst, struct brw_reg arg0, struct brw_reg arg1, unsigned precision)
static void emit_exp_noalias (struct brw_vs_compile *c, struct brw_reg dst, struct brw_reg arg0)
static void emit_log_noalias (struct brw_vs_compile *c, struct brw_reg dst, struct brw_reg arg0)
static void emit_dst_noalias (struct brw_vs_compile *c, struct brw_reg dst, struct brw_reg arg0, struct brw_reg arg1)
static void emit_xpd (struct brw_compile *p, struct brw_reg dst, struct brw_reg t, struct brw_reg u)
static void emit_lit_noalias (struct brw_vs_compile *c, struct brw_reg dst, struct brw_reg arg0)
static struct brw_reg get_reg (struct brw_vs_compile *c, unsigned file, unsigned index)
static struct brw_reg deref (struct brw_vs_compile *c, struct brw_reg arg, int offset)
static void emit_arl (struct brw_vs_compile *c, struct brw_reg dst, struct brw_reg arg0)
static struct brw_reg get_arg (struct brw_vs_compile *c, struct tgsi_src_register *src)
static struct brw_reg get_dst (struct brw_vs_compile *c, const struct tgsi_dst_register *dst)
static void emit_swz (struct brw_vs_compile *c, struct brw_reg dst, struct tgsi_src_register src)
static void emit_vertex_write (struct brw_vs_compile *c, struct brw_prog_info *info)
static void post_vs_emit (struct brw_vs_compile *c, struct brw_instruction *end_inst)
static void process_declaration (const struct tgsi_full_declaration *decl, struct brw_prog_info *info)
static void process_instruction (struct brw_vs_compile *c, struct tgsi_full_instruction *inst, struct brw_prog_info *info)
void brw_vs_emit (struct brw_vs_compile *c)


Define Documentation

#define MAX_IFSN   32


Function Documentation

static void brw_vs_alloc_regs ( struct brw_vs_compile c,
struct brw_prog_info info 
) [static]

Definition at line 54 of file brw_vs_emit.c.

References BRW_GENERAL_REGISTER_FILE, BRW_HORIZONTAL_STRIDE_1, brw_message_reg(), brw_reg(), BRW_REGISTER_TYPE_D, BRW_SWIZZLE_XXXX, brw_uw16_reg(), brw_vec4_grf(), brw_vec8_grf(), BRW_VERTICAL_STRIDE_8, BRW_WIDTH_8, brw_vs_prog_data::curb_read_length, brw_vs_compile::first_output, brw_vs_compile::first_tmp, brw_vertex_program::info, brw_vs_compile::key, brw_vs_compile::last_tmp, brw_vs_prog_data::max_const, brw_vs_compile::nr_inputs, brw_vs_compile::nr_outputs, brw_vs_prog_key::nr_userclip, brw_prog_info::num_addrs, tgsi_shader_info::num_inputs, tgsi_shader_info::num_outputs, brw_prog_info::num_temps, brw_vs_compile::output_regs, brw_prog_info::pos_idx, brw_vs_compile::prog_data, brw_vs_compile::r0, brw_vs_compile::reg, brw_vs_compile::regs, brw_vs_compile::stack, stride(), TGSI_FILE_ADDRESS, TGSI_FILE_CONSTANT, TGSI_FILE_INPUT, TGSI_FILE_OUTPUT, TGSI_FILE_TEMPORARY, TGSI_WRITEMASK_X, brw_vs_prog_data::total_grf, brw_vs_prog_data::urb_entry_size, brw_vs_prog_data::urb_read_length, brw_vs_compile::used_in_src, brw_vs_compile::userplane, and brw_vs_compile::vp.

00056 {
00057    unsigned i, reg = 0, mrf;
00058    unsigned nr_params;
00059 
00060    /* r0 -- reserved as usual
00061     */
00062    c->r0 = brw_vec8_grf(reg, 0); reg++;
00063 
00064    /* User clip planes from curbe:
00065     */
00066    if (c->key.nr_userclip) {
00067       for (i = 0; i < c->key.nr_userclip; i++) {
00068          c->userplane[i] = stride( brw_vec4_grf(reg+3+i/2, (i%2) * 4), 0, 4, 1);
00069       }
00070 
00071       /* Deal with curbe alignment:
00072        */
00073       reg += ((6+c->key.nr_userclip+3)/4)*2;
00074    }
00075 
00076    /* Vertex program parameters from curbe:
00077     */
00078    nr_params = c->prog_data.max_const;
00079    for (i = 0; i < nr_params; i++) {
00080       c->regs[TGSI_FILE_CONSTANT][i] = stride(brw_vec4_grf(reg+i/2, (i%2) * 4), 0, 4, 1);
00081    }
00082    reg += (nr_params+1)/2;
00083    c->prog_data.curb_read_length = reg - 1;
00084 
00085 
00086 
00087    /* Allocate input regs:
00088     */
00089    c->nr_inputs = c->vp->info.num_inputs;
00090    for (i = 0; i < c->nr_inputs; i++) {
00091          c->regs[TGSI_FILE_INPUT][i] = brw_vec8_grf(reg, 0);
00092          reg++;
00093    }
00094 
00095 
00096    /* Allocate outputs: TODO: could organize the non-position outputs
00097     * to go straight into message regs.
00098     */
00099    c->nr_outputs = 0;
00100    c->first_output = reg;
00101    mrf = 4;
00102    for (i = 0; i < c->vp->info.num_outputs; i++) {
00103       c->nr_outputs++;
00104 #if 0
00105       if (i == VERT_RESULT_HPOS) {
00106          c->regs[TGSI_FILE_OUTPUT][i] = brw_vec8_grf(reg, 0);
00107          reg++;
00108       }
00109       else if (i == VERT_RESULT_PSIZ) {
00110          c->regs[TGSI_FILE_OUTPUT][i] = brw_vec8_grf(reg, 0);
00111          reg++;
00112          mrf++;         /* just a placeholder?  XXX fix later stages & remove this */
00113       }
00114       else {
00115          c->regs[TGSI_FILE_OUTPUT][i] = brw_message_reg(mrf);
00116          mrf++;
00117       }
00118 #else
00119       /*treat pos differently for now */
00120       if (i == info->pos_idx) {
00121          c->regs[TGSI_FILE_OUTPUT][i] = brw_vec8_grf(reg, 0);
00122          reg++;
00123       } else {
00124          c->regs[TGSI_FILE_OUTPUT][i] = brw_message_reg(mrf);
00125          mrf++;
00126       }
00127 #endif
00128    }
00129 
00130    /* Allocate program temporaries:
00131     */
00132    for (i = 0; i < info->num_temps; i++) {
00133       c->regs[TGSI_FILE_TEMPORARY][i] = brw_vec8_grf(reg, 0);
00134       reg++;
00135    }
00136 
00137    /* Address reg(s).  Don't try to use the internal address reg until
00138     * deref time.
00139     */
00140    for (i = 0; i < info->num_addrs; i++) {
00141       c->regs[TGSI_FILE_ADDRESS][i] =  brw_reg(BRW_GENERAL_REGISTER_FILE,
00142                                                reg,
00143                                                0,
00144                                                BRW_REGISTER_TYPE_D,
00145                                                BRW_VERTICAL_STRIDE_8,
00146                                                BRW_WIDTH_8,
00147                                                BRW_HORIZONTAL_STRIDE_1,
00148                                                BRW_SWIZZLE_XXXX,
00149                                                TGSI_WRITEMASK_X);
00150       reg++;
00151    }
00152 
00153    for (i = 0; i < 128; i++) {
00154       if (c->output_regs[i].used_in_src) {
00155          c->output_regs[i].reg = brw_vec8_grf(reg, 0);
00156          reg++;
00157       }
00158    }
00159 
00160    c->stack =  brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, reg, 0);
00161    reg += 2;
00162 
00163 
00164    /* Some opcodes need an internal temporary:
00165     */
00166    c->first_tmp = reg;
00167    c->last_tmp = reg;           /* for allocation purposes */
00168 
00169    /* Each input reg holds data from two vertices.  The
00170     * urb_read_length is the number of registers read from *each*
00171     * vertex urb, so is half the amount:
00172     */
00173    c->prog_data.urb_read_length = (c->nr_inputs+1)/2;
00174 
00175    c->prog_data.urb_entry_size = (c->nr_outputs+2+3)/4;
00176    c->prog_data.total_grf = reg;
00177 }

void brw_vs_emit ( struct brw_vs_compile c  ) 

Definition at line 1243 of file brw_vs_emit.c.

References brw_address(), BRW_ALIGN_1, BRW_ALIGN_16, BRW_COMPRESSION_NONE, brw_indirect(), brw_MOV(), brw_set_access_mode(), brw_set_compression_control(), brw_vs_alloc_regs(), emit_vertex_write(), tgsi_src_register::File, tgsi_immediate_float32::Float, tgsi_full_token::FullDeclaration, tgsi_full_token::FullImmediate, tgsi_full_token::FullInstruction, tgsi_full_instruction::FullSrcRegisters, tgsi_parse_context::FullToken, brw_vs_compile::func, get_addr_reg(), brw_vs_prog_data::imm_buf, tgsi_full_immediate::ImmediateFloat32, tgsi_src_register::Index, brw_vs_prog_data::max_const, brw_compile::nr_insn, brw_prog_info::num_consts, brw_vs_prog_data::num_consts, brw_vs_prog_data::num_imm, brw_vs_compile::output_regs, post_vs_emit(), process_declaration(), process_instruction(), brw_vs_compile::prog_data, brw_vertex_program::program, tgsi_full_src_register::SrcRegister, brw_vs_compile::stack, brw_compile::store, TGSI_FILE_OUTPUT, tgsi_parse_end_of_tokens(), tgsi_parse_free(), tgsi_parse_init(), tgsi_parse_token(), TGSI_TOKEN_TYPE_DECLARATION, TGSI_TOKEN_TYPE_IMMEDIATE, TGSI_TOKEN_TYPE_INSTRUCTION, tgsi_full_token::Token, pipe_shader_state::tokens, TRUE, tgsi_token::Type, tgsi_full_immediate::u, brw_vs_compile::used_in_src, and brw_vs_compile::vp.

01244 {
01245 #define MAX_IFSN 32
01246    struct brw_compile *p = &c->func;
01247    struct brw_instruction *end_inst;
01248    struct tgsi_parse_context parse;
01249    struct brw_indirect stack_index = brw_indirect(0, 0);
01250    const struct tgsi_token *tokens = c->vp->program.tokens;
01251    struct brw_prog_info prog_info;
01252    unsigned allocated_registers = 0;
01253    memset(&prog_info, 0, sizeof(struct brw_prog_info));
01254 
01255    brw_set_compression_control(p, BRW_COMPRESSION_NONE);
01256    brw_set_access_mode(p, BRW_ALIGN_16);
01257 
01258    tgsi_parse_init(&parse, tokens);
01259    /* Message registers can't be read, so copy the output into GRF register
01260       if they are used in source registers */
01261    while (!tgsi_parse_end_of_tokens(&parse)) {
01262       tgsi_parse_token(&parse);
01263       unsigned i;
01264       switch (parse.FullToken.Token.Type) {
01265       case TGSI_TOKEN_TYPE_INSTRUCTION: {
01266          const struct tgsi_full_instruction *inst = &parse.FullToken.FullInstruction;
01267          for (i = 0; i < 3; ++i) {
01268             const struct tgsi_src_register *src = &inst->FullSrcRegisters[i].SrcRegister;
01269             unsigned index = src->Index;
01270             unsigned file = src->File;
01271             if (file == TGSI_FILE_OUTPUT)
01272                c->output_regs[index].used_in_src = TRUE;
01273          }
01274       }
01275          break;
01276       default:
01277          /* nothing */
01278          break;
01279       }
01280    }
01281    tgsi_parse_free(&parse);
01282 
01283    tgsi_parse_init(&parse, tokens);
01284 
01285    while (!tgsi_parse_end_of_tokens(&parse)) {
01286       tgsi_parse_token(&parse);
01287 
01288       switch (parse.FullToken.Token.Type) {
01289       case TGSI_TOKEN_TYPE_DECLARATION: {
01290          struct tgsi_full_declaration *decl = &parse.FullToken.FullDeclaration;
01291          process_declaration(decl, &prog_info);
01292       }
01293          break;
01294       case TGSI_TOKEN_TYPE_IMMEDIATE: {
01295          struct tgsi_full_immediate *imm = &parse.FullToken.FullImmediate;
01296          /*assert(imm->Immediate.Size == 4);*/
01297          c->prog_data.imm_buf[c->prog_data.num_imm][0] = imm->u.ImmediateFloat32[0].Float;
01298          c->prog_data.imm_buf[c->prog_data.num_imm][1] = imm->u.ImmediateFloat32[1].Float;
01299          c->prog_data.imm_buf[c->prog_data.num_imm][2] = imm->u.ImmediateFloat32[2].Float;
01300          c->prog_data.imm_buf[c->prog_data.num_imm][3] = imm->u.ImmediateFloat32[3].Float;
01301          c->prog_data.num_imm++;
01302       }
01303          break;
01304       case TGSI_TOKEN_TYPE_INSTRUCTION: {
01305          struct tgsi_full_instruction *inst = &parse.FullToken.FullInstruction;
01306          if (!allocated_registers) {
01307             /* first instruction (declerations finished).
01308              * now that we know what vars are being used allocate
01309              * registers for them.*/
01310             c->prog_data.num_consts = prog_info.num_consts;
01311             c->prog_data.max_const = prog_info.num_consts + c->prog_data.num_imm;
01312             brw_vs_alloc_regs(c, &prog_info);
01313 
01314             brw_set_access_mode(p, BRW_ALIGN_1);
01315             brw_MOV(p, get_addr_reg(stack_index), brw_address(c->stack));
01316             brw_set_access_mode(p, BRW_ALIGN_16);
01317             allocated_registers = 1;
01318          }
01319          process_instruction(c, inst, &prog_info);
01320       }
01321          break;
01322       }
01323    }
01324 
01325    end_inst = &p->store[p->nr_insn];
01326    emit_vertex_write(c, &prog_info);
01327    post_vs_emit(c, end_inst);
01328    tgsi_parse_free(&parse);
01329 
01330 }

static struct brw_reg deref ( struct brw_vs_compile c,
struct brw_reg  arg,
int  offset 
) [static, read]

Definition at line 653 of file brw_vs_emit.c.

References brw_ADD(), brw_address_reg(), BRW_ALIGN_1, brw_imm_d(), brw_MOV(), brw_pop_insn_state(), brw_push_insn_state(), BRW_REGISTER_TYPE_UW, brw_set_access_mode(), brw_vec4_indirect(), byte_offset(), get_reg(), get_tmp(), brw_reg::nr, offset(), retype(), suboffset(), TGSI_FILE_ADDRESS, vec1(), vec4(), and vec8().

00656 {
00657    struct brw_compile *p = &c->func;
00658    struct brw_reg tmp = vec4(get_tmp(c));
00659    struct brw_reg vp_address = retype(vec1(get_reg(c, TGSI_FILE_ADDRESS, 0)), BRW_REGISTER_TYPE_UW);
00660    unsigned byte_offset = arg.nr * 32 + arg.subnr + offset * 16;
00661    struct brw_reg indirect = brw_vec4_indirect(0,0);
00662 
00663    {
00664       brw_push_insn_state(p);
00665       brw_set_access_mode(p, BRW_ALIGN_1);
00666 
00667       /* This is pretty clunky - load the address register twice and
00668        * fetch each 4-dword value in turn.  There must be a way to do
00669        * this in a single pass, but I couldn't get it to work.
00670        */
00671       brw_ADD(p, brw_address_reg(0), vp_address, brw_imm_d(byte_offset));
00672       brw_MOV(p, tmp, indirect);
00673 
00674       brw_ADD(p, brw_address_reg(0), suboffset(vp_address, 8), brw_imm_d(byte_offset));
00675       brw_MOV(p, suboffset(tmp, 4), indirect);
00676 
00677       brw_pop_insn_state(p);
00678    }
00679 
00680    return vec8(tmp);
00681 }

static void emit_arl ( struct brw_vs_compile c,
struct brw_reg  dst,
struct brw_reg  arg0 
) [static]

Definition at line 684 of file brw_vs_emit.c.

References BRW_GENERAL_REGISTER_FILE, brw_imm_d(), brw_MUL(), brw_RNDD(), brw_reg::file, brw_vs_compile::func, get_tmp(), and release_tmp().

00687 {
00688    struct brw_compile *p = &c->func;
00689    struct brw_reg tmp = dst;
00690    boolean need_tmp = (dst.file != BRW_GENERAL_REGISTER_FILE);
00691 
00692    if (need_tmp)
00693       tmp = get_tmp(c);
00694 
00695    brw_RNDD(p, tmp, arg0);
00696    brw_MUL(p, dst, tmp, brw_imm_d(16));
00697 
00698    if (need_tmp)
00699       release_tmp(c, tmp);
00700 }

static void emit_dst_noalias ( struct brw_vs_compile c,
struct brw_reg  dst,
struct brw_reg  arg0,
struct brw_reg  arg1 
) [static]

Definition at line 546 of file brw_vs_emit.c.

References brw_reg::bits, brw_imm_f(), brw_MOV(), brw_MUL(), brw_writemask(), brw_reg::dw1, brw_vs_compile::func, TGSI_WRITEMASK_W, TGSI_WRITEMASK_X, TGSI_WRITEMASK_Y, and TGSI_WRITEMASK_Z.

00550 {
00551    struct brw_compile *p = &c->func;
00552 
00553    /* There must be a better way to do this:
00554     */
00555    if (dst.dw1.bits.writemask & TGSI_WRITEMASK_X)
00556       brw_MOV(p, brw_writemask(dst, TGSI_WRITEMASK_X), brw_imm_f(1.0));
00557    if (dst.dw1.bits.writemask & TGSI_WRITEMASK_Y)
00558       brw_MUL(p, brw_writemask(dst, TGSI_WRITEMASK_Y), arg0, arg1);
00559    if (dst.dw1.bits.writemask & TGSI_WRITEMASK_Z)
00560       brw_MOV(p, brw_writemask(dst, TGSI_WRITEMASK_Z), arg0);
00561    if (dst.dw1.bits.writemask & TGSI_WRITEMASK_W)
00562       brw_MOV(p, brw_writemask(dst, TGSI_WRITEMASK_W), arg1);
00563 }

static void emit_exp_noalias ( struct brw_vs_compile c,
struct brw_reg  dst,
struct brw_reg  arg0 
) [static]

Definition at line 394 of file brw_vs_emit.c.

References brw_reg::bits, brw_ADD(), brw_FRC(), brw_imm_d(), brw_imm_f(), BRW_MATH_FUNCTION_EXP, BRW_MATH_PRECISION_PARTIAL, brw_MOV(), BRW_REGISTER_TYPE_D, brw_RNDD(), brw_SHL(), brw_swizzle1(), brw_writemask(), brw_reg::dw1, emit_math1(), brw_vs_compile::func, get_tmp(), release_tmp(), retype(), TGSI_WRITEMASK_W, TGSI_WRITEMASK_X, TGSI_WRITEMASK_Y, and TGSI_WRITEMASK_Z.

00397 {
00398    struct brw_compile *p = &c->func;
00399 
00400 
00401    if (dst.dw1.bits.writemask & TGSI_WRITEMASK_X) {
00402       struct brw_reg tmp = get_tmp(c);
00403       struct brw_reg tmp_d = retype(tmp, BRW_REGISTER_TYPE_D);
00404 
00405       /* tmp_d = floor(arg0.x) */
00406       brw_RNDD(p, tmp_d, brw_swizzle1(arg0, 0));
00407 
00408       /* result[0] = 2.0 ^ tmp */
00409 
00410       /* Adjust exponent for floating point:
00411        * exp += 127
00412        */
00413       brw_ADD(p, brw_writemask(tmp_d, TGSI_WRITEMASK_X), tmp_d, brw_imm_d(127));
00414 
00415       /* Install exponent and sign.
00416        * Excess drops off the edge:
00417        */
00418       brw_SHL(p, brw_writemask(retype(dst, BRW_REGISTER_TYPE_D), TGSI_WRITEMASK_X),
00419               tmp_d, brw_imm_d(23));
00420 
00421       release_tmp(c, tmp);
00422    }
00423 
00424    if (dst.dw1.bits.writemask & TGSI_WRITEMASK_Y) {
00425       /* result[1] = arg0.x - floor(arg0.x) */
00426       brw_FRC(p, brw_writemask(dst, TGSI_WRITEMASK_Y), brw_swizzle1(arg0, 0));
00427    }
00428 
00429    if (dst.dw1.bits.writemask & TGSI_WRITEMASK_Z) {
00430       /* As with the LOG instruction, we might be better off just
00431        * doing a taylor expansion here, seeing as we have to do all
00432        * the prep work.
00433        *
00434        * If mathbox partial precision is too low, consider also:
00435        * result[3] = result[0] * EXP(result[1])
00436        */
00437       emit_math1(c,
00438                  BRW_MATH_FUNCTION_EXP,
00439                  brw_writemask(dst, TGSI_WRITEMASK_Z),
00440                  brw_swizzle1(arg0, 0),
00441                  BRW_MATH_PRECISION_PARTIAL);
00442    }
00443 
00444    if (dst.dw1.bits.writemask & TGSI_WRITEMASK_W) {
00445       /* result[3] = 1.0; */
00446       brw_MOV(p, brw_writemask(dst, TGSI_WRITEMASK_W), brw_imm_f(1));
00447    }
00448 }

static void emit_lit_noalias ( struct brw_vs_compile c,
struct brw_reg  dst,
struct brw_reg  arg0 
) [static]

Definition at line 576 of file brw_vs_emit.c.

References brw_CMP(), BRW_CONDITIONAL_G, brw_ENDIF(), BRW_EXECUTE_8, BRW_GENERAL_REGISTER_FILE, brw_IF(), brw_imm_f(), BRW_MATH_FUNCTION_POW, BRW_MATH_PRECISION_PARTIAL, brw_MOV(), brw_null_reg(), BRW_PREDICATE_NONE, brw_set_predicate_control(), brw_swizzle1(), brw_writemask(), emit_math2(), brw_reg::file, brw_vs_compile::func, get_tmp(), TGSI_WRITEMASK_XW, TGSI_WRITEMASK_Y, TGSI_WRITEMASK_YZ, and TGSI_WRITEMASK_Z.

00579 {
00580    struct brw_compile *p = &c->func;
00581    struct brw_instruction *if_insn;
00582    struct brw_reg tmp = dst;
00583    boolean need_tmp = (dst.file != BRW_GENERAL_REGISTER_FILE);
00584 
00585    if (need_tmp)
00586       tmp = get_tmp(c);
00587 
00588    brw_MOV(p, brw_writemask(dst, TGSI_WRITEMASK_YZ), brw_imm_f(0));
00589    brw_MOV(p, brw_writemask(dst, TGSI_WRITEMASK_XW), brw_imm_f(1));
00590 
00591    /* Need to use BRW_EXECUTE_8 and also do an 8-wide compare in order
00592     * to get all channels active inside the IF.  In the clipping code
00593     * we run with NoMask, so it's not an option and we can use
00594     * BRW_EXECUTE_1 for all comparisions.
00595     */
00596    brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_G, brw_swizzle1(arg0,0), brw_imm_f(0));
00597    if_insn = brw_IF(p, BRW_EXECUTE_8);
00598    {
00599       brw_MOV(p, brw_writemask(dst, TGSI_WRITEMASK_Y), brw_swizzle1(arg0,0));
00600 
00601       brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_G, brw_swizzle1(arg0,1), brw_imm_f(0));
00602       brw_MOV(p, brw_writemask(tmp, TGSI_WRITEMASK_Z),  brw_swizzle1(arg0,1));
00603       brw_set_predicate_control(p, BRW_PREDICATE_NONE);
00604 
00605       emit_math2(c,
00606                  BRW_MATH_FUNCTION_POW,
00607                  brw_writemask(dst, TGSI_WRITEMASK_Z),
00608                  brw_swizzle1(tmp, 2),
00609                  brw_swizzle1(arg0, 3),
00610                  BRW_MATH_PRECISION_PARTIAL);
00611    }
00612 
00613    brw_ENDIF(p, if_insn);
00614 }

static void emit_log_noalias ( struct brw_vs_compile c,
struct brw_reg  dst,
struct brw_reg  arg0 
) [static]

Definition at line 451 of file brw_vs_emit.c.

References brw_reg::bits, brw_ADD(), brw_AND(), BRW_GENERAL_REGISTER_FILE, brw_imm_d(), brw_imm_f(), brw_imm_ud(), BRW_MATH_FUNCTION_LOG, BRW_MATH_PRECISION_FULL, brw_MOV(), brw_OR(), BRW_REGISTER_TYPE_D, BRW_REGISTER_TYPE_UD, brw_SHR(), brw_swizzle1(), brw_writemask(), brw_reg::dw1, emit_math1(), brw_reg::file, brw_vs_compile::func, get_tmp(), release_tmp(), retype(), TGSI_WRITEMASK_W, TGSI_WRITEMASK_X, TGSI_WRITEMASK_XZ, TGSI_WRITEMASK_Y, TGSI_WRITEMASK_YZ, and TGSI_WRITEMASK_Z.

00454 {
00455    struct brw_compile *p = &c->func;
00456    struct brw_reg tmp = dst;
00457    struct brw_reg tmp_ud = retype(tmp, BRW_REGISTER_TYPE_UD);
00458    struct brw_reg arg0_ud = retype(arg0, BRW_REGISTER_TYPE_UD);
00459    boolean need_tmp = (dst.dw1.bits.writemask != 0xf ||
00460                          dst.file != BRW_GENERAL_REGISTER_FILE);
00461 
00462    if (need_tmp) {
00463       tmp = get_tmp(c);
00464       tmp_ud = retype(tmp, BRW_REGISTER_TYPE_UD);
00465    }
00466 
00467    /* Perform mant = frexpf(fabsf(x), &exp), adjust exp and mnt
00468     * according to spec:
00469     *
00470     * These almost look likey they could be joined up, but not really
00471     * practical:
00472     *
00473     * result[0].f = (x.i & ((1<<31)-1) >> 23) - 127
00474     * result[1].i = (x.i & ((1<<23)-1)        + (127<<23)
00475     */
00476    if (dst.dw1.bits.writemask & TGSI_WRITEMASK_XZ) {
00477       brw_AND(p,
00478               brw_writemask(tmp_ud, TGSI_WRITEMASK_X),
00479               brw_swizzle1(arg0_ud, 0),
00480               brw_imm_ud((1U<<31)-1));
00481 
00482       brw_SHR(p,
00483               brw_writemask(tmp_ud, TGSI_WRITEMASK_X),
00484               tmp_ud,
00485               brw_imm_ud(23));
00486 
00487       brw_ADD(p,
00488               brw_writemask(tmp, TGSI_WRITEMASK_X),
00489               retype(tmp_ud, BRW_REGISTER_TYPE_D),      /* does it matter? */
00490               brw_imm_d(-127));
00491    }
00492 
00493    if (dst.dw1.bits.writemask & TGSI_WRITEMASK_YZ) {
00494       brw_AND(p,
00495               brw_writemask(tmp_ud, TGSI_WRITEMASK_Y),
00496               brw_swizzle1(arg0_ud, 0),
00497               brw_imm_ud((1<<23)-1));
00498 
00499       brw_OR(p,
00500              brw_writemask(tmp_ud, TGSI_WRITEMASK_Y),
00501              tmp_ud,
00502              brw_imm_ud(127<<23));
00503    }
00504 
00505    if (dst.dw1.bits.writemask & TGSI_WRITEMASK_Z) {
00506       /* result[2] = result[0] + LOG2(result[1]); */
00507 
00508       /* Why bother?  The above is just a hint how to do this with a
00509        * taylor series.  Maybe we *should* use a taylor series as by
00510        * the time all the above has been done it's almost certainly
00511        * quicker than calling the mathbox, even with low precision.
00512        *
00513        * Options are:
00514        *    - result[0] + mathbox.LOG2(result[1])
00515        *    - mathbox.LOG2(arg0.x)
00516        *    - result[0] + inline_taylor_approx(result[1])
00517        */
00518       emit_math1(c,
00519                  BRW_MATH_FUNCTION_LOG,
00520                  brw_writemask(tmp, TGSI_WRITEMASK_Z),
00521                  brw_swizzle1(tmp, 1),
00522                  BRW_MATH_PRECISION_FULL);
00523 
00524       brw_ADD(p,
00525               brw_writemask(tmp, TGSI_WRITEMASK_Z),
00526               brw_swizzle1(tmp, 2),
00527               brw_swizzle1(tmp, 0));
00528    }
00529 
00530    if (dst.dw1.bits.writemask & TGSI_WRITEMASK_W) {
00531       /* result[3] = 1.0; */
00532       brw_MOV(p, brw_writemask(tmp, TGSI_WRITEMASK_W), brw_imm_f(1));
00533    }
00534 
00535    if (need_tmp) {
00536       brw_MOV(p, dst, tmp);
00537       release_tmp(c, tmp);
00538    }
00539 }

static void emit_math1 ( struct brw_vs_compile c,
unsigned  function,
struct brw_reg  dst,
struct brw_reg  arg0,
unsigned  precision 
) [static]

Definition at line 324 of file brw_vs_emit.c.

References brw_reg::bits, BRW_GENERAL_REGISTER_FILE, brw_math(), BRW_MATH_DATA_SCALAR, BRW_MATH_SATURATE_NONE, brw_MOV(), brw_reg::dw1, brw_reg::file, brw_vs_compile::func, get_tmp(), and release_tmp().

00329 {
00330    /* There are various odd behaviours with SEND on the simulator.  In
00331     * addition there are documented issues with the fact that the GEN4
00332     * processor doesn't do dependency control properly on SEND
00333     * results.  So, on balance, this kludge to get around failures
00334     * with writemasked math results looks like it might be necessary
00335     * whether that turns out to be a simulator bug or not:
00336     */
00337    struct brw_compile *p = &c->func;
00338    struct brw_reg tmp = dst;
00339    boolean need_tmp = (dst.dw1.bits.writemask != 0xf ||
00340                          dst.file != BRW_GENERAL_REGISTER_FILE);
00341 
00342    if (need_tmp)
00343       tmp = get_tmp(c);
00344 
00345    brw_math(p,
00346             tmp,
00347             function,
00348             BRW_MATH_SATURATE_NONE,
00349             2,
00350             arg0,
00351             BRW_MATH_DATA_SCALAR,
00352             precision);
00353 
00354    if (need_tmp) {
00355       brw_MOV(p, dst, tmp);
00356       release_tmp(c, tmp);
00357    }
00358 }

static void emit_math2 ( struct brw_vs_compile c,
unsigned  function,
struct brw_reg  dst,
struct brw_reg  arg0,
struct brw_reg  arg1,
unsigned  precision 
) [static]

Definition at line 360 of file brw_vs_emit.c.

References brw_reg::bits, BRW_GENERAL_REGISTER_FILE, brw_math(), BRW_MATH_DATA_SCALAR, BRW_MATH_SATURATE_NONE, brw_message_reg(), brw_MOV(), brw_reg::dw1, brw_reg::file, brw_vs_compile::func, get_tmp(), and release_tmp().

00366 {
00367    struct brw_compile *p = &c->func;
00368    struct brw_reg tmp = dst;
00369    boolean need_tmp = (dst.dw1.bits.writemask != 0xf ||
00370                          dst.file != BRW_GENERAL_REGISTER_FILE);
00371 
00372    if (need_tmp)
00373       tmp = get_tmp(c);
00374 
00375    brw_MOV(p, brw_message_reg(3), arg1);
00376 
00377    brw_math(p,
00378             tmp,
00379             function,
00380             BRW_MATH_SATURATE_NONE,
00381             2,
00382             arg0,
00383             BRW_MATH_DATA_SCALAR,
00384             precision);
00385 
00386    if (need_tmp) {
00387       brw_MOV(p, dst, tmp);
00388       release_tmp(c, tmp);
00389    }
00390 }

static void emit_max ( struct brw_compile p,
struct brw_reg  dst,
struct brw_reg  arg0,
struct brw_reg  arg1 
) [static]

Definition at line 303 of file brw_vs_emit.c.

References brw_CMP(), BRW_CONDITIONAL_L, brw_null_reg(), BRW_PREDICATE_NONE, brw_SEL(), and brw_set_predicate_control().

00307 {
00308    brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, arg0, arg1);
00309    brw_SEL(p, dst, arg1, arg0);
00310    brw_set_predicate_control(p, BRW_PREDICATE_NONE);
00311 }

static void emit_min ( struct brw_compile p,
struct brw_reg  dst,
struct brw_reg  arg0,
struct brw_reg  arg1 
) [static]

Definition at line 313 of file brw_vs_emit.c.

References brw_CMP(), BRW_CONDITIONAL_L, brw_null_reg(), BRW_PREDICATE_NONE, brw_SEL(), and brw_set_predicate_control().

00317 {
00318    brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, arg0, arg1);
00319    brw_SEL(p, dst, arg0, arg1);
00320    brw_set_predicate_control(p, BRW_PREDICATE_NONE);
00321 }

static void emit_seq ( struct brw_compile p,
struct brw_reg  dst,
struct brw_reg  arg0,
struct brw_reg  arg1 
) [static]

Definition at line 256 of file brw_vs_emit.c.

References BRW_CONDITIONAL_EQ, and emit_sop().

00260 {
00261    emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_EQ);
00262 }

static void emit_sge ( struct brw_compile p,
struct brw_reg  dst,
struct brw_reg  arg0,
struct brw_reg  arg1 
) [static]

Definition at line 295 of file brw_vs_emit.c.

References BRW_CONDITIONAL_GE, and emit_sop().

00299 {
00300   emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_GE);
00301 }

static void emit_sgt ( struct brw_compile p,
struct brw_reg  dst,
struct brw_reg  arg0,
struct brw_reg  arg1 
) [static]

Definition at line 287 of file brw_vs_emit.c.

References BRW_CONDITIONAL_G, and emit_sop().

00291 {
00292    emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_G);
00293 }

static void emit_sle ( struct brw_compile p,
struct brw_reg  dst,
struct brw_reg  arg0,
struct brw_reg  arg1 
) [static]

Definition at line 279 of file brw_vs_emit.c.

References BRW_CONDITIONAL_LE, and emit_sop().

00283 {
00284    emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_LE);
00285 }

static void emit_slt ( struct brw_compile p,
struct brw_reg  dst,
struct brw_reg  arg0,
struct brw_reg  arg1 
) [static]

Definition at line 271 of file brw_vs_emit.c.

References BRW_CONDITIONAL_L, and emit_sop().

00275 {
00276    emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_L);
00277 }

static void emit_sne ( struct brw_compile p,
struct brw_reg  dst,
struct brw_reg  arg0,
struct brw_reg  arg1 
) [static]

Definition at line 264 of file brw_vs_emit.c.

References BRW_CONDITIONAL_NEQ, and emit_sop().

00268 {
00269    emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_NEQ);
00270 }

static void emit_sop ( struct brw_compile p,
struct brw_reg  dst,
struct brw_reg  arg0,
struct brw_reg  arg1,
unsigned  cond 
) [static]

Definition at line 241 of file brw_vs_emit.c.

References brw_CMP(), brw_imm_f(), brw_MOV(), brw_null_reg(), brw_pop_insn_state(), BRW_PREDICATE_NONE, BRW_PREDICATE_NORMAL, brw_push_insn_state(), brw_set_predicate_control(), and brw_reg::f.

00246 {
00247    brw_push_insn_state(p);
00248    brw_CMP(p, brw_null_reg(), cond, arg0, arg1);
00249    brw_set_predicate_control(p, BRW_PREDICATE_NONE);
00250    brw_MOV(p, dst, brw_imm_f(1.0f));
00251    brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
00252    brw_MOV(p, dst, brw_imm_f(0.0f));
00253    brw_pop_insn_state(p);
00254 }

static void emit_swz ( struct brw_vs_compile c,
struct brw_reg  dst,
struct tgsi_src_register  src 
) [static]

Definition at line 750 of file brw_vs_emit.c.

References brw_reg::bits, BRW_GENERAL_REGISTER_FILE, brw_imm_f(), brw_MOV(), brw_swizzle(), brw_writemask(), deref(), brw_reg::dw1, tgsi_src_register::File, brw_reg::file, brw_vs_compile::func, get_reg(), get_tmp(), tgsi_src_register::Index, negate(), tgsi_src_register::Negate, brw_vs_compile::regs, release_tmp(), tgsi_src_register::SwizzleW, tgsi_src_register::SwizzleX, tgsi_src_register::SwizzleY, tgsi_src_register::SwizzleZ, TGSI_EXTSWIZZLE_ONE, TGSI_EXTSWIZZLE_ZERO, TGSI_SWIZZLE_W, TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y, and TGSI_SWIZZLE_Z.

00753 {
00754    struct brw_compile *p = &c->func;
00755    unsigned zeros_mask = 0;
00756    unsigned ones_mask = 0;
00757    unsigned src_mask = 0;
00758    ubyte src_swz[4];
00759    boolean need_tmp = (src.Negate &&
00760                          dst.file != BRW_GENERAL_REGISTER_FILE);
00761    struct brw_reg tmp = dst;
00762    unsigned i;
00763 
00764    if (need_tmp)
00765       tmp = get_tmp(c);
00766 
00767    for (i = 0; i < 4; i++) {
00768       if (dst.dw1.bits.writemask & (1<<i)) {
00769          ubyte s = 0;
00770          switch(i) {
00771          case 0:
00772             s = src.SwizzleX;
00773             break;
00774             s = src.SwizzleY;
00775          case 1:
00776             break;
00777             s = src.SwizzleZ;
00778          case 2:
00779             break;
00780             s = src.SwizzleW;
00781          case 3:
00782             break;
00783          }
00784          switch (s) {
00785          case TGSI_SWIZZLE_X:
00786          case TGSI_SWIZZLE_Y:
00787          case TGSI_SWIZZLE_Z:
00788          case TGSI_SWIZZLE_W:
00789             src_mask |= 1<<i;
00790             src_swz[i] = s;
00791             break;
00792          case TGSI_EXTSWIZZLE_ZERO:
00793             zeros_mask |= 1<<i;
00794             break;
00795          case TGSI_EXTSWIZZLE_ONE:
00796             ones_mask |= 1<<i;
00797             break;
00798          }
00799       }
00800    }
00801 
00802    /* Do src first, in case dst aliases src:
00803     */
00804    if (src_mask) {
00805       struct brw_reg arg0;
00806 
00807 #if 0
00808       if (src.RelAddr)
00809          arg0 = deref(c, c->regs[PROGRAM_STATE_VAR][0], src.Index);
00810       else
00811 #endif
00812          arg0 = get_reg(c, src.File, src.Index);
00813 
00814       arg0 = brw_swizzle(arg0,
00815                          src_swz[0], src_swz[1],
00816                          src_swz[2], src_swz[3]);
00817 
00818       brw_MOV(p, brw_writemask(tmp, src_mask), arg0);
00819    }
00820 
00821    if (zeros_mask)
00822       brw_MOV(p, brw_writemask(tmp, zeros_mask), brw_imm_f(0));
00823 
00824    if (ones_mask)
00825       brw_MOV(p, brw_writemask(tmp, ones_mask), brw_imm_f(1));
00826 
00827    if (src.Negate)
00828       brw_MOV(p, brw_writemask(tmp, src.Negate), negate(tmp));
00829 
00830    if (need_tmp) {
00831       brw_MOV(p, dst, tmp);
00832       release_tmp(c, tmp);
00833    }
00834 }

static void emit_vertex_write ( struct brw_vs_compile c,
struct brw_prog_info info 
) [static]

Definition at line 840 of file brw_vs_emit.c.

References BRW_ALIGN_1, BRW_ALIGN_16, brw_AND(), brw_CMP(), BRW_CONDITIONAL_L, brw_DP4(), brw_imm_f(), brw_imm_ud(), BRW_MATH_FUNCTION_INV, BRW_MATH_PRECISION_FULL, brw_message_reg(), brw_MOV(), brw_MUL(), brw_null_reg(), brw_OR(), BRW_PREDICATE_NONE, BRW_REGISTER_TYPE_UD, brw_set_access_mode(), brw_set_conditionalmod(), brw_set_predicate_control(), brw_swizzle1(), BRW_URB_SWIZZLE_INTERLEAVE, brw_urb_WRITE(), brw_writemask(), brw_vs_prog_key::copy_edgeflag, brw_prog_info::edge_flag_idx, emit_math1(), brw_vs_compile::func, get_reg(), get_tmp(), brw_vs_compile::key, brw_vs_prog_key::know_w_is_one, brw_vs_compile::nr_outputs, brw_vs_prog_key::nr_userclip, offset(), brw_prog_info::pos_idx, brw_prog_info::psize_idx, brw_vs_compile::r0, brw_vs_compile::regs, release_tmp(), brw_prog_info::result_edge_idx, retype(), TGSI_FILE_INPUT, TGSI_FILE_OUTPUT, TGSI_WRITEMASK_W, TGSI_WRITEMASK_XYZ, brw_vs_compile::userplane, vec8(), and brw_prog_info::writes_psize.

00841 {
00842    struct brw_compile *p = &c->func;
00843    struct brw_reg m0 = brw_message_reg(0);
00844    struct brw_reg pos = c->regs[TGSI_FILE_OUTPUT][info->pos_idx];
00845    struct brw_reg ndc;
00846 
00847    if (c->key.copy_edgeflag) {
00848       brw_MOV(p,
00849               get_reg(c, TGSI_FILE_OUTPUT, info->result_edge_idx),
00850               get_reg(c, TGSI_FILE_INPUT, info->edge_flag_idx));
00851    }
00852 
00853 
00854    /* Build ndc coords?   TODO: Shortcircuit when w is known to be one.
00855     */
00856    if (!c->key.know_w_is_one) {
00857       ndc = get_tmp(c);
00858       emit_math1(c, BRW_MATH_FUNCTION_INV, ndc, brw_swizzle1(pos, 3), BRW_MATH_PRECISION_FULL);
00859       brw_MUL(p, brw_writemask(ndc, TGSI_WRITEMASK_XYZ), pos, ndc);
00860    }
00861    else {
00862       ndc = pos;
00863    }
00864 
00865    /* This includes the workaround for -ve rhw, so is no longer an
00866     * optional step:
00867     */
00868    if (info->writes_psize ||
00869        c->key.nr_userclip ||
00870        !c->key.know_w_is_one)
00871    {
00872       struct brw_reg header1 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
00873       unsigned i;
00874 
00875       brw_MOV(p, header1, brw_imm_ud(0));
00876 
00877       brw_set_access_mode(p, BRW_ALIGN_16);
00878 
00879       if (info->writes_psize) {
00880          struct brw_reg psiz = c->regs[TGSI_FILE_OUTPUT][info->psize_idx];
00881          brw_MUL(p, brw_writemask(header1, TGSI_WRITEMASK_W),
00882                  brw_swizzle1(psiz, 0), brw_imm_f(1<<11));
00883          brw_AND(p, brw_writemask(header1, TGSI_WRITEMASK_W), header1,
00884                  brw_imm_ud(0x7ff<<8));
00885       }
00886 
00887 
00888       for (i = 0; i < c->key.nr_userclip; i++) {
00889          brw_set_conditionalmod(p, BRW_CONDITIONAL_L);
00890          brw_DP4(p, brw_null_reg(), pos, c->userplane[i]);
00891          brw_OR(p, brw_writemask(header1, TGSI_WRITEMASK_W), header1, brw_imm_ud(1<<i));
00892          brw_set_predicate_control(p, BRW_PREDICATE_NONE);
00893       }
00894 
00895 
00896       /* i965 clipping workaround:
00897        * 1) Test for -ve rhw
00898        * 2) If set,
00899        *      set ndc = (0,0,0,0)
00900        *      set ucp[6] = 1
00901        *
00902        * Later, clipping will detect ucp[6] and ensure the primitive is
00903        * clipped against all fixed planes.
00904        */
00905       if (!c->key.know_w_is_one) {
00906          brw_CMP(p,
00907                  vec8(brw_null_reg()),
00908                  BRW_CONDITIONAL_L,
00909                  brw_swizzle1(ndc, 3),
00910                  brw_imm_f(0));
00911 
00912          brw_OR(p, brw_writemask(header1, TGSI_WRITEMASK_W), header1, brw_imm_ud(1<<6));
00913          brw_MOV(p, ndc, brw_imm_f(0));
00914          brw_set_predicate_control(p, BRW_PREDICATE_NONE);
00915       }
00916 
00917       brw_set_access_mode(p, BRW_ALIGN_1);      /* why? */
00918       brw_MOV(p, retype(brw_message_reg(1), BRW_REGISTER_TYPE_UD), header1);
00919       brw_set_access_mode(p, BRW_ALIGN_16);
00920 
00921       release_tmp(c, header1);
00922    }
00923    else {
00924       brw_MOV(p, retype(brw_message_reg(1), BRW_REGISTER_TYPE_UD), brw_imm_ud(0));
00925    }
00926 
00927 
00928    /* Emit the (interleaved) headers for the two vertices - an 8-reg
00929     * of zeros followed by two sets of NDC coordinates:
00930     */
00931    brw_set_access_mode(p, BRW_ALIGN_1);
00932    brw_MOV(p, offset(m0, 2), ndc);
00933    brw_MOV(p, offset(m0, 3), pos);
00934 
00935 
00936    brw_urb_WRITE(p,
00937                  brw_null_reg(), /* dest */
00938                  0,             /* starting mrf reg nr */
00939                  c->r0,         /* src */
00940                  0,             /* allocate */
00941                  1,             /* used */
00942                  c->nr_outputs + 3, /* msg len */
00943                  0,             /* response len */
00944                  1,             /* eot */
00945                  1,             /* writes complete */
00946                  0,             /* urb destination offset */
00947                  BRW_URB_SWIZZLE_INTERLEAVE);
00948 
00949 }

static void emit_xpd ( struct brw_compile p,
struct brw_reg  dst,
struct brw_reg  t,
struct brw_reg  u 
) [static]

Definition at line 565 of file brw_vs_emit.c.

References brw_MAC(), brw_MUL(), brw_null_reg(), brw_swizzle(), and negate().

00569 {
00570    brw_MUL(p, brw_null_reg(), brw_swizzle(t, 1,2,0,3),  brw_swizzle(u,2,0,1,3));
00571    brw_MAC(p, dst,     negate(brw_swizzle(t, 2,0,1,3)), brw_swizzle(u,1,2,0,3));
00572 }

static struct brw_reg get_arg ( struct brw_vs_compile c,
struct tgsi_src_register src 
) [static, read]

Definition at line 707 of file brw_vs_emit.c.

References brw_reg::bits, brw_null_reg(), BRW_SWIZZLE4, deref(), brw_reg::dw1, get_reg(), brw_reg::negate, and TGSI_FILE_NULL.

00709 {
00710    struct brw_reg reg;
00711 
00712    if (src->File == TGSI_FILE_NULL)
00713       return brw_null_reg();
00714 
00715 #if 0
00716    if (src->RelAddr)
00717       reg = deref(c, c->regs[PROGRAM_STATE_VAR][0], src->Index);
00718    else
00719 #endif
00720       reg = get_reg(c, src->File, src->Index);
00721 
00722    /* Convert 3-bit swizzle to 2-bit.
00723     */
00724    reg.dw1.bits.swizzle = BRW_SWIZZLE4(src->SwizzleX,
00725                                        src->SwizzleY,
00726                                        src->SwizzleZ,
00727                                        src->SwizzleW);
00728 
00729    /* Note this is ok for non-swizzle instructions:
00730     */
00731    reg.negate = src->Negate ? 1 : 0;
00732 
00733    return reg;
00734 }

static struct brw_reg get_dst ( struct brw_vs_compile c,
const struct tgsi_dst_register dst 
) [static, read]

Definition at line 737 of file brw_vs_emit.c.

References brw_reg::bits, brw_reg::dw1, and get_reg().

00739 {
00740    struct brw_reg reg = get_reg(c, dst->File, dst->Index);
00741 
00742    reg.dw1.bits.writemask = dst->WriteMask;
00743 
00744    return reg;
00745 }

static struct brw_reg get_reg ( struct brw_vs_compile c,
unsigned  file,
unsigned  index 
) [static, read]

Definition at line 622 of file brw_vs_emit.c.

References assert, brw_null_reg(), brw_reg::nr, TGSI_FILE_ADDRESS, TGSI_FILE_CONSTANT, TGSI_FILE_IMMEDIATE, TGSI_FILE_INPUT, TGSI_FILE_NULL, TGSI_FILE_OUTPUT, and TGSI_FILE_TEMPORARY.

00625 {
00626    switch (file) {
00627    case TGSI_FILE_TEMPORARY:
00628    case TGSI_FILE_INPUT:
00629    case TGSI_FILE_OUTPUT:
00630       assert(c->regs[file][index].nr != 0);
00631       return c->regs[file][index];
00632    case TGSI_FILE_CONSTANT:
00633       assert(c->regs[TGSI_FILE_CONSTANT][index + c->prog_data.num_imm].nr != 0);
00634       return c->regs[TGSI_FILE_CONSTANT][index + c->prog_data.num_imm];
00635    case TGSI_FILE_IMMEDIATE:
00636       assert(c->regs[TGSI_FILE_CONSTANT][index].nr != 0);
00637       return c->regs[TGSI_FILE_CONSTANT][index];
00638    case TGSI_FILE_ADDRESS:
00639       assert(index == 0);
00640       return c->regs[file][index];
00641 
00642    case TGSI_FILE_NULL:                 /* undef values */
00643       return brw_null_reg();
00644 
00645    default:
00646       assert(0);
00647       return brw_null_reg();
00648    }
00649 }

static struct brw_reg get_tmp ( struct brw_vs_compile c  )  [static, read]

Definition at line 180 of file brw_vs_emit.c.

References brw_vec8_grf().

00181 {
00182    struct brw_reg tmp = brw_vec8_grf(c->last_tmp, 0);
00183 
00184    if (++c->last_tmp > c->prog_data.total_grf)
00185       c->prog_data.total_grf = c->last_tmp;
00186 
00187    return tmp;
00188 }

static void post_vs_emit ( struct brw_vs_compile c,
struct brw_instruction end_inst 
) [static]

Definition at line 952 of file brw_vs_emit.c.

References brw_imm_d(), brw_set_src1(), tgsi_full_token::FullInstruction, tgsi_parse_context::FullToken, offset(), brw_vertex_program::program, TGSI_OPCODE_BRA, TGSI_OPCODE_CAL, TGSI_OPCODE_END, tgsi_parse_end_of_tokens(), tgsi_parse_free(), tgsi_parse_init(), tgsi_parse_token(), TGSI_TOKEN_TYPE_INSTRUCTION, tgsi_full_token::Token, pipe_shader_state::tokens, tgsi_token::Type, and brw_vs_compile::vp.

00953 {
00954    struct tgsi_parse_context parse;
00955    const struct tgsi_token *tokens = c->vp->program.tokens;
00956    tgsi_parse_init(&parse, tokens);
00957    while (!tgsi_parse_end_of_tokens(&parse)) {
00958       tgsi_parse_token(&parse);
00959       if (parse.FullToken.Token.Type == TGSI_TOKEN_TYPE_INSTRUCTION) {
00960 #if 0
00961          struct brw_instruction *brw_inst1, *brw_inst2;
00962          const struct tgsi_full_instruction *inst1, *inst2;
00963          int offset;
00964          inst1 = &parse.FullToken.FullInstruction;
00965          brw_inst1 = inst1->Data;
00966          switch (inst1->Opcode) {
00967          case TGSI_OPCODE_CAL:
00968          case TGSI_OPCODE_BRA:
00969             target_insn = inst1->BranchTarget;
00970             inst2 = &c->vp->program.Base.Instructions[target_insn];
00971             brw_inst2 = inst2->Data;
00972             offset = brw_inst2 - brw_inst1;
00973             brw_set_src1(brw_inst1, brw_imm_d(offset*16));
00974             break;
00975          case TGSI_OPCODE_END:
00976             offset = end_inst - brw_inst1;
00977             brw_set_src1(brw_inst1, brw_imm_d(offset*16));
00978             break;
00979          default:
00980             break;
00981          }
00982 #endif
00983       }
00984    }
00985    tgsi_parse_free(&parse);
00986 }

static void process_declaration ( const struct tgsi_full_declaration decl,
struct brw_prog_info info 
) [static]

Definition at line 988 of file brw_vs_emit.c.

References assert, tgsi_full_declaration::Declaration, tgsi_full_declaration::DeclarationRange, tgsi_declaration::File, tgsi_declaration_range::First, tgsi_declaration_range::Last, brw_prog_info::num_addrs, brw_prog_info::num_consts, brw_prog_info::num_temps, brw_prog_info::pos_idx, brw_prog_info::psize_idx, tgsi_full_declaration::Semantic, tgsi_declaration::Semantic, tgsi_declaration_semantic::SemanticName, TGSI_FILE_ADDRESS, TGSI_FILE_CONSTANT, TGSI_FILE_IMMEDIATE, TGSI_FILE_INPUT, TGSI_FILE_NULL, TGSI_FILE_OUTPUT, TGSI_FILE_SAMPLER, TGSI_FILE_TEMPORARY, TGSI_SEMANTIC_BCOLOR, TGSI_SEMANTIC_COLOR, TGSI_SEMANTIC_FOG, TGSI_SEMANTIC_GENERIC, TGSI_SEMANTIC_POSITION, TGSI_SEMANTIC_PSIZE, TRUE, and brw_prog_info::writes_psize.

00990 {
00991    int first = decl->DeclarationRange.First;
00992    int last = decl->DeclarationRange.Last;
00993    
00994    switch(decl->Declaration.File) {
00995    case TGSI_FILE_CONSTANT: 
00996       info->num_consts += last - first + 1;
00997       break;
00998    case TGSI_FILE_INPUT: {
00999    }
01000       break;
01001    case TGSI_FILE_OUTPUT: {
01002       assert(last == first);    /* for now */
01003       if (decl->Declaration.Semantic) {
01004          switch (decl->Semantic.SemanticName) {
01005          case TGSI_SEMANTIC_POSITION: {
01006             info->pos_idx = first;
01007          }
01008             break;
01009          case TGSI_SEMANTIC_COLOR:
01010             break;
01011          case TGSI_SEMANTIC_BCOLOR:
01012             break;
01013          case TGSI_SEMANTIC_FOG:
01014             break;
01015          case TGSI_SEMANTIC_PSIZE: {
01016             info->writes_psize = TRUE;
01017             info->psize_idx = first;
01018          }
01019             break;
01020          case TGSI_SEMANTIC_GENERIC:
01021             break;
01022          }
01023       }
01024    }
01025       break;
01026    case TGSI_FILE_TEMPORARY: {
01027       info->num_temps += (last - first) + 1;
01028    }
01029       break;
01030    case TGSI_FILE_SAMPLER: {
01031    }
01032       break;
01033    case TGSI_FILE_ADDRESS: {
01034       info->num_addrs += (last - first) + 1;
01035    }
01036       break;
01037    case TGSI_FILE_IMMEDIATE: {
01038    }
01039       break;
01040    case TGSI_FILE_NULL: {
01041    }
01042       break;
01043    }
01044 }

static void process_instruction ( struct brw_vs_compile c,
struct tgsi_full_instruction inst,
struct brw_prog_info info 
) [static]

Definition at line 1046 of file brw_vs_emit.c.

References assert, brw_abs(), brw_acc_reg(), brw_ADD(), BRW_ALIGN_1, BRW_ALIGN_16, brw_DP3(), brw_DP4(), brw_DPH(), brw_ELSE(), brw_ENDIF(), BRW_EXECUTE_8, brw_FRC(), brw_IF(), brw_imm_d(), brw_ip_reg(), brw_MAC(), BRW_MATH_FUNCTION_EXP, BRW_MATH_FUNCTION_INV, BRW_MATH_FUNCTION_LOG, BRW_MATH_FUNCTION_POW, BRW_MATH_FUNCTION_RSQ, BRW_MATH_PRECISION_FULL, brw_MOV(), brw_MUL(), BRW_PREDICATE_NORMAL, brw_RNDD(), brw_set_access_mode(), brw_set_predicate_control(), brw_set_predicate_control_flag_value(), debug_printf(), deref_1uw(), tgsi_full_dst_register::DstRegister, emit_arl(), emit_dst_noalias(), emit_exp_noalias(), emit_lit_noalias(), emit_log_noalias(), emit_math1(), emit_math2(), emit_max(), emit_min(), emit_seq(), emit_sge(), emit_sgt(), emit_sle(), emit_slt(), emit_sne(), emit_swz(), emit_xpd(), tgsi_dst_register::File, tgsi_src_register::File, tgsi_full_instruction::FullDstRegisters, tgsi_full_instruction::FullSrcRegisters, brw_vs_compile::func, get_addr_reg(), get_arg(), get_dst(), tgsi_dst_register::Index, tgsi_src_register::Index, tgsi_full_instruction::Instruction, MAX_IFSN, negate(), brw_compile::nr_insn, tgsi_instruction::Opcode, brw_vs_compile::output_regs, brw_prog_info::pos_idx, brw_vs_compile::reg, release_tmps(), tgsi_full_src_register::SrcRegister, brw_compile::store, TGSI_FILE_OUTPUT, TGSI_OPCODE_ABS, TGSI_OPCODE_ADD, TGSI_OPCODE_ARL, TGSI_OPCODE_BGNSUB, TGSI_OPCODE_BRA, TGSI_OPCODE_CAL, TGSI_OPCODE_DP3, TGSI_OPCODE_DP4, TGSI_OPCODE_DPH, TGSI_OPCODE_DST, TGSI_OPCODE_ELSE, TGSI_OPCODE_END, TGSI_OPCODE_ENDIF, TGSI_OPCODE_ENDSUB, TGSI_OPCODE_EX2, TGSI_OPCODE_EXP, TGSI_OPCODE_FLR, TGSI_OPCODE_FRC, TGSI_OPCODE_IF, TGSI_OPCODE_LG2, TGSI_OPCODE_LIT, TGSI_OPCODE_LOG, TGSI_OPCODE_MAD, TGSI_OPCODE_MAX, TGSI_OPCODE_MIN, TGSI_OPCODE_MOV, TGSI_OPCODE_MUL, TGSI_OPCODE_POW, TGSI_OPCODE_RCP, TGSI_OPCODE_RET, TGSI_OPCODE_RSQ, TGSI_OPCODE_SEQ, TGSI_OPCODE_SGE, TGSI_OPCODE_SGT, TGSI_OPCODE_SLE, TGSI_OPCODE_SLT, TGSI_OPCODE_SNE, TGSI_OPCODE_SUB, TGSI_OPCODE_SWZ, TGSI_OPCODE_XPD, unalias1(), unalias2(), and brw_vs_compile::used_in_src.

01049 {
01050    struct brw_reg args[3], dst;
01051    struct brw_compile *p = &c->func;
01052    /*struct brw_indirect stack_index = brw_indirect(0, 0);*/
01053    unsigned i;
01054    unsigned index;
01055    unsigned file;
01056    /*FIXME: might not be the only one*/
01057    const struct tgsi_dst_register *dst_reg = &inst->FullDstRegisters[0].DstRegister;
01058    /*
01059    struct brw_instruction *if_inst[MAX_IFSN];
01060    unsigned insn, if_insn = 0;
01061    */
01062 
01063    for (i = 0; i < 3; i++) {
01064       struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i];
01065       index = src->SrcRegister.Index;
01066       file = src->SrcRegister.File;
01067       if (file == TGSI_FILE_OUTPUT && c->output_regs[index].used_in_src)
01068          args[i] = c->output_regs[index].reg;
01069       else
01070          args[i] = get_arg(c, &src->SrcRegister);
01071    }
01072 
01073    /* Get dest regs.  Note that it is possible for a reg to be both
01074     * dst and arg, given the static allocation of registers.  So
01075     * care needs to be taken emitting multi-operation instructions.
01076     */
01077    index = dst_reg->Index;
01078    file = dst_reg->File;
01079    if (file == TGSI_FILE_OUTPUT && c->output_regs[index].used_in_src)
01080       dst = c->output_regs[index].reg;
01081    else
01082       dst = get_dst(c, dst_reg);
01083 
01084    switch (inst->Instruction.Opcode) {
01085    case TGSI_OPCODE_ABS:
01086       brw_MOV(p, dst, brw_abs(args[0]));
01087       break;
01088    case TGSI_OPCODE_ADD:
01089       brw_ADD(p, dst, args[0], args[1]);
01090       break;
01091    case TGSI_OPCODE_DP3:
01092       brw_DP3(p, dst, args[0], args[1]);
01093       break;
01094    case TGSI_OPCODE_DP4:
01095       brw_DP4(p, dst, args[0], args[1]);
01096       break;
01097    case TGSI_OPCODE_DPH:
01098       brw_DPH(p, dst, args[0], args[1]);
01099       break;
01100    case TGSI_OPCODE_DST:
01101       unalias2(c, dst, args[0], args[1], emit_dst_noalias);
01102       break;
01103    case TGSI_OPCODE_EXP:
01104       unalias1(c, dst, args[0], emit_exp_noalias);
01105       break;
01106    case TGSI_OPCODE_EX2:
01107       emit_math1(c, BRW_MATH_FUNCTION_EXP, dst, args[0], BRW_MATH_PRECISION_FULL);
01108       break;
01109    case TGSI_OPCODE_ARL:
01110       emit_arl(c, dst, args[0]);
01111       break;
01112    case TGSI_OPCODE_FLR:
01113       brw_RNDD(p, dst, args[0]);
01114       break;
01115    case TGSI_OPCODE_FRC:
01116       brw_FRC(p, dst, args[0]);
01117       break;
01118    case TGSI_OPCODE_LOG:
01119       unalias1(c, dst, args[0], emit_log_noalias);
01120       break;
01121    case TGSI_OPCODE_LG2:
01122       emit_math1(c, BRW_MATH_FUNCTION_LOG, dst, args[0], BRW_MATH_PRECISION_FULL);
01123       break;
01124    case TGSI_OPCODE_LIT:
01125       unalias1(c, dst, args[0], emit_lit_noalias);
01126       break;
01127    case TGSI_OPCODE_MAD:
01128       brw_MOV(p, brw_acc_reg(), args[2]);
01129       brw_MAC(p, dst, args[0], args[1]);
01130       break;
01131    case TGSI_OPCODE_MAX:
01132       emit_max(p, dst, args[0], args[1]);
01133       break;
01134    case TGSI_OPCODE_MIN:
01135       emit_min(p, dst, args[0], args[1]);
01136       break;
01137    case TGSI_OPCODE_MOV:
01138    case TGSI_OPCODE_SWZ:
01139 #if 0
01140       /* The args[0] value can't be used here as it won't have
01141        * correctly encoded the full swizzle:
01142        */
01143       emit_swz(c, dst, inst->SrcReg[0] );
01144 #endif
01145       brw_MOV(p, dst, args[0]);
01146       break;
01147    case TGSI_OPCODE_MUL:
01148       brw_MUL(p, dst, args[0], args[1]);
01149       break;
01150    case TGSI_OPCODE_POW:
01151       emit_math2(c, BRW_MATH_FUNCTION_POW, dst, args[0], args[1], BRW_MATH_PRECISION_FULL);
01152       break;
01153    case TGSI_OPCODE_RCP:
01154       emit_math1(c, BRW_MATH_FUNCTION_INV, dst, args[0], BRW_MATH_PRECISION_FULL);
01155       break;
01156    case TGSI_OPCODE_RSQ:
01157       emit_math1(c, BRW_MATH_FUNCTION_RSQ, dst, args[0], BRW_MATH_PRECISION_FULL);
01158       break;
01159 
01160    case TGSI_OPCODE_SEQ:
01161       emit_seq(p, dst, args[0], args[1]);
01162       break;
01163    case TGSI_OPCODE_SNE:
01164       emit_sne(p, dst, args[0], args[1]);
01165       break;
01166    case TGSI_OPCODE_SGE:
01167       emit_sge(p, dst, args[0], args[1]);
01168       break;
01169    case TGSI_OPCODE_SGT:
01170       emit_sgt(p, dst, args[0], args[1]);
01171       break;
01172    case TGSI_OPCODE_SLT:
01173       emit_slt(p, dst, args[0], args[1]);
01174       break;
01175    case TGSI_OPCODE_SLE:
01176       emit_sle(p, dst, args[0], args[1]);
01177       break;
01178    case TGSI_OPCODE_SUB:
01179       brw_ADD(p, dst, args[0], negate(args[1]));
01180       break;
01181    case TGSI_OPCODE_XPD:
01182       emit_xpd(p, dst, args[0], args[1]);
01183       break;
01184 #if 0
01185    case TGSI_OPCODE_IF:
01186       assert(if_insn < MAX_IFSN);
01187       if_inst[if_insn++] = brw_IF(p, BRW_EXECUTE_8);
01188       break;
01189    case TGSI_OPCODE_ELSE:
01190       if_inst[if_insn-1] = brw_ELSE(p, if_inst[if_insn-1]);
01191       break;
01192    case TGSI_OPCODE_ENDIF:
01193       assert(if_insn > 0);
01194       brw_ENDIF(p, if_inst[--if_insn]);
01195       break;
01196    case TGSI_OPCODE_BRA:
01197       brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
01198       brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
01199       brw_set_predicate_control_flag_value(p, 0xff);
01200       break;
01201    case TGSI_OPCODE_CAL:
01202       brw_set_access_mode(p, BRW_ALIGN_1);
01203       brw_ADD(p, deref_1uw(stack_index, 0), brw_ip_reg(), brw_imm_d(3*16));
01204       brw_set_access_mode(p, BRW_ALIGN_16);
01205       brw_ADD(p, get_addr_reg(stack_index),
01206               get_addr_reg(stack_index), brw_imm_d(4));
01207       inst->Data = &p->store[p->nr_insn];
01208       brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
01209       break;
01210 #endif
01211    case TGSI_OPCODE_RET:
01212 #if 0
01213       brw_ADD(p, get_addr_reg(stack_index),
01214               get_addr_reg(stack_index), brw_imm_d(-4));
01215       brw_set_access_mode(p, BRW_ALIGN_1);
01216       brw_MOV(p, brw_ip_reg(), deref_1uw(stack_index, 0));
01217       brw_set_access_mode(p, BRW_ALIGN_16);
01218 #else
01219       /*brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));*/
01220 #endif
01221       break;
01222    case TGSI_OPCODE_END:
01223       brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
01224       break;
01225    case TGSI_OPCODE_BGNSUB:
01226    case TGSI_OPCODE_ENDSUB:
01227       break;
01228    default:
01229       debug_printf("Unsupport opcode %d in vertex shader\n", inst->Instruction.Opcode);
01230       break;
01231    }
01232 
01233    if (dst_reg->File == TGSI_FILE_OUTPUT
01234        && dst_reg->Index != info->pos_idx
01235        && c->output_regs[dst_reg->Index].used_in_src)
01236       brw_MOV(p, get_dst(c, dst_reg), dst);
01237 
01238    release_tmps(c);
01239 }

static void release_tmp ( struct brw_vs_compile c,
struct brw_reg  tmp 
) [static]

Definition at line 190 of file brw_vs_emit.c.

References brw_vs_compile::last_tmp, and brw_reg::nr.

00191 {
00192    if (tmp.nr == c->last_tmp-1)
00193       c->last_tmp--;
00194 }

static void release_tmps ( struct brw_vs_compile c  )  [static]

Definition at line 196 of file brw_vs_emit.c.

References brw_vs_compile::first_tmp, and brw_vs_compile::last_tmp.

00197 {
00198    c->last_tmp = c->first_tmp;
00199 }

static void unalias1 ( struct brw_vs_compile c,
struct brw_reg  dst,
struct brw_reg  arg0,
void(*)(struct brw_vs_compile *, struct brw_reg, struct brw_reg func 
) [static]

Definition at line 202 of file brw_vs_emit.c.

References brw_reg::bits, brw_MOV(), brw_writemask(), brw_reg::dw1, brw_reg::file, brw_vs_compile::func, get_tmp(), and brw_reg::nr.

00208 {
00209    if (dst.file == arg0.file && dst.nr == arg0.nr) {
00210       struct brw_compile *p = &c->func;
00211       struct brw_reg tmp = brw_writemask(get_tmp(c), dst.dw1.bits.writemask);
00212       func(c, tmp, arg0);
00213       brw_MOV(p, dst, tmp);
00214    }
00215    else {
00216       func(c, dst, arg0);
00217    }
00218 }

static void unalias2 ( struct brw_vs_compile c,
struct brw_reg  dst,
struct brw_reg  arg0,
struct brw_reg  arg1,
void(*)(struct brw_vs_compile *, struct brw_reg, struct brw_reg, struct brw_reg func 
) [static]

Definition at line 220 of file brw_vs_emit.c.

References brw_reg::bits, brw_MOV(), brw_writemask(), brw_reg::dw1, brw_reg::file, brw_vs_compile::func, get_tmp(), and brw_reg::nr.

00228 {
00229    if ((dst.file == arg0.file && dst.nr == arg0.nr) ||
00230        (dst.file == arg1.file && dst.nr == arg1.nr)) {
00231       struct brw_compile *p = &c->func;
00232       struct brw_reg tmp = brw_writemask(get_tmp(c), dst.dw1.bits.writemask);
00233       func(c, tmp, arg0, arg1);
00234       brw_MOV(p, dst, tmp);
00235    }
00236    else {
00237       func(c, dst, arg0, arg1);
00238    }
00239 }


Generated on Tue Sep 29 06:25:39 2009 for Gallium3D by  doxygen 1.5.4