summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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);
}
}
}