[Mesa-dev] [PATCH 3/3] radeonsi: Handle TGSI_OPCODE_DDX/Y

Michel Dänzer michel at daenzer.net
Fri Feb 22 08:02:39 PST 2013


From: Michel Dänzer <michel.daenzer at amd.com>

15 more little piglits.

Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
---
 src/gallium/drivers/radeonsi/radeonsi_shader.c | 34 ++++++++++++++++++++++++++
 src/gallium/drivers/radeonsi/radeonsi_shader.h |  1 +
 src/gallium/drivers/radeonsi/si_state_draw.c   |  1 +
 3 files changed, 36 insertions(+)

diff --git a/src/gallium/drivers/radeonsi/radeonsi_shader.c b/src/gallium/drivers/radeonsi/radeonsi_shader.c
index d88d208..4300d0e 100644
--- a/src/gallium/drivers/radeonsi/radeonsi_shader.c
+++ b/src/gallium/drivers/radeonsi/radeonsi_shader.c
@@ -39,6 +39,7 @@
 #include "tgsi/tgsi_parse.h"
 #include "tgsi/tgsi_scan.h"
 #include "tgsi/tgsi_dump.h"
+#include "util/u_memory.h"
 
 #include "radeonsi_pipe.h"
 #include "radeonsi_shader.h"
@@ -1006,6 +1007,33 @@ static void build_tex_intrinsic(const struct lp_build_tgsi_action * action,
 		emit_data->args, emit_data->arg_count);
 }
 
+static void si_llvm_emit_ddxy(
+	const struct lp_build_tgsi_action * action,
+	struct lp_build_tgsi_context * bld_base,
+	struct lp_build_emit_data * emit_data)
+{
+	struct gallivm_state * gallivm = bld_base->base.gallivm;
+	LLVMValueRef args[6];
+	unsigned c, sampler_src;
+
+	assert(emit_data->arg_count + 2 <= Elements(args));
+
+	for (c = 0; c < emit_data->arg_count; ++c)
+		args[c] = emit_data->args[c];
+
+	sampler_src = emit_data->inst->Instruction.NumSrcRegs-1;
+
+	args[c] = lp_build_const_int32(gallivm,
+				       emit_data->inst->Src[sampler_src].Register.Index);
+	args[c + 1] = args[c];
+	args[c + 2] = lp_build_const_int32(gallivm, emit_data->inst->Texture.Texture);
+
+	emit_data->output[0] = build_intrinsic(gallivm->builder,
+					       action->intr_name,
+					       emit_data->dst_type, args, c + 3,
+					       LLVMReadNoneAttribute);
+}
+
 static const struct lp_build_tgsi_action tex_action = {
 	.fetch_args = tex_fetch_args,
 	.emit = build_tex_intrinsic,
@@ -1064,6 +1092,9 @@ int si_pipe_shader_create(
 		return -ENOSYS;
 	}
 
+	shader->shader.uses_derivs =
+		shader_info.opcode_count[TGSI_OPCODE_DDX] > 0 ||
+		shader_info.opcode_count[TGSI_OPCODE_DDY] > 0;
 	shader->shader.uses_kill = shader_info.uses_kill;
 	bld_base->info = &shader_info;
 	bld_base->emit_fetch_funcs[TGSI_FILE_CONSTANT] = fetch_constant;
@@ -1076,6 +1107,9 @@ int si_pipe_shader_create(
 	bld_base->op_actions[TGSI_OPCODE_TXL] = txl_action;
 	bld_base->op_actions[TGSI_OPCODE_TXP] = tex_action;
 
+	bld_base->op_actions[TGSI_OPCODE_DDX].emit = si_llvm_emit_ddxy;
+	bld_base->op_actions[TGSI_OPCODE_DDY].emit = si_llvm_emit_ddxy;
+
 	si_shader_ctx.radeon_bld.load_input = declare_input;
 	si_shader_ctx.tokens = sel->tokens;
 	tgsi_parse_init(&si_shader_ctx.parse, si_shader_ctx.tokens);
diff --git a/src/gallium/drivers/radeonsi/radeonsi_shader.h b/src/gallium/drivers/radeonsi/radeonsi_shader.h
index f54f67c..6b8887f 100644
--- a/src/gallium/drivers/radeonsi/radeonsi_shader.h
+++ b/src/gallium/drivers/radeonsi/radeonsi_shader.h
@@ -72,6 +72,7 @@ struct si_shader {
 	struct si_shader_io	output[32];
 
 	unsigned		ninterp;
+	bool			uses_derivs;
 	bool			uses_kill;
 	bool			fs_write_all;
 	unsigned		nr_cbufs;
diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c
index f8460b0..891d4e8 100644
--- a/src/gallium/drivers/radeonsi/si_state_draw.c
+++ b/src/gallium/drivers/radeonsi/si_state_draw.c
@@ -217,6 +217,7 @@ static void si_pipe_shader_ps(struct pipe_context *ctx, struct si_pipe_shader *s
 		       S_00B028_VGPRS((shader->num_vgprs - 1) / 4) |
 		       S_00B028_SGPRS((num_sgprs - 1) / 8));
 	si_pm4_set_reg(pm4, R_00B02C_SPI_SHADER_PGM_RSRC2_PS,
+		       S_00B02C_EXTRA_LDS_SIZE(shader->shader.uses_derivs ? 1 : 0) |
 		       S_00B02C_USER_SGPR(num_user_sgprs));
 
 	si_pm4_set_reg(pm4, R_02880C_DB_SHADER_CONTROL, db_shader_control);
-- 
1.8.1.3



More information about the mesa-dev mailing list