diff options
author | Keith Whitwell <keithw@vmware.com> | 2009-10-28 21:24:03 +0000 |
---|---|---|
committer | Keith Whitwell <keithw@vmware.com> | 2009-10-28 21:24:03 +0000 |
commit | 81b8589f064204d9ddcd7d1f9d43d2dcf5676235 (patch) | |
tree | c284554c3e4b201c4e5de6a20b889f0e222b3ab3 /src/gallium/drivers/i965/brw_vs_emit.c | |
parent | 7ba2fe40fa092551f1c493d754c80ca93564d32b (diff) |
i965g: still working on compilation
Diffstat (limited to 'src/gallium/drivers/i965/brw_vs_emit.c')
-rw-r--r-- | src/gallium/drivers/i965/brw_vs_emit.c | 199 |
1 files changed, 145 insertions, 54 deletions
diff --git a/src/gallium/drivers/i965/brw_vs_emit.c b/src/gallium/drivers/i965/brw_vs_emit.c index 5366ab8514..6809bccdec 100644 --- a/src/gallium/drivers/i965/brw_vs_emit.c +++ b/src/gallium/drivers/i965/brw_vs_emit.c @@ -34,8 +34,7 @@ #include "util/u_memory.h" #include "util/u_math.h" -#include "tgsi/tgsi_ureg.h" -#include "tgsi/tgsi_ureg_parse.h" +#include "tgsi/tgsi_parse.h" #include "tgsi/tgsi_dump.h" #include "tgsi/tgsi_info.h" @@ -67,6 +66,7 @@ static void release_tmps( struct brw_vs_compile *c ) } + /** * Preallocate GRF register before code emit. * Do things as simply as possible. Allocate and populate all regs @@ -83,10 +83,17 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c ) * XXX this heuristic/check may need some fine tuning... */ if (c->vp->info.file_max[TGSI_FILE_CONSTANT] + + c->vp->info.file_max[TGSI_FILE_IMMEDIATE] + c->vp->info.file_max[TGSI_FILE_TEMPORARY] + 21 > BRW_MAX_GRF) c->vp->use_const_buffer = GL_TRUE; - else + else { + /* XXX: immediates can go elsewhere if necessary: + */ + assert(c->vp->info.file_max[TGSI_FILE_IMMEDIATE] + + c->vp->info.file_max[TGSI_FILE_TEMPORARY] + 21 > BRW_MAX_GRF); + c->vp->use_const_buffer = GL_FALSE; + } /*printf("use_const_buffer = %d\n", c->vp->use_const_buffer);*/ @@ -139,6 +146,29 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c ) if (c->nr_inputs == 0) reg++; + /* Allocate a GRF and load immediate values by hand with 4 MOVs!!! + * + * XXX: Try to encode float immediates as brw immediates + * XXX: Put immediates into the CURBE. + * XXX: Make sure ureg sets minimal immediate size and respect it + * here. + */ + for (i = 0; i < c->nr_immediates; i++) { + struct brw_reg r; + int j; + + r = brw_vec8_grf(reg, 0); + + for (j = 0; j < 4; j++) { + brw_MOV(&c->func, + brw_writemask(r, (1<<j)), + brw_imm_f(c->immediate[i][j])); + } + + reg++; + } + + /* Allocate outputs. The non-position outputs go straight into message regs. */ c->nr_outputs = 0; @@ -754,21 +784,20 @@ static void emit_nrm( struct brw_vs_compile *c, static struct brw_reg get_constant(struct brw_vs_compile *c, - const struct ureg_instruction *inst, - GLuint argIndex) + GLuint argIndex, + GLuint index, + GLboolean relAddr) { - const struct ureg_src src = inst->src[argIndex]; struct brw_compile *p = &c->func; struct brw_reg const_reg; struct brw_reg const2_reg; - const GLboolean relAddr = src.Indirect; assert(argIndex < 3); - if (c->current_const[argIndex].index != src.Index || relAddr) { + if (c->current_const[argIndex].index != index || relAddr) { struct brw_reg addrReg = c->regs[TGSI_FILE_ADDRESS][0]; - c->current_const[argIndex].index = src.Index; + c->current_const[argIndex].index = index; #if 0 printf(" fetch const[%d] for arg %d into reg %d\n", @@ -780,7 +809,7 @@ get_constant(struct brw_vs_compile *c, 0, /* oword */ relAddr, /* relative indexing? */ addrReg, /* address register */ - 16 * src.Index, /* byte offset */ + 16 * index, /* byte offset */ SURF_INDEX_VERT_CONST_BUFFER /* binding table index */ ); @@ -797,7 +826,7 @@ get_constant(struct brw_vs_compile *c, 1, /* oword */ relAddr, /* relative indexing? */ addrReg, /* address register */ - 16 * src.Index, /* byte offset */ + 16 * index, /* byte offset */ SURF_INDEX_VERT_CONST_BUFFER ); } @@ -894,12 +923,11 @@ static struct brw_reg deref( struct brw_vs_compile *c, */ static struct brw_reg get_src_reg( struct brw_vs_compile *c, - const struct ureg_instruction *inst, - GLuint argIndex ) + GLuint argIndex, + GLuint file, + GLint index, + GLboolean relAddr ) { - const GLuint file = inst->src[argIndex].File; - const GLint index = inst->src[argIndex].Index; - const GLboolean relAddr = inst->src[argIndex].Indirect; switch (file) { case TGSI_FILE_TEMPORARY: @@ -913,9 +941,12 @@ get_src_reg( struct brw_vs_compile *c, return c->regs[file][index]; } + case TGSI_FILE_IMMEDIATE: + return c->regs[file][index]; + case TGSI_FILE_CONSTANT: if (c->vp->use_const_buffer) { - return get_constant(c, inst, argIndex); + return get_constant(c, argIndex, index, relAddr); } else if (relAddr) { return deref(c, c->regs[TGSI_FILE_CONSTANT][0], index); @@ -962,27 +993,32 @@ static void emit_arl( struct brw_vs_compile *c, * Return the brw reg for the given instruction's src argument. */ static struct brw_reg get_arg( struct brw_vs_compile *c, - const struct ureg_instruction *inst, + const struct tgsi_full_src_register *src, GLuint argIndex ) { - const struct ureg_src src = inst->src[argIndex]; struct brw_reg reg; - if (src.File == TGSI_FILE_NULL) + if (src->SrcRegister.File == TGSI_FILE_NULL) return brw_null_reg(); - reg = get_src_reg(c, inst, argIndex); + reg = get_src_reg(c, argIndex, + src->SrcRegister.File, + src->SrcRegister.Index, + src->SrcRegister.Indirect); /* Convert 3-bit swizzle to 2-bit. */ - reg.dw1.bits.swizzle = BRW_SWIZZLE4(src.SwizzleX, - src.SwizzleY, - src.SwizzleZ, - src.SwizzleW); + reg.dw1.bits.swizzle = BRW_SWIZZLE4(src->SrcRegister.SwizzleX, + src->SrcRegister.SwizzleY, + src->SrcRegister.SwizzleZ, + src->SrcRegister.SwizzleW); /* Note this is ok for non-swizzle instructions: */ - reg.negate = src.Negate ? 1 : 0; + reg.negate = src->SrcRegister.Negate ? 1 : 0; + + /* XXX: abs, absneg + */ return reg; } @@ -992,19 +1028,21 @@ static struct brw_reg get_arg( struct brw_vs_compile *c, * Get brw register for the given program dest register. */ static struct brw_reg get_dst( struct brw_vs_compile *c, - struct ureg_dst dst ) + unsigned file, + unsigned index, + unsigned writemask ) { struct brw_reg reg; - switch (dst.File) { + switch (file) { case TGSI_FILE_TEMPORARY: case TGSI_FILE_OUTPUT: - assert(c->regs[dst.File][dst.Index].nr != 0); - reg = c->regs[dst.File][dst.Index]; + assert(c->regs[file][index].nr != 0); + reg = c->regs[file][index]; break; case TGSI_FILE_ADDRESS: - assert(dst.Index == 0); - reg = c->regs[dst.File][dst.Index]; + assert(index == 0); + reg = c->regs[file][index]; break; case TGSI_FILE_NULL: /* we may hit this for OPCODE_END, OPCODE_KIL, etc */ @@ -1015,7 +1053,7 @@ static struct brw_reg get_dst( struct brw_vs_compile *c, reg = brw_null_reg(); } - reg.dw1.bits.writemask = dst.WriteMask; + reg.dw1.bits.writemask = writemask; return reg; } @@ -1199,7 +1237,7 @@ post_vs_emit( struct brw_vs_compile *c, } static uint32_t -get_predicate(const struct ureg_instruction *inst) +get_predicate(const struct tgsi_full_instruction *inst) { /* XXX: disabling for now */ @@ -1242,8 +1280,10 @@ get_predicate(const struct ureg_instruction *inst) } static void emit_insn(struct brw_vs_compile *c, - const struct ureg_instruction *inst) + const struct tgsi_full_instruction *inst) { + unsigned opcode = inst->Instruction.Opcode; + unsigned label = inst->InstructionExtLabel.Label; struct brw_compile *p = &c->func; struct brw_reg args[3], dst; GLuint i; @@ -1256,20 +1296,25 @@ static void emit_insn(struct brw_vs_compile *c, /* Get argument regs. */ for (i = 0; i < 3; i++) { - args[i] = get_arg(c, inst, i); + args[i] = get_arg(c, &inst->FullSrcRegisters[i], i); } /* Get dest regs. Note that it is possible for a reg to be both * dst and arg, given the static allocation of registers. So * care needs to be taken emitting multi-operation instructions. */ - dst = get_dst(c, inst->dst); + dst = get_dst(c, + inst->FullDstRegisters[0].DstRegister.File, + inst->FullDstRegisters[0].DstRegister.Index, + inst->FullDstRegisters[0].DstRegister.WriteMask); - if (inst->dst.Saturate) { + /* XXX: saturate + */ + if (inst->Instruction.Saturate != TGSI_SAT_NONE) { debug_printf("Unsupported saturate in vertex shader"); } - switch (inst->opcode) { + switch (opcode) { case TGSI_OPCODE_ABS: brw_MOV(p, dst, brw_abs(args[0])); break; @@ -1443,7 +1488,7 @@ static void emit_insn(struct brw_vs_compile *c, brw_set_access_mode(p, BRW_ALIGN_16); brw_ADD(p, get_addr_reg(c->stack_index), get_addr_reg(c->stack_index), brw_imm_d(4)); - brw_save_call(p, inst->label, p->nr_insn); + brw_save_call(p, label, p->nr_insn); brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16)); break; case TGSI_OPCODE_RET: @@ -1468,8 +1513,8 @@ static void emit_insn(struct brw_vs_compile *c, break; default: debug_printf("Unsupported opcode %i (%s) in vertex shader", - inst->opcode, - tgsi_get_opcode_name(inst->opcode)); + opcode, + tgsi_get_opcode_name(opcode)); } /* Set the predication update on the last instruction of the native @@ -1498,11 +1543,12 @@ static void emit_insn(struct brw_vs_compile *c, void brw_vs_emit(struct brw_vs_compile *c) { struct brw_compile *p = &c->func; + const struct tgsi_token *tokens = c->vp->tokens; struct brw_instruction *end_inst, *last_inst; - struct ureg_parse_context parse; - struct ureg_declaration *decl; - struct ureg_declaration *imm; - struct ureg_declaration *insn; + struct tgsi_parse_context parse; + struct tgsi_full_instruction *inst; + boolean done = FALSE; + int i; if (BRW_DEBUG & DEBUG_VS) tgsi_dump(c->vp->tokens, 0); @@ -1512,21 +1558,66 @@ void brw_vs_emit(struct brw_vs_compile *c) brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_set_access_mode(p, BRW_ALIGN_16); + /* Inputs */ + tgsi_parse_init( &parse, tokens ); + while( !tgsi_parse_end_of_tokens( &parse ) ) { + tgsi_parse_token( &parse ); + + switch( parse.FullToken.Token.Type ) { + case TGSI_TOKEN_TYPE_DECLARATION: + /* Nothing to do -- using info from tgsi_scan(). + */ + break; + + case TGSI_TOKEN_TYPE_IMMEDIATE: { + static const float id[4] = {0,0,0,1}; + const float *imm = &parse.FullToken.FullImmediate.u[i].Float; + unsigned size = parse.FullToken.FullImmediate.Immediate.NrTokens - 1; + + for (i = 0; i < size; i++) + c->immediate[c->nr_immediates][i] = imm[i]; + + for ( ; i < 4; i++) + c->immediate[c->nr_immediates][i] = id[i]; + + c->nr_immediates++; + break; + } + + case TGSI_TOKEN_TYPE_INSTRUCTION: + done = 1; + break; + } + } + /* Static register allocation */ brw_vs_alloc_regs(c); brw_MOV(p, get_addr_reg(c->stack_index), brw_address(c->stack)); - while (ureg_next_decl(&parse, &decl)) { - } - - while (ureg_next_immediate(&parse, &imm)) { - } - - while (ureg_next_instruction(&parse, &insn)) { + /* Instructions + */ + tgsi_parse_init( &parse, tokens ); + while( !tgsi_parse_end_of_tokens( &parse ) ) { + tgsi_parse_token( &parse ); + + switch( parse.FullToken.Token.Type ) { + case TGSI_TOKEN_TYPE_DECLARATION: + case TGSI_TOKEN_TYPE_IMMEDIATE: + break; + + case TGSI_TOKEN_TYPE_INSTRUCTION: + inst = &parse.FullToken.FullInstruction; + emit_insn( c, inst ); + break; + + default: + assert( 0 ); + } } + tgsi_parse_free( &parse ); - end_inst = &p->store[end_offset]; + end_inst = &p->store[c->end_offset]; last_inst = &p->store[p->nr_insn]; /* The END instruction will be patched to jump to this code */ |