コード例 #1
0
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;
	int two_side = (ctx->two_side && input->name == TGSI_SEMANTIC_COLOR);
	LLVMValueRef v;
	boolean require_interp_intrinsic = ctx->chip_class >= EVERGREEN &&
		ctx->type == TGSI_PROCESSOR_FRAGMENT;

	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], "");
	}
	}
}
コード例 #2
0
ファイル: r600_llvm.c プロジェクト: VadimGirlin/mesa
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;
			}
		}
	}
}