summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_logic.c12
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_logic.h2
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c48
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.c11
4 files changed, 65 insertions, 8 deletions
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_logic.c b/src/gallium/auxiliary/gallivm/lp_bld_logic.c
index d23de4f0ef..41ac81b744 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_logic.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_logic.c
@@ -419,3 +419,15 @@ lp_build_select_aos(struct lp_build_context *bld,
#endif
}
}
+
+LLVMValueRef
+lp_build_alloca(struct lp_build_context *bld)
+{
+ const struct lp_type type = bld->type;
+
+ if (type.length > 1) { /*vector*/
+ return LLVMBuildAlloca(bld->builder, lp_build_vec_type(type), "");
+ } else { /*scalar*/
+ return LLVMBuildAlloca(bld->builder, lp_build_elem_type(type), "");
+ }
+}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_logic.h b/src/gallium/auxiliary/gallivm/lp_bld_logic.h
index 40d64eb2c1..a399ebf39e 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_logic.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_logic.h
@@ -76,5 +76,7 @@ lp_build_select_aos(struct lp_build_context *bld,
LLVMValueRef b,
const boolean cond[4]);
+LLVMValueRef
+lp_build_alloca(struct lp_build_context *bld);
#endif /* !LP_BLD_LOGIC_H */
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
index 85e3b1bdd4..a52c6c5028 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
@@ -185,7 +185,7 @@ emit_fetch(
break;
case TGSI_FILE_TEMPORARY:
- res = bld->temps[reg->Register.Index][swizzle];
+ res = LLVMBuildLoad(bld->base.builder, bld->temps[reg->Register.Index][swizzle], "");
if(!res)
return bld->base.undef;
break;
@@ -287,11 +287,13 @@ emit_store(
switch( reg->Register.File ) {
case TGSI_FILE_OUTPUT:
- bld->outputs[reg->Register.Index][chan_index] = value;
+ LLVMBuildStore(bld->base.builder, value,
+ bld->outputs[reg->Register.Index][chan_index]);
break;
case TGSI_FILE_TEMPORARY:
- bld->temps[reg->Register.Index][chan_index] = value;
+ LLVMBuildStore(bld->base.builder, value,
+ bld->temps[reg->Register.Index][chan_index]);
break;
case TGSI_FILE_ADDRESS:
@@ -438,6 +440,42 @@ indirect_temp_reference(const struct tgsi_full_instruction *inst)
return FALSE;
}
+static int
+emit_declaration(
+ struct lp_build_tgsi_soa_context *bld,
+ const struct tgsi_full_declaration *decl)
+{
+ unsigned first = decl->Range.First;
+ unsigned last = decl->Range.Last;
+ unsigned idx, i;
+
+ for (idx = first; idx <= last; ++idx) {
+ boolean ok;
+
+ switch (decl->Declaration.File) {
+ case TGSI_FILE_TEMPORARY:
+ for (i = 0; i < NUM_CHANNELS; i++)
+ bld->temps[idx][i] = lp_build_alloca(&bld->base);
+ ok = TRUE;
+ break;
+
+ case TGSI_FILE_OUTPUT:
+ for (i = 0; i < NUM_CHANNELS; i++)
+ bld->outputs[idx][i] = lp_build_alloca(&bld->base);
+ ok = TRUE;
+ break;
+
+ default:
+ /* don't need to declare other vars */
+ ok = TRUE;
+ }
+
+ if (!ok)
+ return FALSE;
+ }
+
+ return TRUE;
+}
static int
emit_instruction(
@@ -1429,6 +1467,10 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
switch( parse.FullToken.Token.Type ) {
case TGSI_TOKEN_TYPE_DECLARATION:
/* Inputs already interpolated */
+ {
+ if (!emit_declaration( &bld, &parse.FullToken.FullDeclaration ))
+ _debug_printf("warning: failed to define LLVM variable\n");
+ }
break;
case TGSI_TOKEN_TYPE_INSTRUCTION:
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index 320e2b72e4..2001a95661 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -468,20 +468,21 @@ generate_fs(struct llvmpipe_context *lp,
for (attrib = 0; attrib < shader->info.num_outputs; ++attrib) {
for(chan = 0; chan < NUM_CHANNELS; ++chan) {
if(outputs[attrib][chan]) {
- lp_build_name(outputs[attrib][chan], "output%u.%u.%c", i, attrib, "xyzw"[chan]);
+ LLVMValueRef out = LLVMBuildLoad(builder, outputs[attrib][chan], "");
+ lp_build_name(out, "output%u.%u.%c", i, attrib, "xyzw"[chan]);
switch (shader->info.output_semantic_name[attrib]) {
case TGSI_SEMANTIC_COLOR:
{
unsigned cbuf = shader->info.output_semantic_index[attrib];
- lp_build_name(outputs[attrib][chan], "color%u.%u.%c", i, attrib, "rgba"[chan]);
+ lp_build_name(out, "color%u.%u.%c", i, attrib, "rgba"[chan]);
/* Alpha test */
/* XXX: should the alpha reference value be passed separately? */
/* XXX: should only test the final assignment to alpha */
if(cbuf == 0 && chan == 3) {
- LLVMValueRef alpha = outputs[attrib][chan];
+ LLVMValueRef alpha = out;
LLVMValueRef alpha_ref_value;
alpha_ref_value = lp_jit_context_alpha_ref_value(builder, context_ptr);
alpha_ref_value = lp_build_broadcast(builder, vec_type, alpha_ref_value);
@@ -489,13 +490,13 @@ generate_fs(struct llvmpipe_context *lp,
&mask, alpha, alpha_ref_value);
}
- color[cbuf][chan] = outputs[attrib][chan];
+ color[cbuf][chan] = out;
break;
}
case TGSI_SEMANTIC_POSITION:
if(chan == 2)
- z = outputs[attrib][chan];
+ z = out;
break;
}
}