summaryrefslogtreecommitdiff
path: root/src/gallium/auxiliary/gallivm
diff options
context:
space:
mode:
authorBrian Paul <brianp@vmware.com>2010-12-08 19:02:14 -0700
committerBrian Paul <brianp@vmware.com>2010-12-08 19:04:11 -0700
commit1d6f3543a063ab9e740fd0c149dcce26c282d773 (patch)
tree62d31e80ec29fbddafc0312c1438673d913f213c /src/gallium/auxiliary/gallivm
parent2b5e1e5287df5cae218b6f83d2638853d250aff9 (diff)
gallivm/llvmpipe: implement system values and instanceID
Diffstat (limited to 'src/gallium/auxiliary/gallivm')
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi.h8
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c71
2 files changed, 79 insertions, 0 deletions
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
index a4d3b750c3..694818ccfb 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 7f0f058c22..3fdfac95a0 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;
+}