[Mesa-dev] [PATCH 12/12] radeon/llvm: add suport for cube textures

Vadim Girlin vadimgirlin at gmail.com
Mon May 7 10:08:54 PDT 2012


Signed-off-by: Vadim Girlin <vadimgirlin at gmail.com>
---
 src/gallium/drivers/r600/r600_llvm.c               |   22 -----
 .../drivers/radeon/radeon_setup_tgsi_llvm.c        |   92 +++++++++++++++++++-
 2 files changed, 91 insertions(+), 23 deletions(-)

diff --git a/src/gallium/drivers/r600/r600_llvm.c b/src/gallium/drivers/r600/r600_llvm.c
index b2cdbd0..2f83009 100644
--- a/src/gallium/drivers/r600/r600_llvm.c
+++ b/src/gallium/drivers/r600/r600_llvm.c
@@ -203,28 +203,7 @@ static struct lp_build_tgsi_action dot_action = {
 	.intr_name = "llvm.AMDGPU.dp4"
 };
 
-static void txp_fetch_args(
-	struct lp_build_tgsi_context * bld_base,
-	struct lp_build_emit_data * emit_data)
-{
-	LLVMValueRef src_w;
-	unsigned chan;
-	LLVMValueRef coords[4];
-
-	emit_data->dst_type = LLVMVectorType(bld_base->base.elem_type, 4);
-	src_w = lp_build_emit_fetch(bld_base, emit_data->inst, 0, TGSI_CHAN_W);
 
-	for (chan = 0; chan < 3; chan++ ) {
-		LLVMValueRef arg = lp_build_emit_fetch(bld_base,
-						emit_data->inst, 0, chan);
-		coords[chan] = lp_build_emit_llvm_binary(bld_base,
-					TGSI_OPCODE_DIV, arg, src_w);
-	}
-	coords[3] = bld_base->base.one;
-	emit_data->args[0] = lp_build_gather_values(bld_base->base.gallivm,
-						coords, 4);
-	emit_data->arg_count = 1;
-}
 
 LLVMModuleRef r600_tgsi_llvm(
 	struct radeon_llvm_context * ctx,
@@ -257,7 +236,6 @@ LLVMModuleRef r600_tgsi_llvm(
 	bld_base->op_actions[TGSI_OPCODE_TXL].emit = llvm_emit_tex;
 	bld_base->op_actions[TGSI_OPCODE_TXF].emit = llvm_emit_tex;
 	bld_base->op_actions[TGSI_OPCODE_TXQ].emit = llvm_emit_tex;
-	bld_base->op_actions[TGSI_OPCODE_TXP].fetch_args = txp_fetch_args;
 	bld_base->op_actions[TGSI_OPCODE_TXP].emit = llvm_emit_tex;
 
 	lp_build_tgsi_llvm(bld_base, tokens);
diff --git a/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c b/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c
index 502d551..6e6fc3d 100644
--- a/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c
+++ b/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c
@@ -509,6 +509,87 @@ static void kil_emit(
 	}
 }
 
+
+static void emit_prepare_cube_coords(
+		struct lp_build_tgsi_context * bld_base,
+		struct lp_build_emit_data * emit_data)
+{
+	boolean shadowcube = (emit_data->inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE);
+	struct gallivm_state * gallivm = bld_base->base.gallivm;
+	LLVMBuilderRef builder = gallivm->builder;
+	LLVMTypeRef type = bld_base->base.elem_type;
+	LLVMValueRef coords[4];
+	LLVMValueRef mad_args[3];
+	unsigned i, cnt;
+
+	LLVMValueRef v = lp_build_intrinsic(builder, "llvm.AMDGPU.cube",
+			LLVMVectorType(type, 4),
+			&emit_data->args[0],1);
+
+	/* save src.w for shadow cube */
+	cnt = shadowcube ? 3 : 4;
+
+	for (i = 0; i < cnt; ++i) {
+		LLVMValueRef idx = lp_build_const_int32(gallivm, i);
+		coords[i] = LLVMBuildExtractElement(builder, v, idx, "");
+	}
+
+	coords[2] = lp_build_intrinsic(builder, "llvm.AMDIL.fabs.",
+			type, &coords[2], 1);
+	coords[2] = lp_build_intrinsic(builder, "llvm.AMDGPU.rcp",
+			type, &coords[2], 1);
+
+	mad_args[1] = coords[2];
+	mad_args[2] = LLVMConstReal(type, 1.5);
+
+	mad_args[0] = coords[0];
+	coords[0] = lp_build_intrinsic(builder, "llvm.AMDIL.mad.",
+			type, mad_args, 3);
+
+	mad_args[0] = coords[1];
+	coords[1] = lp_build_intrinsic(builder, "llvm.AMDIL.mad.",
+			type, mad_args, 3);
+
+	/* apply yxwy swizzle to cooords */
+	coords[2] = coords[3];
+	coords[3] = coords[1];
+	coords[1] = coords[0];
+	coords[0] = coords[3];
+
+	emit_data->args[0] = lp_build_gather_values(bld_base->base.gallivm,
+						coords, 4);
+}
+
+static void txp_fetch_args(
+	struct lp_build_tgsi_context * bld_base,
+	struct lp_build_emit_data * emit_data)
+{
+	const struct tgsi_full_instruction * inst = emit_data->inst;
+	LLVMValueRef src_w;
+	unsigned chan;
+	LLVMValueRef coords[4];
+
+	emit_data->dst_type = LLVMVectorType(bld_base->base.elem_type, 4);
+	src_w = lp_build_emit_fetch(bld_base, emit_data->inst, 0, TGSI_CHAN_W);
+
+	for (chan = 0; chan < 3; chan++ ) {
+		LLVMValueRef arg = lp_build_emit_fetch(bld_base,
+						emit_data->inst, 0, chan);
+		coords[chan] = lp_build_emit_llvm_binary(bld_base,
+					TGSI_OPCODE_DIV, arg, src_w);
+	}
+	coords[3] = bld_base->base.one;
+	emit_data->args[0] = lp_build_gather_values(bld_base->base.gallivm,
+						coords, 4);
+	emit_data->arg_count = 1;
+
+	if ((inst->Texture.Texture == TGSI_TEXTURE_CUBE ||
+	     inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE) &&
+	    inst->Instruction.Opcode != TGSI_OPCODE_TXQ) {
+		emit_prepare_cube_coords(bld_base, emit_data);
+	}
+}
+
 static void tex_fetch_args(
 	struct lp_build_tgsi_context * bld_base,
 	struct lp_build_emit_data * emit_data)
@@ -521,16 +602,24 @@ static void tex_fetch_args(
 
 	*/
 
+	const struct tgsi_full_instruction * inst = emit_data->inst;
+
 	LLVMValueRef coords[4];
 	unsigned chan;
 	for (chan = 0; chan < 4; chan++) {
-		coords[chan] = lp_build_emit_fetch(bld_base, emit_data->inst, 0, chan);
+		coords[chan] = lp_build_emit_fetch(bld_base, inst, 0, chan);
 	}
 
 	emit_data->arg_count = 1;
 	emit_data->args[0] = lp_build_gather_values(bld_base->base.gallivm,
 						coords, 4);
 	emit_data->dst_type = LLVMVectorType(bld_base->base.elem_type, 4);
+
+	if ((inst->Texture.Texture == TGSI_TEXTURE_CUBE ||
+	     inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE) &&
+	    inst->Instruction.Opcode != TGSI_OPCODE_TXQ) {
+		emit_prepare_cube_coords(bld_base, emit_data);
+	}
 }
 
 static void emit_icmp(
@@ -954,6 +1043,7 @@ void radeon_llvm_context_init(struct radeon_llvm_context * ctx)
 	bld_base->op_actions[TGSI_OPCODE_TXD].intr_name = "llvm.AMDGPU.txd";
 	bld_base->op_actions[TGSI_OPCODE_TXL].fetch_args = tex_fetch_args;
 	bld_base->op_actions[TGSI_OPCODE_TXL].intr_name = "llvm.AMDGPU.txl";
+	bld_base->op_actions[TGSI_OPCODE_TXP].fetch_args = txp_fetch_args;
 	bld_base->op_actions[TGSI_OPCODE_TXP].intr_name = "llvm.AMDGPU.tex";
 	bld_base->op_actions[TGSI_OPCODE_TRUNC].emit = lp_build_tgsi_intrinsic;
 	bld_base->op_actions[TGSI_OPCODE_TRUNC].intr_name = "llvm.AMDGPU.trunc";
-- 
1.7.10.1



More information about the mesa-dev mailing list