r600g: use special constants for 0, 1, -1, 1.0f, 0.5f etc
authorChristian König <deathsimple@vodafone.de>
Tue, 14 Dec 2010 22:38:30 +0000 (23:38 +0100)
committerChristian König <deathsimple@vodafone.de>
Wed, 12 Jan 2011 18:40:52 +0000 (19:40 +0100)
src/gallium/drivers/r600/r600_shader.c

index 0902f398f6290f68e91aba042f676af41bf71223..b853fd9dc88e39a15ed8380e1f4433e11d8a3a82 100644 (file)
@@ -556,7 +556,7 @@ int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *s
         * kcache banks later. */
        ctx.file_offset[TGSI_FILE_CONSTANT] = 512;
 
-       ctx.file_offset[TGSI_FILE_IMMEDIATE] = 253;
+       ctx.file_offset[TGSI_FILE_IMMEDIATE] = V_SQ_ALU_SRC_LITERAL;
        ctx.temp_reg = ctx.file_offset[TGSI_FILE_TEMPORARY] +
                        ctx.info.file_count[TGSI_FILE_TEMPORARY];
 
@@ -746,22 +746,54 @@ static int tgsi_src(struct r600_shader_ctx *ctx,
                        const struct tgsi_full_src_register *tgsi_src,
                        struct r600_bc_alu_src *r600_src)
 {
-       int index;
        memset(r600_src, 0, sizeof(struct r600_bc_alu_src));
-       r600_src->sel = tgsi_src->Register.Index;
-       if (tgsi_src->Register.File == TGSI_FILE_IMMEDIATE) {
-               r600_src->sel = 0;
+       r600_src->neg = tgsi_src->Register.Negate;
+       r600_src->abs = tgsi_src->Register.Absolute;
+       if (tgsi_src->Register.File == TGSI_FILE_IMMEDIATE) {           
+               int index;
+               if((tgsi_src->Register.SwizzleX == tgsi_src->Register.SwizzleY) &&
+                       (tgsi_src->Register.SwizzleX == tgsi_src->Register.SwizzleZ) &&
+                       (tgsi_src->Register.SwizzleX == tgsi_src->Register.SwizzleW)) {
+
+                       index = tgsi_src->Register.Index * 4 + tgsi_src->Register.SwizzleX;
+                       switch(ctx->literals[index]) {
+                       case 0:
+                               r600_src->sel = V_SQ_ALU_SRC_0;
+                               return 0;
+                       case 1:
+                               r600_src->sel = V_SQ_ALU_SRC_1_INT;
+                               return 0;
+                       case -1:
+                               r600_src->sel = V_SQ_ALU_SRC_M_1_INT;
+                               return 0;
+                       case 0x3F800000: // 1.0f
+                               r600_src->sel = V_SQ_ALU_SRC_1;
+                               return 0;
+                       case 0x3F000000: // 0.5f
+                               r600_src->sel = V_SQ_ALU_SRC_0_5;
+                               return 0;
+                       case 0xBF800000: // -1.0f
+                               r600_src->sel = V_SQ_ALU_SRC_1;
+                               r600_src->neg ^= 1;
+                               return 0;
+                       case 0xBF000000: // -0.5f
+                               r600_src->sel = V_SQ_ALU_SRC_0_5;
+                               r600_src->neg ^= 1;
+                               return 0;
+                       }
+               }
                index = tgsi_src->Register.Index;
+               r600_src->sel = V_SQ_ALU_SRC_LITERAL;
                ctx->value[0] = ctx->literals[index * 4 + 0];
                ctx->value[1] = ctx->literals[index * 4 + 1];
                ctx->value[2] = ctx->literals[index * 4 + 2];
                ctx->value[3] = ctx->literals[index * 4 + 3];
+       } else {
+               if (tgsi_src->Register.Indirect)
+                       r600_src->rel = V_SQ_REL_RELATIVE;
+               r600_src->sel = tgsi_src->Register.Index;
+               r600_src->sel += ctx->file_offset[tgsi_src->Register.File];
        }
-       if (tgsi_src->Register.Indirect)
-               r600_src->rel = V_SQ_REL_RELATIVE;
-       r600_src->neg = tgsi_src->Register.Negate;
-       r600_src->abs = tgsi_src->Register.Absolute;
-       r600_src->sel += ctx->file_offset[tgsi_src->Register.File];
        return 0;
 }
 
@@ -849,12 +881,12 @@ static int tgsi_split_literal_constant(struct r600_shader_ctx *ctx, struct r600_
        int i, j, k, nliteral, r;
 
        for (i = 0, nliteral = 0; i < inst->Instruction.NumSrcRegs; i++) {
-               if (inst->Src[i].Register.File == TGSI_FILE_IMMEDIATE) {
+               if (r600_src[i].sel == V_SQ_ALU_SRC_LITERAL) {
                        nliteral++;
                }
        }
        for (i = 0, j = nliteral - 1; i < inst->Instruction.NumSrcRegs; i++) {
-               if (j > 0 && inst->Src[i].Register.File == TGSI_FILE_IMMEDIATE) {
+               if (j > 0 && r600_src[i].sel == V_SQ_ALU_SRC_LITERAL) {
                        int treg = r600_get_temp(ctx);
                        for (k = 0; k < 4; k++) {
                                memset(&alu, 0, sizeof(struct r600_bc_alu));