*/
LLVMValueRef inputs_array;
+ LLVMValueRef system_values_array;
+
const struct tgsi_shader_info *info;
/** bitmask indicating which register files are accessed indirectly */
unsigned indirect_files;
static void lp_exec_mask_update(struct lp_exec_mask *mask)
{
+ LLVMBuilderRef builder = mask->bld->gallivm->builder;
+
if (mask->loop_stack_size) {
/*for loops we need to update the entire mask at runtime */
LLVMValueRef tmp;
assert(mask->break_mask);
- tmp = LLVMBuildAnd(mask->bld->builder,
+ tmp = LLVMBuildAnd(builder,
mask->cont_mask,
mask->break_mask,
"maskcb");
- mask->exec_mask = LLVMBuildAnd(mask->bld->builder,
+ mask->exec_mask = LLVMBuildAnd(builder,
mask->cond_mask,
tmp,
"maskfull");
mask->exec_mask = mask->cond_mask;
if (mask->call_stack_size) {
- mask->exec_mask = LLVMBuildAnd(mask->bld->builder,
+ mask->exec_mask = LLVMBuildAnd(builder,
mask->exec_mask,
mask->ret_mask,
"callmask");
static void lp_exec_mask_cond_push(struct lp_exec_mask *mask,
LLVMValueRef val)
{
+ LLVMBuilderRef builder = mask->bld->gallivm->builder;
+
assert(mask->cond_stack_size < LP_MAX_TGSI_NESTING);
if (mask->cond_stack_size == 0) {
assert(mask->cond_mask == LLVMConstAllOnes(mask->int_vec_type));
}
mask->cond_stack[mask->cond_stack_size++] = mask->cond_mask;
assert(LLVMTypeOf(val) == mask->int_vec_type);
- mask->cond_mask = LLVMBuildAnd(mask->bld->builder,
+ mask->cond_mask = LLVMBuildAnd(builder,
mask->cond_mask,
val,
"");
static void lp_exec_mask_cond_invert(struct lp_exec_mask *mask)
{
+ LLVMBuilderRef builder = mask->bld->gallivm->builder;
LLVMValueRef prev_mask;
LLVMValueRef inv_mask;
assert(prev_mask == LLVMConstAllOnes(mask->int_vec_type));
}
- inv_mask = LLVMBuildNot(mask->bld->builder, mask->cond_mask, "");
+ inv_mask = LLVMBuildNot(builder, mask->cond_mask, "");
- mask->cond_mask = LLVMBuildAnd(mask->bld->builder,
+ mask->cond_mask = LLVMBuildAnd(builder,
inv_mask,
prev_mask, "");
lp_exec_mask_update(mask);
static void lp_exec_bgnloop(struct lp_exec_mask *mask)
{
+ LLVMBuilderRef builder = mask->bld->gallivm->builder;
+
if (mask->loop_stack_size == 0) {
assert(mask->loop_block == NULL);
assert(mask->cont_mask == LLVMConstAllOnes(mask->int_vec_type));
++mask->loop_stack_size;
mask->break_var = lp_build_alloca(mask->bld->gallivm, mask->int_vec_type, "");
- LLVMBuildStore(mask->bld->builder, mask->break_mask, mask->break_var);
+ LLVMBuildStore(builder, mask->break_mask, mask->break_var);
mask->loop_block = lp_build_insert_new_block(mask->bld->gallivm, "bgnloop");
- LLVMBuildBr(mask->bld->builder, mask->loop_block);
- LLVMPositionBuilderAtEnd(mask->bld->builder, mask->loop_block);
+ LLVMBuildBr(builder, mask->loop_block);
+ LLVMPositionBuilderAtEnd(builder, mask->loop_block);
- mask->break_mask = LLVMBuildLoad(mask->bld->builder, mask->break_var, "");
+ mask->break_mask = LLVMBuildLoad(builder, mask->break_var, "");
lp_exec_mask_update(mask);
}
static void lp_exec_break(struct lp_exec_mask *mask)
{
- LLVMValueRef exec_mask = LLVMBuildNot(mask->bld->builder,
+ LLVMBuilderRef builder = mask->bld->gallivm->builder;
+ LLVMValueRef exec_mask = LLVMBuildNot(builder,
mask->exec_mask,
"break");
- mask->break_mask = LLVMBuildAnd(mask->bld->builder,
+ mask->break_mask = LLVMBuildAnd(builder,
mask->break_mask,
exec_mask, "break_full");
static void lp_exec_continue(struct lp_exec_mask *mask)
{
- LLVMValueRef exec_mask = LLVMBuildNot(mask->bld->builder,
+ LLVMBuilderRef builder = mask->bld->gallivm->builder;
+ LLVMValueRef exec_mask = LLVMBuildNot(builder,
mask->exec_mask,
"");
- mask->cont_mask = LLVMBuildAnd(mask->bld->builder,
+ mask->cont_mask = LLVMBuildAnd(builder,
mask->cont_mask,
exec_mask, "");
static void lp_exec_endloop(struct gallivm_state *gallivm,
struct lp_exec_mask *mask)
{
+ LLVMBuilderRef builder = mask->bld->gallivm->builder;
LLVMBasicBlockRef endloop;
LLVMTypeRef reg_type = LLVMIntTypeInContext(gallivm->context,
mask->bld->type.width *
* Unlike the continue mask, the break_mask must be preserved across loop
* iterations
*/
- LLVMBuildStore(mask->bld->builder, mask->break_mask, mask->break_var);
+ LLVMBuildStore(builder, mask->break_mask, mask->break_var);
/* i1cond = (mask == 0) */
i1cond = LLVMBuildICmp(
- mask->bld->builder,
+ builder,
LLVMIntNE,
- LLVMBuildBitCast(mask->bld->builder, mask->exec_mask, reg_type, ""),
+ LLVMBuildBitCast(builder, mask->exec_mask, reg_type, ""),
LLVMConstNull(reg_type), "");
endloop = lp_build_insert_new_block(mask->bld->gallivm, "endloop");
- LLVMBuildCondBr(mask->bld->builder,
+ LLVMBuildCondBr(builder,
i1cond, mask->loop_block, endloop);
- LLVMPositionBuilderAtEnd(mask->bld->builder, endloop);
+ LLVMPositionBuilderAtEnd(builder, endloop);
assert(mask->loop_stack_size);
--mask->loop_stack_size;
LLVMValueRef val,
LLVMValueRef dst)
{
+ LLVMBuilderRef builder = mask->bld->gallivm->builder;
+
/* Mix the predicate and execution mask */
if (mask->has_mask) {
if (pred) {
- pred = LLVMBuildAnd(mask->bld->builder, pred, mask->exec_mask, "");
+ pred = LLVMBuildAnd(builder, pred, mask->exec_mask, "");
} else {
pred = mask->exec_mask;
}
if (pred) {
LLVMValueRef real_val, dst_val;
- dst_val = LLVMBuildLoad(mask->bld->builder, dst, "");
+ dst_val = LLVMBuildLoad(builder, dst, "");
real_val = lp_build_select(mask->bld,
pred,
val, dst_val);
- LLVMBuildStore(mask->bld->builder, real_val, dst);
+ LLVMBuildStore(builder, real_val, dst);
} else
- LLVMBuildStore(mask->bld->builder, val, dst);
+ LLVMBuildStore(builder, val, dst);
}
static void lp_exec_mask_call(struct lp_exec_mask *mask,
static void lp_exec_mask_ret(struct lp_exec_mask *mask, int *pc)
{
+ LLVMBuilderRef builder = mask->bld->gallivm->builder;
LLVMValueRef exec_mask;
if (mask->call_stack_size == 0) {
*pc = -1;
return;
}
- exec_mask = LLVMBuildNot(mask->bld->builder,
+ exec_mask = LLVMBuildNot(builder,
mask->exec_mask,
"ret");
- mask->ret_mask = LLVMBuildAnd(mask->bld->builder,
+ mask->ret_mask = LLVMBuildAnd(builder,
mask->ret_mask,
exec_mask, "ret_full");
unsigned index,
unsigned chan)
{
+ LLVMBuilderRef builder = bld->base.gallivm->builder;
assert(chan < 4);
if (bld->indirect_files & (1 << TGSI_FILE_TEMPORARY)) {
LLVMValueRef lindex = lp_build_const_int32(bld->base.gallivm, index * 4 + chan);
- return LLVMBuildGEP(bld->base.builder, bld->temps_array, &lindex, 1, "");
+ return LLVMBuildGEP(builder, bld->temps_array, &lindex, 1, "");
}
else {
return bld->temps[index][chan];
unsigned index,
unsigned chan)
{
+ LLVMBuilderRef builder = bld->base.gallivm->builder;
assert(chan < 4);
if (bld->indirect_files & (1 << TGSI_FILE_OUTPUT)) {
LLVMValueRef lindex = lp_build_const_int32(bld->base.gallivm,
index * 4 + chan);
- return LLVMBuildGEP(bld->base.builder, bld->outputs_array, &lindex, 1, "");
+ return LLVMBuildGEP(builder, bld->outputs_array, &lindex, 1, "");
}
else {
return bld->outputs[index][chan];
LLVMValueRef base_ptr,
LLVMValueRef indexes)
{
+ LLVMBuilderRef builder = bld->base.gallivm->builder;
LLVMValueRef res = bld->base.undef;
unsigned i;
*/
for (i = 0; i < bld->base.type.length; i++) {
LLVMValueRef ii = lp_build_const_int32(bld->base.gallivm, i);
- LLVMValueRef index = LLVMBuildExtractElement(bld->base.builder,
+ LLVMValueRef index = LLVMBuildExtractElement(builder,
indexes, ii, "");
- LLVMValueRef scalar_ptr = LLVMBuildGEP(bld->base.builder, base_ptr,
+ LLVMValueRef scalar_ptr = LLVMBuildGEP(builder, base_ptr,
&index, 1, "gather_ptr");
- LLVMValueRef scalar = LLVMBuildLoad(bld->base.builder, scalar_ptr, "");
+ LLVMValueRef scalar = LLVMBuildLoad(builder, scalar_ptr, "");
- res = LLVMBuildInsertElement(bld->base.builder, res, scalar, ii, "");
+ res = LLVMBuildInsertElement(builder, res, scalar, ii, "");
}
return res;
LLVMValueRef pred)
{
struct gallivm_state *gallivm = bld->base.gallivm;
- LLVMBuilderRef builder = bld->base.builder;
+ LLVMBuilderRef builder = gallivm->builder;
unsigned i;
/* Mix the predicate and execution mask */
if (mask->has_mask) {
if (pred) {
- pred = LLVMBuildAnd(mask->bld->builder, pred, mask->exec_mask, "");
+ pred = LLVMBuildAnd(builder, pred, mask->exec_mask, "");
}
else {
pred = mask->exec_mask;
unsigned reg_file, unsigned reg_index,
const struct tgsi_src_register *indirect_reg)
{
+ LLVMBuilderRef builder = bld->base.gallivm->builder;
struct lp_build_context *uint_bld = &bld->uint_bld;
/* always use X component of address register */
unsigned swizzle = indirect_reg->SwizzleX;
base = lp_build_const_int_vec(bld->base.gallivm, uint_bld->type, reg_index);
assert(swizzle < 4);
- rel = LLVMBuildLoad(bld->base.builder,
+ rel = LLVMBuildLoad(builder,
bld->addr[indirect_reg->Index][swizzle],
"load addr reg");
/* for indexing we want integers */
- rel = LLVMBuildFPToSI(bld->base.builder,
+ rel = LLVMBuildFPToSI(builder,
rel,
uint_bld->vec_type, "");
const unsigned chan_index )
{
struct gallivm_state *gallivm = bld->base.gallivm;
+ LLVMBuilderRef builder = gallivm->builder;
struct lp_build_context *uint_bld = &bld->uint_bld;
const struct tgsi_full_src_register *reg = &inst->Src[src_op];
const unsigned swizzle =
index = lp_build_const_int32(gallivm, reg->Register.Index*4 + swizzle);
- scalar_ptr = LLVMBuildGEP(bld->base.builder, bld->consts_ptr,
+ scalar_ptr = LLVMBuildGEP(builder, bld->consts_ptr,
&index, 1, "");
- scalar = LLVMBuildLoad(bld->base.builder, scalar_ptr, "");
+ scalar = LLVMBuildLoad(builder, scalar_ptr, "");
res = lp_build_broadcast_scalar(&bld->base, scalar);
}
/* cast inputs_array pointer to float* */
float4_ptr_type = LLVMPointerType(LLVMFloatTypeInContext(gallivm->context), 0);
- inputs_array = LLVMBuildBitCast(uint_bld->builder, bld->inputs_array,
- float4_ptr_type, "");
+ inputs_array = LLVMBuildBitCast(builder, bld->inputs_array,
+ float4_ptr_type, "");
/* Gather values from the temporary register array */
res = build_gather(bld, inputs_array, index_vec);
if (bld->indirect_files & (1 << TGSI_FILE_INPUT)) {
LLVMValueRef lindex = lp_build_const_int32(gallivm,
reg->Register.Index * 4 + swizzle);
- LLVMValueRef input_ptr = LLVMBuildGEP(bld->base.builder,
+ LLVMValueRef input_ptr = LLVMBuildGEP(builder,
bld->inputs_array, &lindex, 1, "");
- res = LLVMBuildLoad(bld->base.builder, input_ptr, "");
+ res = LLVMBuildLoad(builder, input_ptr, "");
}
else {
res = bld->inputs[reg->Register.Index][swizzle];
/* cast temps_array pointer to float* */
float4_ptr_type = LLVMPointerType(LLVMFloatTypeInContext(bld->base.gallivm->context), 0);
- temps_array = LLVMBuildBitCast(uint_bld->builder, bld->temps_array,
+ temps_array = LLVMBuildBitCast(builder, bld->temps_array,
float4_ptr_type, "");
/* Gather values from the temporary register array */
else {
LLVMValueRef temp_ptr;
temp_ptr = get_temp_ptr(bld, reg->Register.Index, swizzle);
- res = LLVMBuildLoad(bld->base.builder, temp_ptr, "");
+ res = LLVMBuildLoad(builder, temp_ptr, "");
if (!res)
return bld->base.undef;
}
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(gallivm,
+ reg->Register.Index * 4 + swizzle);
+
+ scalar_ptr = LLVMBuildGEP(builder, bld->system_values_array,
+ &index, 1, "");
+ scalar = LLVMBuildLoad(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;
const struct tgsi_full_instruction *inst,
LLVMValueRef *pred)
{
+ LLVMBuilderRef builder = bld->base.gallivm->builder;
unsigned index;
unsigned char swizzles[4];
LLVMValueRef unswizzled[4] = {NULL, NULL, NULL, NULL};
* in the swizzles
*/
if (!unswizzled[swizzle]) {
- value = LLVMBuildLoad(bld->base.builder,
+ value = LLVMBuildLoad(builder,
bld->preds[index][swizzle], "");
/*
value,
bld->base.zero);
if (inst->Predicate.Negate) {
- value = LLVMBuildNot(bld->base.builder, value, "");
+ value = LLVMBuildNot(builder, value, "");
}
unswizzled[swizzle] = value;
LLVMValueRef value)
{
struct gallivm_state *gallivm = bld->base.gallivm;
+ LLVMBuilderRef builder = gallivm->builder;
const struct tgsi_full_dst_register *reg = &inst->Dst[index];
struct lp_build_context *uint_bld = &bld->uint_bld;
LLVMValueRef indirect_index = NULL;
switch( reg->Register.File ) {
case TGSI_FILE_OUTPUT:
if (reg->Register.Indirect) {
- LLVMBuilderRef builder = bld->base.builder;
LLVMValueRef chan_vec =
lp_build_const_int_vec(gallivm, uint_bld->type, chan_index);
LLVMValueRef length_vec =
case TGSI_FILE_TEMPORARY:
if (reg->Register.Indirect) {
- LLVMBuilderRef builder = bld->base.builder;
LLVMValueRef chan_vec =
lp_build_const_int_vec(gallivm, uint_bld->type, chan_index);
LLVMValueRef length_vec =
enum lp_build_tex_modifier modifier,
LLVMValueRef *texel)
{
+ LLVMBuilderRef builder = bld->base.gallivm->builder;
unsigned unit;
LLVMValueRef lod_bias, explicit_lod;
LLVMValueRef oow = NULL;
for (i = 0; i < num_coords; i++) {
LLVMValueRef src1 = emit_fetch( bld, inst, 1, i );
LLVMValueRef src2 = emit_fetch( bld, inst, 2, i );
- ddx[i] = LLVMBuildExtractElement(bld->base.builder, src1, index0, "");
- ddy[i] = LLVMBuildExtractElement(bld->base.builder, src2, index0, "");
+ ddx[i] = LLVMBuildExtractElement(builder, src1, index0, "");
+ ddy[i] = LLVMBuildExtractElement(builder, src2, index0, "");
}
unit = inst->Src[3].Register.Index;
} else {
const struct tgsi_full_instruction *inst,
int pc)
{
+ LLVMBuilderRef builder = bld->base.gallivm->builder;
const struct tgsi_full_src_register *reg = &inst->Src[0];
LLVMValueRef terms[NUM_CHANNELS];
LLVMValueRef mask;
chan_mask = lp_build_cmp(&bld->base, PIPE_FUNC_GEQUAL, terms[chan_index], bld->base.zero);
if(mask)
- mask = LLVMBuildAnd(bld->base.builder, mask, chan_mask, "");
+ mask = LLVMBuildAnd(builder, mask, chan_mask, "");
else
mask = chan_mask;
}
const struct tgsi_full_instruction *inst,
int pc)
{
+ LLVMBuilderRef builder = bld->base.gallivm->builder;
LLVMValueRef mask;
/* For those channels which are "alive", disable fragment shader
* execution.
*/
if (bld->exec_mask.has_mask) {
- mask = LLVMBuildNot(bld->base.builder, bld->exec_mask.exec_mask, "kilp");
+ mask = LLVMBuildNot(builder, bld->exec_mask.exec_mask, "kilp");
}
else {
LLVMValueRef zero = LLVMConstNull(bld->base.int_vec_type);
for (chan = 0; chan < 4; chan++) {
temp_ptr = get_temp_ptr(bld, index, chan);
- res = LLVMBuildLoad(bld->base.builder, temp_ptr, "");
+ res = LLVMBuildLoad(builder, temp_ptr, "");
v[chan][0] = LLVMBuildExtractElement(builder, res, i0, "");
v[chan][1] = LLVMBuildExtractElement(builder, res, i1, "");
v[chan][2] = LLVMBuildExtractElement(builder, res, i2, "");
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],
LLVMValueRef lindex =
lp_build_const_int32(gallivm, index * 4 + chan);
LLVMValueRef input_ptr =
- LLVMBuildGEP(bld.base.builder, bld.inputs_array,
+ LLVMBuildGEP(gallivm->builder, bld.inputs_array,
&lindex, 1, "");
LLVMValueRef value = bld.inputs[index][chan];
if (value)
- LLVMBuildStore(bld.base.builder, value, input_ptr);
+ LLVMBuildStore(gallivm->builder, value, input_ptr);
}
}
}
+ bld.system_values_array = system_values_array;
+
tgsi_parse_init( &parse, tokens );
while( !tgsi_parse_end_of_tokens( &parse ) ) {
if (0) {
LLVMModuleRef module = LLVMGetGlobalParent(
- LLVMGetBasicBlockParent(LLVMGetInsertBlock(bld.base.builder)));
+ LLVMGetBasicBlockParent(LLVMGetInsertBlock(gallivm->builder)));
LLVMDumpModule(module);
}
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(struct gallivm_state *gallivm,
+ const struct tgsi_shader_info *info,
+ LLVMValueRef instance_id,
+ LLVMValueRef facing)
+{
+ LLVMValueRef size = lp_build_const_int32(gallivm, 4 * info->num_system_values);
+ LLVMTypeRef float_t = LLVMFloatTypeInContext(gallivm->context);
+ LLVMValueRef array = lp_build_array_alloca(gallivm, float_t,
+ size, "sysvals_array");
+ unsigned i;
+
+ for (i = 0; i < info->num_system_values; i++) {
+ LLVMValueRef index = lp_build_const_int32(gallivm, 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(gallivm->builder, instance_id, float_t,
+ "sysval_instanceid");
+ break;
+ case TGSI_SEMANTIC_FACE:
+ /* fall-through */
+ default:
+ assert(0 && "unexpected semantic in build_system_values_array()");
+ }
+
+ ptr = LLVMBuildGEP(gallivm->builder, array, &index, 1, "");
+ LLVMBuildStore(gallivm->builder, value, ptr);
+ }
+
+ return array;
+}