r600g: add flat non-interpolation support.
authorDave Airlie <airlied@redhat.com>
Thu, 15 Sep 2011 11:38:10 +0000 (12:38 +0100)
committerDave Airlie <airlied@redhat.com>
Fri, 16 Sep 2011 08:25:48 +0000 (09:25 +0100)
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 <airlied@redhat.com>
src/gallium/drivers/r600/r600_asm.c
src/gallium/drivers/r600/r600_opcodes.h
src/gallium/drivers/r600/r600_shader.c

index fc792f1cf71f48ae6aac5be5c77ed630b0086570..6d92640f467941e2f634b75fad3c43d7a5e2c54a 100644 (file)
@@ -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);
index 7ae091ea5cd976e164a458053d2601c31bdd78b8..024b3a7808df662dde62597f2c5ac6641ac222d9 100644 (file)
 #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
index 7f7f74537328d4dc6cb3cc04e22278523df0b60e..32aaf15b7f500f869f88ffc7d2da044f9073fc2c 100644 (file)
@@ -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);
                                }
                        }
                }