summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/auxiliary/draw/draw_llvm.c21
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi.h8
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c71
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.c3
4 files changed, 98 insertions, 5 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;
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index 48971510f21..cd67d488616 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -334,7 +334,8 @@ generate_fs(struct lp_fragment_shader *shader,
/* Build the actual shader */
lp_build_tgsi_soa(builder, tokens, type, &mask,
- consts_ptr, interp->pos, interp->inputs,
+ consts_ptr, NULL, /* sys values array */
+ interp->pos, interp->inputs,
outputs, sampler, &shader->info.base);