summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <[email protected]>2011-09-15 12:38:10 +0100
committerDave Airlie <[email protected]>2011-09-16 09:25:48 +0100
commit21c5607e64ca4ef68730d8e846d8e7744ecdd024 (patch)
treee73d01045a1cad7f34546c7de227aa7e6425c3a6
parentde3218664a03ee116ca58db571f90a6914299a81 (diff)
r600g: add flat non-interpolation support.
TGSI CONSTANT interpolation is just flat, and we just read the values direct from the LDS into the GPR without doing any interpolation on them. This is needed to pass integer types into the fragment shader. Signed-off-by: Dave Airlie <[email protected]>
-rw-r--r--src/gallium/drivers/r600/r600_asm.c1
-rw-r--r--src/gallium/drivers/r600/r600_opcodes.h2
-rw-r--r--src/gallium/drivers/r600/r600_shader.c33
3 files changed, 33 insertions, 3 deletions
diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c
index fc792f1cf71..6d92640f467 100644
--- a/src/gallium/drivers/r600/r600_asm.c
+++ b/src/gallium/drivers/r600/r600_asm.c
@@ -162,6 +162,7 @@ static inline unsigned int r600_bytecode_get_num_operands(struct r600_bytecode *
case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_COS:
case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RNDNE:
case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOT_INT:
+ case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INTERP_LOAD_P0:
return 1;
default: R600_ERR(
"Need instruction operand number for 0x%x.\n", alu->inst);
diff --git a/src/gallium/drivers/r600/r600_opcodes.h b/src/gallium/drivers/r600/r600_opcodes.h
index 7ae091ea5cd..024b3a7808d 100644
--- a/src/gallium/drivers/r600/r600_opcodes.h
+++ b/src/gallium/drivers/r600/r600_opcodes.h
@@ -364,7 +364,7 @@
#define EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INTERP_ZW 0x000000D7
#define EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INTERP_X 0x000000D8
#define EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INTERP_Z 0x000000D9
-
+#define EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INTERP_LOAD_P0 0x000000E0
/* TODO ADD OTHER OP3 */
#define EG_V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD 0x00000014
diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
index 7f7f7453732..32aaf15b7f5 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -299,6 +299,32 @@ static int evergreen_interp_alu(struct r600_shader_ctx *ctx, int input)
return 0;
}
+static int evergreen_interp_flat(struct r600_shader_ctx *ctx, int input)
+{
+ int i, r;
+ struct r600_bytecode_alu alu;
+
+ for (i = 0; i < 4; i++) {
+ memset(&alu, 0, sizeof(struct r600_bytecode_alu));
+
+ alu.inst = EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INTERP_LOAD_P0;
+
+ alu.dst.sel = ctx->shader->input[input].gpr;
+ alu.dst.write = 1;
+
+ alu.dst.chan = i;
+
+ alu.src[0].sel = V_SQ_ALU_SRC_PARAM_BASE + ctx->shader->input[input].lds_pos;
+ alu.src[0].chan = i;
+
+ if (i == 3)
+ alu.last = 1;
+ r = r600_bytecode_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+ }
+ return 0;
+}
static int tgsi_declaration(struct r600_shader_ctx *ctx)
{
@@ -316,10 +342,13 @@ static int tgsi_declaration(struct r600_shader_ctx *ctx)
ctx->shader->input[i].gpr = ctx->file_offset[TGSI_FILE_INPUT] + i;
if (ctx->type == TGSI_PROCESSOR_FRAGMENT && ctx->bc->chip_class >= EVERGREEN) {
/* turn input into interpolate on EG */
- if (ctx->shader->input[i].name != TGSI_SEMANTIC_POSITION) {
+ if (ctx->shader->input[i].name != TGSI_SEMANTIC_POSITION &&
+ ctx->shader->input[i].name != TGSI_SEMANTIC_FACE) {
+ ctx->shader->input[i].lds_pos = ctx->shader->nlds++;
if (ctx->shader->input[i].interpolate > 0) {
- ctx->shader->input[i].lds_pos = ctx->shader->nlds++;
evergreen_interp_alu(ctx, i);
+ } else {
+ evergreen_interp_flat(ctx, i);
}
}
}