summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/i965/brw_vs_emit.c
diff options
context:
space:
mode:
authorZou Nan hai <nanhai.zou@intel.com>2007-04-12 09:43:00 +0800
committerZou Nan hai <nanhai.zou@intel.com>2007-04-12 09:43:00 +0800
commit35707dbe57873adb5a8088cd47c13bd216e143e4 (patch)
treebfa296dcb0818f474d69ebc66afc2546e175a0cd /src/mesa/drivers/dri/i965/brw_vs_emit.c
parentbce7043ebcbb75cec727553341af4c66b03732ef (diff)
Initial 965 GLSL support
Diffstat (limited to 'src/mesa/drivers/dri/i965/brw_vs_emit.c')
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs_emit.c184
1 files changed, 138 insertions, 46 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c
index 6eb11b19ad..613ee03b2a 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c
@@ -134,6 +134,17 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
WRITEMASK_X);
reg++;
}
+
+ c->ret = brw_reg(BRW_GENERAL_REGISTER_FILE,
+ reg,
+ 0,
+ BRW_REGISTER_TYPE_D,
+ BRW_VERTICAL_STRIDE_8,
+ BRW_WIDTH_8,
+ BRW_HORIZONTAL_STRIDE_1,
+ BRW_SWIZZLE_XXXX,
+ WRITEMASK_X);
+ reg++;
/* Some opcodes need an internal temporary:
@@ -213,57 +224,68 @@ static void unalias2( struct brw_vs_compile *c,
}
}
+static void emit_sop( struct brw_compile *p,
+ struct brw_reg dst,
+ struct brw_reg arg0,
+ struct brw_reg arg1,
+ GLuint cond)
+{
+ brw_push_insn_state(p);
+ brw_CMP(p, brw_null_reg(), cond, arg0, arg1);
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+ brw_MOV(p, dst, brw_imm_f(1.0f));
+ brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
+ brw_MOV(p, dst, brw_imm_f(0.0f));
+ brw_pop_insn_state(p);
+}
+static void emit_seq( struct brw_compile *p,
+ struct brw_reg dst,
+ struct brw_reg arg0,
+ struct brw_reg arg1 )
+{
+ emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_EQ);
+}
-
+static void emit_sne( struct brw_compile *p,
+ struct brw_reg dst,
+ struct brw_reg arg0,
+ struct brw_reg arg1 )
+{
+ emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_NEQ);
+}
static void emit_slt( struct brw_compile *p,
struct brw_reg dst,
struct brw_reg arg0,
struct brw_reg arg1 )
{
- /* Could be done with an if/else/endif, but this method uses half
- * the instructions. Note that we are careful to reference the
- * arguments before writing the dest. That means we emit the
- * instructions in an odd order and have to play with the flag
- * values.
- */
- brw_push_insn_state(p);
- brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_GE, arg0, arg1);
-
- /* Write all values to 1:
- */
- brw_set_predicate_control(p, BRW_PREDICATE_NONE);
- brw_MOV(p, dst, brw_imm_f(1.0));
+ emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_L);
+}
- /* Where the test succeeded, overwite with zero:
- */
- brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
- brw_MOV(p, dst, brw_imm_f(0.0));
- brw_pop_insn_state(p);
+static void emit_sle( struct brw_compile *p,
+ struct brw_reg dst,
+ struct brw_reg arg0,
+ struct brw_reg arg1 )
+{
+ emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_LE);
}
+static void emit_sgt( struct brw_compile *p,
+ struct brw_reg dst,
+ struct brw_reg arg0,
+ struct brw_reg arg1 )
+{
+ emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_G);
+}
static void emit_sge( struct brw_compile *p,
struct brw_reg dst,
struct brw_reg arg0,
struct brw_reg arg1 )
{
- brw_push_insn_state(p);
- brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_GE, arg0, arg1);
-
- /* Write all values to zero:
- */
- brw_set_predicate_control(p, BRW_PREDICATE_NONE);
- brw_MOV(p, dst, brw_imm_f(0));
-
- /* Where the test succeeded, overwite with 1:
- */
- brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
- brw_MOV(p, dst, brw_imm_f(1.0));
- brw_pop_insn_state(p);
+ emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_GE);
}
-
static void emit_max( struct brw_compile *p,
struct brw_reg dst,
struct brw_reg arg0,
@@ -592,9 +614,13 @@ static struct brw_reg get_reg( struct brw_vs_compile *c,
case PROGRAM_TEMPORARY:
case PROGRAM_INPUT:
case PROGRAM_OUTPUT:
- case PROGRAM_STATE_VAR:
assert(c->regs[file][index].nr != 0);
return c->regs[file][index];
+ case PROGRAM_STATE_VAR:
+ case PROGRAM_CONSTANT:
+ case PROGRAM_UNIFORM:
+ assert(c->regs[PROGRAM_STATE_VAR][index].nr != 0);
+ return c->regs[PROGRAM_STATE_VAR][index];
case PROGRAM_ADDRESS:
assert(index == 0);
return c->regs[file][index];
@@ -891,17 +917,46 @@ static void emit_vertex_write( struct brw_vs_compile *c)
}
-
-
+static void
+post_vs_emit( struct brw_vs_compile *c, struct brw_instruction *end_inst )
+{
+ GLuint nr_insns = c->vp->program.Base.NumInstructions;
+ GLuint insn, target_insn;
+ struct prog_instruction *inst1, *inst2;
+ struct brw_instruction *brw_inst1, *brw_inst2;
+ int offset;
+ for (insn = 0; insn < nr_insns; insn++) {
+ inst1 = &c->vp->program.Base.Instructions[insn];
+ brw_inst1 = inst1->Data;
+ switch (inst1->Opcode) {
+ case OPCODE_CAL:
+ case OPCODE_BRA:
+ target_insn = inst1->BranchTarget;
+ inst2 = &c->vp->program.Base.Instructions[target_insn];
+ brw_inst2 = inst2->Data;
+ offset = brw_inst2 - brw_inst1;
+ brw_set_src1(brw_inst1, brw_imm_d(offset*16));
+ break;
+ case OPCODE_END:
+ offset = end_inst - brw_inst1;
+ brw_set_src1(brw_inst1, brw_imm_d(offset*16));
+ break;
+ default:
+ break;
+ }
+ }
+}
/* Emit the fragment program instructions here.
*/
-void brw_vs_emit( struct brw_vs_compile *c )
+void brw_vs_emit(struct brw_vs_compile *c )
{
+#define MAX_IFSN 32
struct brw_compile *p = &c->func;
GLuint nr_insns = c->vp->program.Base.NumInstructions;
- GLuint insn;
-
+ GLuint insn, if_insn = 0;
+ struct brw_instruction *end_inst;
+ struct brw_instruction *if_inst[32];
if (INTEL_DEBUG & DEBUG_VS) {
_mesa_printf("\n\n\nvs-emit:\n");
@@ -924,6 +979,7 @@ void brw_vs_emit( struct brw_vs_compile *c )
/* Get argument regs. SWZ is special and does this itself.
*/
+ inst->Data = &p->store[p->nr_insn];
if (inst->Opcode != OPCODE_SWZ)
for (i = 0; i < 3; i++)
args[i] = get_arg(c, inst->SrcReg[i]);
@@ -934,7 +990,6 @@ void brw_vs_emit( struct brw_vs_compile *c )
*/
dst = get_dst(c, inst->DstReg);
-
switch (inst->Opcode) {
case OPCODE_ABS:
brw_MOV(p, dst, brw_abs(args[0]));
@@ -1003,12 +1058,25 @@ void brw_vs_emit( struct brw_vs_compile *c )
case OPCODE_RSQ:
emit_math1(c, BRW_MATH_FUNCTION_RSQ, dst, args[0], BRW_MATH_PRECISION_FULL);
break;
+
+ case OPCODE_SEQ:
+ emit_seq(p, dst, args[0], args[1]);
+ break;
+ case OPCODE_SNE:
+ emit_sne(p, dst, args[0], args[1]);
+ break;
case OPCODE_SGE:
emit_sge(p, dst, args[0], args[1]);
break;
+ case OPCODE_SGT:
+ emit_sgt(p, dst, args[0], args[1]);
+ break;
case OPCODE_SLT:
emit_slt(p, dst, args[0], args[1]);
break;
+ case OPCODE_SLE:
+ emit_sle(p, dst, args[0], args[1]);
+ break;
case OPCODE_SUB:
brw_ADD(p, dst, args[0], negate(args[1]));
break;
@@ -1021,21 +1089,45 @@ void brw_vs_emit( struct brw_vs_compile *c )
case OPCODE_XPD:
emit_xpd(p, dst, args[0], args[1]);
break;
+ case OPCODE_IF:
+ assert(if_insn < MAX_IFSN);
+ if_inst[if_insn++] = brw_IF(p, BRW_EXECUTE_8);
+ break;
+ case OPCODE_ELSE:
+ brw_ELSE(p, if_inst[if_insn]);
+ break;
+ case OPCODE_ENDIF:
+ assert(if_insn > 0);
+ brw_ENDIF(p, if_inst[--if_insn]);
+ break;
+ case OPCODE_BRA:
+ brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
+ brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
+ brw_set_predicate_control_flag_value(p, 0xFF);
+ break;
+ case OPCODE_CAL:
+ brw_ADD(p, c->ret, brw_ip_reg(), brw_imm_d(2*16));
+ inst->Data = &p->store[p->nr_insn];
+ brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
+ break;
+ case OPCODE_RET:
+ brw_MOV(p, brw_ip_reg(), c->ret);
case OPCODE_END:
+ brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
+ break;
case OPCODE_PRINT:
+ case OPCODE_BGNSUB:
+ case OPCODE_ENDSUB:
break;
default:
+ _mesa_printf("Unsupport opcode %d in vertex shader\n", inst->Opcode);
break;
}
release_tmps(c);
}
+ end_inst = &p->store[p->nr_insn];
emit_vertex_write(c);
-
+ post_vs_emit(c, end_inst);
}
-
-
-
-
-