vc4: Add support for swizzling of texture colors.
authorEric Anholt <eric@anholt.net>
Mon, 18 Aug 2014 18:07:31 +0000 (11:07 -0700)
committerEric Anholt <eric@anholt.net>
Mon, 18 Aug 2014 22:27:43 +0000 (15:27 -0700)
Fixes swapped colors on the copypix demo and some piglit tests like
pbo-teximage-tiling .

src/gallium/drivers/vc4/vc4_program.c
src/gallium/drivers/vc4/vc4_screen.c
src/gallium/drivers/vc4/vc4_screen.h

index f64bc06f907cbfe02822058c1db8279322d1991c..20f7a4489dc20ce5ea758f96d57a4a055bbf9c79 100644 (file)
@@ -52,6 +52,7 @@ struct tgsi_to_qir {
         uint32_t num_consts;
 
         struct pipe_shader_state *shader_state;
+        struct vc4_key *key;
         struct vc4_fs_key *fs_key;
         struct vc4_vs_key *vs_key;
 
@@ -64,6 +65,7 @@ struct tgsi_to_qir {
 
 struct vc4_key {
         struct pipe_shader_state *shader_state;
+        enum pipe_format tex_format[VC4_MAX_TEXTURE_SAMPLERS];
 };
 
 struct vc4_fs_key {
@@ -325,6 +327,7 @@ tgsi_to_qir_tex(struct tgsi_to_qir *trans,
 
         struct qreg s = src[0 * 4 + 0];
         struct qreg t = src[0 * 4 + 1];
+        uint32_t sampler = 0; /* XXX */
 
         if (tgsi_inst->Instruction.Opcode == TGSI_OPCODE_TXP) {
                 struct qreg proj = qir_RCP(c, src[0 * 4 + 3]);
@@ -337,7 +340,6 @@ tgsi_to_qir_tex(struct tgsi_to_qir *trans,
          * 1]).
          */
         if (tgsi_inst->Texture.Texture == TGSI_TEXTURE_RECT) {
-                uint32_t sampler = 0; /* XXX */
                 s = qir_FMUL(c, s,
                              get_temp_for_uniform(trans,
                                                   QUNIFORM_TEXRECT_SCALE_X,
@@ -364,12 +366,32 @@ tgsi_to_qir_tex(struct tgsi_to_qir *trans,
         trans->num_texture_samples++;
         qir_emit(c, qir_inst(QOP_TEX_RESULT, c->undef, c->undef, c->undef));
 
+        struct qreg unpacked[4];
+        for (int i = 0; i < 4; i++)
+                unpacked[i] = qir_R4_UNPACK(c, i);
+
+        bool format_warned = false;
         for (int i = 0; i < 4; i++) {
                 if (!(tgsi_inst->Dst[0].Register.WriteMask & (1 << i)))
                         continue;
 
-                struct qreg dst = qir_R4_UNPACK(c, i);
-                update_dst(trans, tgsi_inst, i, dst);
+                enum pipe_format format = trans->key->tex_format[sampler];
+                const struct util_format_description *desc =
+                        util_format_description(format);
+
+                uint8_t swiz = desc->swizzle[i];
+                if (!format_warned &&
+                    swiz <= UTIL_FORMAT_SWIZZLE_W &&
+                    (desc->channel[swiz].type != UTIL_FORMAT_TYPE_UNSIGNED ||
+                     desc->channel[swiz].size != 8)) {
+                        fprintf(stderr,
+                                "tex channel %d unsupported type: %s\n",
+                                i, util_format_name(format));
+                        format_warned = true;
+                }
+
+                update_dst(trans, tgsi_inst, i,
+                           get_swizzled_channel(trans, unpacked, swiz));
         }
 }
 
@@ -1094,6 +1116,7 @@ vc4_shader_tgsi_to_qir(struct vc4_compiled_shader *shader, enum qstage stage,
                 tgsi_dump(trans->shader_state->tokens, 0);
         }
 
+        trans->key = key;
         switch (stage) {
         case QSTAGE_FRAG:
                 trans->fs_key = (struct vc4_fs_key *)key;
@@ -1243,6 +1266,15 @@ vc4_vs_compile(struct vc4_context *vc4, struct vc4_compiled_shader *shader,
         qir_compile_destroy(cs_trans->c);
 }
 
+static void
+vc4_setup_shared_key(struct vc4_key *key, struct vc4_texture_stateobj *texstate)
+{
+        for (int i = 0; i < texstate->num_textures; i++) {
+                struct pipe_resource *prsc = texstate->textures[i]->texture;
+                key->tex_format[i] = prsc->format;
+        }
+}
+
 static void
 vc4_update_compiled_fs(struct vc4_context *vc4, uint8_t prim_mode)
 {
@@ -1250,6 +1282,7 @@ vc4_update_compiled_fs(struct vc4_context *vc4, uint8_t prim_mode)
         struct vc4_fs_key *key = &local_key;
 
         memset(key, 0, sizeof(*key));
+        vc4_setup_shared_key(&key->base, &vc4->fragtex);
         key->base.shader_state = vc4->prog.bind_fs;
         key->is_points = (prim_mode == PIPE_PRIM_POINTS);
         key->is_lines = (prim_mode >= PIPE_PRIM_LINES &&
@@ -1282,6 +1315,7 @@ vc4_update_compiled_vs(struct vc4_context *vc4)
         struct vc4_vs_key *key = &local_key;
 
         memset(key, 0, sizeof(*key));
+        vc4_setup_shared_key(&key->base, &vc4->verttex);
         key->base.shader_state = vc4->prog.bind_vs;
 
         for (int i = 0; i < ARRAY_SIZE(key->attr_formats); i++)
index 852ff871322343ac1ca03a1788cae72d7499c654..41fd373de11e18f16f50150bd1ef0aed29a5f220 100644 (file)
@@ -293,7 +293,7 @@ vc4_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
                 return 0;
         case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
         case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
-                return 16;
+                return VC4_MAX_TEXTURE_SAMPLERS;
         case PIPE_SHADER_CAP_PREFERRED_IR:
                 return PIPE_SHADER_IR_TGSI;
         default:
index 998bbac0416ad92faaaa119b69301dd52f46dad9..5cfdcaeed9f00695345231e2934423bafbb7025e 100644 (file)
@@ -38,6 +38,7 @@ struct vc4_bo;
 #define VC4_DEBUG_NORAST    0x0040
 
 #define VC4_MAX_MIP_LEVELS 12
+#define VC4_MAX_TEXTURE_SAMPLERS 16
 
 struct vc4_screen {
         struct pipe_screen base;