summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/i965/brw_wm_glsl.c
diff options
context:
space:
mode:
authorBrian Paul <brianp@vmware.com>2009-02-13 17:17:52 -0700
committerBrian Paul <brianp@vmware.com>2009-02-13 17:18:36 -0700
commitc51c822ee02cb47ddba46da668577d51b7c02831 (patch)
tree905cafdc5a02f07aa67fc04e66a7fb1734abec20 /src/mesa/drivers/dri/i965/brw_wm_glsl.c
parent74b6d55864b9264323a09856781f655e453b182b (diff)
i965: rewrite the code for handling shader subroutine calls
Previously, the prog_instruction::Data field was used to map original Mesa instructions to brw instructions in order to resolve subroutine calls. This was a rather tangled mess. Plus it's an obstacle to implementing dynamic allocation/growing of the instruction buffer (it's still a fixed size). Mesa's GLSL compiler emits a label for each subroutine and CAL instruction. Now we use those labels to patch the subroutine calls after code generation has been done. We just keep a list of all CAL instructions that needs patching and a list of all subroutine labels. It's a simple matter to resolve them. This also consolidates some redundant post-emit code between brw_vs_emit.c and brw_wm_glsl.c and removes some loops that cleared the prog_instruction::Data fields at the end. Plus, a bunch of new comments.
Diffstat (limited to 'src/mesa/drivers/dri/i965/brw_wm_glsl.c')
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_glsl.c36
1 files changed, 8 insertions, 28 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
index 0d3e2eb770..d99aa372a9 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
@@ -2252,28 +2252,12 @@ static void emit_tex(struct brw_wm_compile *c,
brw_MOV(p, dst[3], brw_imm_f(1.0));
}
+/**
+ * Resolve subroutine calls after code emit is done.
+ */
static void post_wm_emit( struct brw_wm_compile *c )
{
- GLuint nr_insns = c->fp->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->fp->program.Base.Instructions[insn];
- brw_inst1 = inst1->Data;
- switch (inst1->Opcode) {
- case OPCODE_CAL:
- target_insn = inst1->BranchTarget;
- inst2 = &c->fp->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;
- default:
- break;
- }
- }
+ brw_resolve_cals(&c->func);
}
static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
@@ -2293,10 +2277,6 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
for (i = 0; i < c->nr_fp_insns; i++) {
struct prog_instruction *inst = &c->prog_instructions[i];
- struct prog_instruction *orig_inst;
-
- if ((orig_inst = inst->Data) != 0)
- orig_inst->Data = current_insn(p);
if (inst->CondUpdate)
brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
@@ -2454,7 +2434,10 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
brw_ENDIF(p, if_inst[--if_insn]);
break;
case OPCODE_BGNSUB:
+ brw_save_label(p, inst->Comment, p->nr_insn);
+ break;
case OPCODE_ENDSUB:
+ /* no-op */
break;
case OPCODE_CAL:
brw_push_insn_state(p);
@@ -2464,8 +2447,7 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
brw_set_access_mode(p, BRW_ALIGN_16);
brw_ADD(p, get_addr_reg(stack_index),
get_addr_reg(stack_index), brw_imm_d(4));
- orig_inst = inst->Data;
- orig_inst->Data = &p->store[p->nr_insn];
+ brw_save_call(&c->func, inst->Comment, p->nr_insn);
brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
brw_pop_insn_state(p);
break;
@@ -2518,8 +2500,6 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
}
post_wm_emit(c);
- for (i = 0; i < c->fp->program.Base.NumInstructions; i++)
- c->fp->program.Base.Instructions[i].Data = NULL;
}