Example #1
0
static LLVMValueRef
emit_fetch_temporary(
	struct lp_build_tgsi_context *bld_base,
	const struct tgsi_full_src_register *reg,
	enum tgsi_opcode_type type,
	unsigned swizzle)
{
	struct lp_build_tgsi_soa_context *bld = lp_soa_context(bld_base);
	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
	if (swizzle == ~0) {
		LLVMValueRef values[TGSI_NUM_CHANNELS] = {};
		unsigned chan;
		for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
			values[chan] = emit_fetch_temporary(bld_base, reg, type, chan);
		}
		return lp_build_gather_values(bld_base->base.gallivm, values,
						TGSI_NUM_CHANNELS);
	}

	if (reg->Register.Indirect) {
		LLVMValueRef array_index = emit_array_index(bld, reg, swizzle);
		LLVMValueRef ptr = LLVMBuildGEP(builder, bld->temps_array, &array_index,
						1, "");
		return LLVMBuildLoad(builder, ptr, "");
	} else {
		LLVMValueRef temp_ptr;
		temp_ptr = lp_get_temp_ptr_soa(bld, reg->Register.Index, swizzle);
		return bitcast(bld_base,type,LLVMBuildLoad(builder, temp_ptr, ""));
	}
}
Example #2
0
static LLVMValueRef
emit_fetch(
	struct lp_build_tgsi_context *bld_base,
	const struct tgsi_full_src_register *reg,
	enum tgsi_opcode_type type,
	unsigned swizzle)
{
	struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
	struct lp_build_tgsi_soa_context *bld = lp_soa_context(bld_base);
	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
	LLVMValueRef result, ptr;

	if (swizzle == ~0) {
		LLVMValueRef values[TGSI_NUM_CHANNELS];
		unsigned chan;
		for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
			values[chan] = emit_fetch(bld_base, reg, type, chan);
		}
		return lp_build_gather_values(bld_base->base.gallivm, values,
					      TGSI_NUM_CHANNELS);
	}

	if (reg->Register.Indirect) {
		struct tgsi_declaration_range range = get_array_range(bld_base,
			reg->Register.File, &reg->Indirect);
		return LLVMBuildExtractElement(builder,
			emit_array_fetch(bld_base, reg->Register.File, type, range, swizzle),
			emit_array_index(bld, &reg->Indirect, reg->Register.Index - range.First),
			"");
	}

	switch(reg->Register.File) {
	case TGSI_FILE_IMMEDIATE: {
		LLVMTypeRef ctype = tgsi2llvmtype(bld_base, type);
		return LLVMConstBitCast(bld->immediates[reg->Register.Index][swizzle], ctype);
	}

	case TGSI_FILE_INPUT:
		result = ctx->inputs[radeon_llvm_reg_index_soa(reg->Register.Index, swizzle)];
		break;

	case TGSI_FILE_TEMPORARY:
		ptr = lp_get_temp_ptr_soa(bld, reg->Register.Index, swizzle);
		result = LLVMBuildLoad(builder, ptr, "");
		break;

	case TGSI_FILE_OUTPUT:
		ptr = lp_get_output_ptr(bld, reg->Register.Index, swizzle);
		result = LLVMBuildLoad(builder, ptr, "");
		break;

	default:
		return LLVMGetUndef(tgsi2llvmtype(bld_base, type));
	}

	return bitcast(bld_base, type, result);
}
Example #3
0
	TGSI_FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
		LLVMValueRef value = dst[chan_index];

		if (inst->Instruction.Saturate != TGSI_SAT_NONE) {
			struct lp_build_emit_data clamp_emit_data;

			memset(&clamp_emit_data, 0, sizeof(clamp_emit_data));
			clamp_emit_data.arg_count = 3;
			clamp_emit_data.args[0] = value;
			clamp_emit_data.args[2] = base.one;

			switch(inst->Instruction.Saturate) {
			case TGSI_SAT_ZERO_ONE:
				clamp_emit_data.args[1] = base.zero;
				break;
			case TGSI_SAT_MINUS_PLUS_ONE:
				clamp_emit_data.args[1] = LLVMConstReal(
						base.elem_type, -1.0f);
				break;
			default:
				assert(0);
			}
			value = lp_build_emit_llvm(bld_base, TGSI_OPCODE_CLAMP,
						&clamp_emit_data);
		}

		switch(reg->Register.File) {
		case TGSI_FILE_ADDRESS:
			temp_ptr = bld->addr[reg->Register.Index][chan_index];
			LLVMBuildStore(builder, value, temp_ptr);
			continue;
		case TGSI_FILE_OUTPUT:
			temp_ptr = bld->outputs[reg->Register.Index][chan_index];
			break;

		case TGSI_FILE_TEMPORARY:
			temp_ptr = lp_get_temp_ptr_soa(bld, reg->Register.Index, chan_index);
			break;

		default:
			return;
		}

		value = bitcast(bld_base, TGSI_TYPE_FLOAT, value);

		LLVMBuildStore(builder, value, temp_ptr);
	}
Example #4
0
	TGSI_FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
		LLVMValueRef value = dst[chan_index];

		if (inst->Instruction.Saturate != TGSI_SAT_NONE) {
			struct lp_build_emit_data clamp_emit_data;

			memset(&clamp_emit_data, 0, sizeof(clamp_emit_data));
			clamp_emit_data.arg_count = 3;
			clamp_emit_data.args[0] = value;
			clamp_emit_data.args[2] = base.one;

			switch(inst->Instruction.Saturate) {
			case TGSI_SAT_ZERO_ONE:
				clamp_emit_data.args[1] = base.zero;
				break;
			case TGSI_SAT_MINUS_PLUS_ONE:
				clamp_emit_data.args[1] = LLVMConstReal(
						base.elem_type, -1.0f);
				break;
			default:
				assert(0);
			}
			value = lp_build_emit_llvm(bld_base, TGSI_OPCODE_CLAMP,
						&clamp_emit_data);
		}

		if (reg->Register.File == TGSI_FILE_ADDRESS) {
			temp_ptr = bld->addr[reg->Register.Index][chan_index];
			LLVMBuildStore(builder, value, temp_ptr);
			continue;
		}
	
		value = bitcast(bld_base, TGSI_TYPE_FLOAT, value);

		if (reg->Register.Indirect) {
			struct tgsi_declaration_range range = get_array_range(bld_base,
				reg->Register.File, &reg->Indirect);

        		unsigned i, size = range.Last - range.First + 1;
			LLVMValueRef array = LLVMBuildInsertElement(builder,
				emit_array_fetch(bld_base, reg->Register.File, TGSI_TYPE_FLOAT, range, chan_index),
				value,  emit_array_index(bld, &reg->Indirect, reg->Register.Index - range.First), "");

        		for (i = 0; i < size; ++i) {
				switch(reg->Register.File) {
				case TGSI_FILE_OUTPUT:
					temp_ptr = bld->outputs[i + range.First][chan_index];
					break;

				case TGSI_FILE_TEMPORARY:
					temp_ptr = lp_get_temp_ptr_soa(bld, i + range.First, chan_index);
					break;

				default:
					return;
				}
				value = LLVMBuildExtractElement(builder, array, 
					lp_build_const_int32(gallivm, i), "");
				LLVMBuildStore(builder, value, temp_ptr);
			}

		} else {
			switch(reg->Register.File) {
			case TGSI_FILE_OUTPUT:
				temp_ptr = bld->outputs[reg->Register.Index][chan_index];
				break;

			case TGSI_FILE_TEMPORARY:
				temp_ptr = lp_get_temp_ptr_soa(bld, reg->Register.Index, chan_index);
				break;

			default:
				return;
			}
			LLVMBuildStore(builder, value, temp_ptr);
		}
	}