diff options
Diffstat (limited to 'src/gallium/auxiliary')
-rw-r--r-- | src/gallium/auxiliary/draw/draw_llvm.c | 21 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_tgsi.h | 8 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c | 71 |
3 files changed, 96 insertions, 4 deletions
diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c index 2b5f01cda74..eb162fb0f62 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.c +++ b/src/gallium/auxiliary/draw/draw_llvm.c @@ -340,6 +340,7 @@ generate_vs(struct draw_llvm *llvm, LLVMBuilderRef builder, LLVMValueRef (*outputs)[NUM_CHANNELS], const LLVMValueRef (*inputs)[NUM_CHANNELS], + LLVMValueRef system_values_array, LLVMValueRef context_ptr, struct lp_build_sampler_soa *draw_sampler) { @@ -371,6 +372,7 @@ generate_vs(struct draw_llvm *llvm, vs_type, NULL /*struct lp_build_mask_context *mask*/, consts_ptr, + system_values_array, NULL /*pos*/, inputs, outputs, @@ -1011,7 +1013,9 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) LLVMValueRef start, end, count, stride, step, io_itr; LLVMValueRef io_ptr, vbuffers_ptr, vb_ptr; LLVMValueRef instance_id; + LLVMValueRef system_values_array; struct draw_context *draw = llvm->draw; + const struct tgsi_shader_info *vs_info = &draw->vs.vertex_shader->info; unsigned i, j; struct lp_build_context bld; struct lp_build_loop_state lp_loop; @@ -1070,6 +1074,9 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) lp_build_context_init(&bld, builder, lp_type_int(32)); + system_values_array = lp_build_system_values_array(builder, vs_info, + instance_id, NULL); + end = lp_build_add(&bld, start, count); step = LLVMConstInt(LLVMInt32Type(), max_vertices, 0); @@ -1126,6 +1133,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) builder, outputs, ptr_aos, + system_values_array, context_ptr, sampler); @@ -1156,8 +1164,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) /* store clipmask in vertex header and positions in data */ convert_to_aos(builder, io, outputs, clipmask, - draw->vs.vertex_shader->info.num_outputs, - max_vertices); + vs_info->num_outputs, max_vertices); } lp_build_loop_end_cond(builder, end, step, LLVMIntUGE, &lp_loop); @@ -1207,7 +1214,9 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian LLVMValueRef fetch_elts, fetch_count, stride, step, io_itr; LLVMValueRef io_ptr, vbuffers_ptr, vb_ptr; LLVMValueRef instance_id; + LLVMValueRef system_values_array; struct draw_context *draw = llvm->draw; + const struct tgsi_shader_info *vs_info = &draw->vs.vertex_shader->info; unsigned i, j; struct lp_build_context bld; struct lp_build_loop_state lp_loop; @@ -1268,6 +1277,10 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian lp_build_context_init(&bld, builder, lp_type_int(32)); + system_values_array = lp_build_system_values_array(builder, vs_info, + instance_id, NULL); + + step = LLVMConstInt(LLVMInt32Type(), max_vertices, 0); /* code generated texture sampling */ @@ -1332,6 +1345,7 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian builder, outputs, ptr_aos, + system_values_array, context_ptr, sampler); @@ -1365,8 +1379,7 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian * and transformed positions in data */ convert_to_aos(builder, io, outputs, clipmask, - draw->vs.vertex_shader->info.num_outputs, - max_vertices); + vs_info->num_outputs, max_vertices); } lp_build_loop_end_cond(builder, fetch_count, step, LLVMIntUGE, &lp_loop); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h index a4d3b750c3c..694818ccfb8 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h @@ -179,6 +179,7 @@ lp_build_tgsi_soa(LLVMBuilderRef builder, struct lp_type type, struct lp_build_mask_context *mask, LLVMValueRef consts_ptr, + LLVMValueRef system_values_array, const LLVMValueRef *pos, const LLVMValueRef (*inputs)[4], LLVMValueRef (*outputs)[4], @@ -198,4 +199,11 @@ lp_build_tgsi_aos(LLVMBuilderRef builder, const struct tgsi_shader_info *info); +LLVMValueRef +lp_build_system_values_array(LLVMBuilderRef builder, + const struct tgsi_shader_info *info, + LLVMValueRef instance_id, + LLVMValueRef facing); + + #endif /* LP_BLD_TGSI_H */ diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c index 7f0f058c222..3fdfac95a0a 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c @@ -156,6 +156,8 @@ struct lp_build_tgsi_soa_context */ LLVMValueRef inputs_array; + LLVMValueRef system_values_array; + const struct tgsi_shader_info *info; /** bitmask indicating which register files are accessed indirectly */ unsigned indirect_files; @@ -732,6 +734,22 @@ emit_fetch( } break; + case TGSI_FILE_SYSTEM_VALUE: + assert(!reg->Register.Indirect); + { + LLVMValueRef index; /* index into the system value array */ + LLVMValueRef scalar, scalar_ptr; + + index = lp_build_const_int32(reg->Register.Index * 4 + swizzle); + + scalar_ptr = LLVMBuildGEP(bld->base.builder, bld->system_values_array, + &index, 1, ""); + scalar = LLVMBuildLoad(bld->base.builder, scalar_ptr, ""); + + res = lp_build_broadcast_scalar(&bld->base, scalar); + } + break; + default: assert(0 && "invalid src register in emit_fetch()"); return bld->base.undef; @@ -2289,6 +2307,7 @@ lp_build_tgsi_soa(LLVMBuilderRef builder, struct lp_type type, struct lp_build_mask_context *mask, LLVMValueRef consts_ptr, + LLVMValueRef system_values_array, const LLVMValueRef *pos, const LLVMValueRef (*inputs)[NUM_CHANNELS], LLVMValueRef (*outputs)[NUM_CHANNELS], @@ -2375,6 +2394,8 @@ lp_build_tgsi_soa(LLVMBuilderRef builder, } } + bld.system_values_array = system_values_array; + tgsi_parse_init( &parse, tokens ); while( !tgsi_parse_end_of_tokens( &parse ) ) { @@ -2476,3 +2497,53 @@ lp_build_tgsi_soa(LLVMBuilderRef builder, FREE( bld.instructions ); } + +/** + * Build up the system values array out of individual values such as + * the instance ID, front-face, primitive ID, etc. The shader info is + * used to determine which system values are needed and where to put + * them in the system values array. + * + * XXX only instance ID is implemented at this time. + * + * The system values register file is similar to the constants buffer. + * Example declaration: + * DCL SV[0], INSTANCEID + * Example instruction: + * MOVE foo, SV[0].xxxx; + * + * \return LLVM float array (interpreted as float [][4]) + */ +LLVMValueRef +lp_build_system_values_array(LLVMBuilderRef builder, + const struct tgsi_shader_info *info, + LLVMValueRef instance_id, + LLVMValueRef facing) +{ + LLVMValueRef size = lp_build_const_int32(4 * info->num_system_values); + LLVMValueRef array = lp_build_array_alloca(builder, LLVMFloatType(), + size, "sysvals_array"); + unsigned i; + + for (i = 0; i < info->num_system_values; i++) { + LLVMValueRef index = lp_build_const_int32(i * 4); + LLVMValueRef ptr, value; + + switch (info->system_value_semantic_name[i]) { + case TGSI_SEMANTIC_INSTANCEID: + /* convert instance ID from int to float */ + value = LLVMBuildSIToFP(builder, instance_id, LLVMFloatType(), + "sysval_instanceid"); + break; + case TGSI_SEMANTIC_FACE: + /* fall-through */ + default: + assert(0 && "unexpected semantic in build_system_values_array()"); + } + + ptr = LLVMBuildGEP(builder, array, &index, 1, ""); + LLVMBuildStore(builder, value, ptr); + } + + return array; +} |