diff options
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_logic.c | 12 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_logic.h | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c | 48 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_state_fs.c | 11 |
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; } } |