Ejemplo n.º 1
0
static LLVMValueRef
llvm_face_select_helper(
	struct radeon_llvm_context * ctx,
	const char *intrinsic, unsigned face_register,
	unsigned frontcolor_register, unsigned backcolor_regiser)
{

	LLVMValueRef backcolor = llvm_load_input_helper(
		ctx,
		intrinsic,
		backcolor_regiser);
	LLVMValueRef front_color = llvm_load_input_helper(
		ctx,
		intrinsic,
		frontcolor_register);
	LLVMValueRef face = llvm_load_input_helper(
		ctx,
		"llvm.R600.load.input",
		face_register);
	LLVMValueRef is_face_positive = LLVMBuildFCmp(
		ctx->soa.bld_base.base.gallivm->builder,
		LLVMRealUGT, face,
		lp_build_const_float(ctx->soa.bld_base.base.gallivm, 0.0f),
		"");
	return LLVMBuildSelect(
		ctx->soa.bld_base.base.gallivm->builder,
		is_face_positive,
		front_color,
		backcolor,
		"");
}
static LLVMValueRef
llvm_face_select_helper(
	struct radeon_llvm_context * ctx,
	unsigned face_loc, LLVMValueRef front_color, LLVMValueRef back_color)
{
	const struct lp_build_context * bb = &ctx->soa.bld_base.base;
	LLVMValueRef face = llvm_load_input_helper(ctx, face_loc, 0, 0);
	LLVMValueRef is_front = LLVMBuildFCmp(
		bb->gallivm->builder, LLVMRealUGT, face,
		lp_build_const_float(bb->gallivm, 0.0f),	"");
	return LLVMBuildSelect(bb->gallivm->builder, is_front,
		front_color, back_color, "");
}
static void llvm_load_input(
	struct radeon_llvm_context * ctx,
	unsigned input_index,
	const struct tgsi_full_declaration *decl)
{
	const struct r600_shader_io * input = &ctx->r600_inputs[input_index];
	unsigned chan;
#if HAVE_LLVM < 0x0304
	unsigned interp = 0;
	int ij_index;
#endif
	int two_side = (ctx->two_side && input->name == TGSI_SEMANTIC_COLOR);
	LLVMValueRef v;
#if HAVE_LLVM >= 0x0304
	boolean require_interp_intrinsic = ctx->chip_class >= EVERGREEN &&
		ctx->type == TGSI_PROCESSOR_FRAGMENT;
#endif

#if HAVE_LLVM >= 0x0304
	if (require_interp_intrinsic && input->spi_sid) {
		v = llvm_load_input_vector(ctx, input->lds_pos, input->ij_index,
			(input->interpolate > 0));
	} else
		v = LLVMGetParam(ctx->main_fn, input->gpr);

	if (two_side) {
		struct r600_shader_io * back_input =
			&ctx->r600_inputs[input->back_color_input];
		LLVMValueRef v2;
		LLVMValueRef face = LLVMGetParam(ctx->main_fn, ctx->face_gpr);
		face = LLVMBuildExtractElement(ctx->gallivm.builder, face,
			lp_build_const_int32(&(ctx->gallivm), 0), "");

		if (require_interp_intrinsic && back_input->spi_sid)
			v2 = llvm_load_input_vector(ctx, back_input->lds_pos,
				back_input->ij_index, (back_input->interpolate > 0));
		else
			v2 = LLVMGetParam(ctx->main_fn, back_input->gpr);
		v = llvm_face_select_helper(ctx, face, v, v2);
	}

	for (chan = 0; chan < 4; chan++) {
		unsigned soa_index = radeon_llvm_reg_index_soa(input_index, chan);

		ctx->inputs[soa_index] = LLVMBuildExtractElement(ctx->gallivm.builder, v,
			lp_build_const_int32(&(ctx->gallivm), chan), "");

		if (input->name == TGSI_SEMANTIC_POSITION &&
				ctx->type == TGSI_PROCESSOR_FRAGMENT && chan == 3) {
		/* RCP for fragcoord.w */
		ctx->inputs[soa_index] = LLVMBuildFDiv(ctx->gallivm.builder,
				lp_build_const_float(&(ctx->gallivm), 1.0f),
				ctx->inputs[soa_index], "");
	}
}
#else
	if (ctx->chip_class >= EVERGREEN && ctx->type == TGSI_PROCESSOR_FRAGMENT &&
			input->spi_sid) {
		interp = 1;
		ij_index = (input->interpolate > 0) ? input->ij_index : -1;
	}

	for (chan = 0; chan < 4; chan++) {
		unsigned soa_index = radeon_llvm_reg_index_soa(input_index, chan);
		int loc;

		if (interp) {
			loc = 4 * input->lds_pos + chan;
		} else {
			if (input->name == TGSI_SEMANTIC_FACE)
				loc = 4 * ctx->face_gpr;
			else
				loc = 4 * input->gpr + chan;
		}

		v = llvm_load_input_helper(ctx, loc, interp, ij_index);

		if (two_side) {
			struct r600_shader_io * back_input =
					&ctx->r600_inputs[input->back_color_input];
			int back_loc = interp ? back_input->lds_pos : back_input->gpr;
			LLVMValueRef v2;

			back_loc = 4 * back_loc + chan;
			v2 = llvm_load_input_helper(ctx, back_loc, interp, ij_index);
			v = llvm_face_select_helper(ctx, 4 * ctx->face_gpr, v, v2);
		} else if (input->name == TGSI_SEMANTIC_POSITION &&
				ctx->type == TGSI_PROCESSOR_FRAGMENT && chan == 3) {
			/* RCP for fragcoord.w */
			v = LLVMBuildFDiv(ctx->gallivm.builder,
					lp_build_const_float(&(ctx->gallivm), 1.0f),
					v, "");
		}

		ctx->inputs[soa_index] = v;
	}
#endif
}
Ejemplo n.º 4
0
static void llvm_load_input(
	struct radeon_llvm_context * ctx,
	unsigned input_index,
	const struct tgsi_full_declaration *decl)
{
	unsigned chan;

	const char *intrinsics = "llvm.R600.load.input";
	unsigned offset = 4 * ctx->reserved_reg_count;

	if (ctx->type == TGSI_PROCESSOR_FRAGMENT && ctx->chip_class >= EVERGREEN) {
		switch (decl->Interp.Interpolate) {
		case TGSI_INTERPOLATE_COLOR:
		case TGSI_INTERPOLATE_PERSPECTIVE:
			offset = 0;
			intrinsics = "llvm.R600.load.input.perspective";
			break;
		case TGSI_INTERPOLATE_LINEAR:
			offset = 0;
			intrinsics = "llvm.R600.load.input.linear";
			break;
		case TGSI_INTERPOLATE_CONSTANT:
			offset = 0;
			intrinsics = "llvm.R600.load.input.constant";
			break;
		default:
			assert(0 && "Unknow Interpolate mode");
		}
	}

	for (chan = 0; chan < 4; chan++) {
		unsigned soa_index = radeon_llvm_reg_index_soa(input_index,
								chan);

		switch (decl->Semantic.Name) {
		case TGSI_SEMANTIC_FACE:
			ctx->inputs[soa_index] = llvm_load_input_helper(ctx,
				"llvm.R600.load.input",
				4 * ctx->face_input);
			break;
		case TGSI_SEMANTIC_POSITION:
			if (ctx->type != TGSI_PROCESSOR_FRAGMENT || chan != 3) {
				ctx->inputs[soa_index] = llvm_load_input_helper(ctx,
					"llvm.R600.load.input",
					soa_index + (ctx->reserved_reg_count * 4));
			} else {
				LLVMValueRef w_coord = llvm_load_input_helper(ctx,
				"llvm.R600.load.input",
				soa_index + (ctx->reserved_reg_count * 4));
				ctx->inputs[soa_index] = LLVMBuildFDiv(ctx->gallivm.builder,
				lp_build_const_float(&(ctx->gallivm), 1.0f), w_coord, "");
			}
			break;
		case TGSI_SEMANTIC_COLOR:
			if (ctx->two_side) {
				unsigned front_location, back_location;
				unsigned back_reg = ctx->r600_inputs[input_index]
					.potential_back_facing_reg;
				if (ctx->chip_class >= EVERGREEN) {
					front_location = 4 * ctx->r600_inputs[input_index].lds_pos + chan;
					back_location = 4 * ctx->r600_inputs[back_reg].lds_pos + chan;
				} else {
					front_location = soa_index + 4 * ctx->reserved_reg_count;
					back_location = radeon_llvm_reg_index_soa(
						ctx->r600_inputs[back_reg].gpr,
						chan);
				}
				ctx->inputs[soa_index] = llvm_face_select_helper(ctx,
					intrinsics,
					4 * ctx->face_input, front_location, back_location);
				break;
			}
		default:
			{
				unsigned location;
				if (ctx->chip_class >= EVERGREEN) {
					location = 4 * ctx->r600_inputs[input_index].lds_pos + chan;
				} else {
					location = soa_index + 4 * ctx->reserved_reg_count;
				}
				/* The * 4 is assuming that we are in soa mode. */
				ctx->inputs[soa_index] = llvm_load_input_helper(ctx,
					intrinsics, location);
					
			break;
			}
		}
	}
}