Mesa (master): vc4: Add support for two-sided color.

Eric Anholt anholt at kemper.freedesktop.org
Wed Oct 8 15:53:41 UTC 2014


Module: Mesa
Branch: master
Commit: 581418585e5dee3cca1b42c472b72aa9c74140bb
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=581418585e5dee3cca1b42c472b72aa9c74140bb

Author: Eric Anholt <eric at anholt.net>
Date:   Tue Sep 30 16:24:26 2014 -0700

vc4: Add support for two-sided color.

It's fairly easy, thanks to Rob Clark's lowering code.  Fixes
two-sided-lighting and 4 vertex-program-two-side testcases, while
regressing 8 testcases that involve enabling two-sided color while only
initializing one of the two colors in the VS.  If you're enabling two
sided color, it's of course expected that you really do set up both
colors, so this is still an improvement (and when we set up a linker for
TGSI, we'll hopefully fix those 8 fails).

---

 src/gallium/drivers/vc4/vc4_context.h |    7 +++-
 src/gallium/drivers/vc4/vc4_program.c |   62 ++++++++++++++++++++++++---------
 2 files changed, 51 insertions(+), 18 deletions(-)

diff --git a/src/gallium/drivers/vc4/vc4_context.h b/src/gallium/drivers/vc4/vc4_context.h
index 3c43b94..e8f9e35 100644
--- a/src/gallium/drivers/vc4/vc4_context.h
+++ b/src/gallium/drivers/vc4/vc4_context.h
@@ -76,6 +76,11 @@ struct vc4_shader_uniform_info {
         uint32_t num_texture_samples;
 };
 
+struct vc4_uncompiled_shader {
+        struct pipe_shader_state base;
+        const struct tgsi_token *twoside_tokens;
+};
+
 struct vc4_compiled_shader {
         struct vc4_bo *bo;
 
@@ -90,7 +95,7 @@ struct vc4_compiled_shader {
 };
 
 struct vc4_program_stateobj {
-        struct pipe_shader_state *bind_vs, *bind_fs;
+        struct vc4_uncompiled_shader *bind_vs, *bind_fs;
         struct vc4_compiled_shader *vs, *fs;
         uint32_t dirty;
         uint8_t num_exports;
diff --git a/src/gallium/drivers/vc4/vc4_program.c b/src/gallium/drivers/vc4/vc4_program.c
index 21d0ec9..030577b 100644
--- a/src/gallium/drivers/vc4/vc4_program.c
+++ b/src/gallium/drivers/vc4/vc4_program.c
@@ -43,7 +43,7 @@
 #endif
 
 struct vc4_key {
-        struct pipe_shader_state *shader_state;
+        struct vc4_uncompiled_shader *shader_state;
         struct {
                 enum pipe_format format;
                 unsigned compare_mode:1;
@@ -65,6 +65,7 @@ struct vc4_fs_key {
         bool is_lines;
         bool alpha_test;
         bool point_coord_upper_left;
+        bool light_twoside;
         uint8_t alpha_test_func;
         uint32_t point_sprite_mask;
 
@@ -1588,15 +1589,7 @@ vc4_shader_tgsi_to_qir(struct vc4_context *vc4,
         int ret;
 
         c->stage = stage;
-
-        c->shader_state = key->shader_state;
-        ret = tgsi_parse_init(&c->parser, c->shader_state->tokens);
-        assert(ret == TGSI_PARSE_OK);
-
-        if (vc4_debug & VC4_DEBUG_TGSI) {
-                fprintf(stderr, "TGSI:\n");
-                tgsi_dump(c->shader_state->tokens, 0);
-        }
+        c->shader_state = &key->shader_state->base;
 
         c->key = key;
         switch (stage) {
@@ -1617,6 +1610,37 @@ vc4_shader_tgsi_to_qir(struct vc4_context *vc4,
                 break;
         }
 
+        const struct tgsi_token *tokens = key->shader_state->base.tokens;
+        if (c->fs_key && c->fs_key->light_twoside) {
+                if (!key->shader_state->twoside_tokens) {
+                        const struct tgsi_lowering_config lowering_config = {
+                                .color_two_side = true,
+                        };
+                        struct tgsi_shader_info info;
+                        key->shader_state->twoside_tokens =
+                                tgsi_transform_lowering(&lowering_config,
+                                                        key->shader_state->base.tokens,
+                                                        &info);
+
+                        /* If no transformation occurred, then NULL is
+                         * returned and we just use our original tokens.
+                         */
+                        if (!key->shader_state->twoside_tokens) {
+                                key->shader_state->twoside_tokens =
+                                        key->shader_state->base.tokens;
+                        }
+                }
+                tokens = key->shader_state->twoside_tokens;
+        }
+
+        ret = tgsi_parse_init(&c->parser, tokens);
+        assert(ret == TGSI_PARSE_OK);
+
+        if (vc4_debug & VC4_DEBUG_TGSI) {
+                fprintf(stderr, "TGSI:\n");
+                tgsi_dump(tokens, 0);
+        }
+
         while (!tgsi_parse_end_of_tokens(&c->parser)) {
                 tgsi_parse_token(&c->parser);
 
@@ -1675,7 +1699,7 @@ static void *
 vc4_shader_state_create(struct pipe_context *pctx,
                         const struct pipe_shader_state *cso)
 {
-        struct pipe_shader_state *so = CALLOC_STRUCT(pipe_shader_state);
+        struct vc4_uncompiled_shader *so = CALLOC_STRUCT(vc4_uncompiled_shader);
         if (!so)
                 return NULL;
 
@@ -1694,9 +1718,9 @@ vc4_shader_state_create(struct pipe_context *pctx,
         };
 
         struct tgsi_shader_info info;
-        so->tokens = tgsi_transform_lowering(&lowering_config, cso->tokens, &info);
-        if (!so->tokens)
-                so->tokens = tgsi_dup_tokens(cso->tokens);
+        so->base.tokens = tgsi_transform_lowering(&lowering_config, cso->tokens, &info);
+        if (!so->base.tokens)
+                so->base.tokens = tgsi_dup_tokens(cso->tokens);
 
         return so;
 }
@@ -1823,6 +1847,8 @@ vc4_update_compiled_fs(struct vc4_context *vc4, uint8_t prim_mode)
                          PIPE_SPRITE_COORD_UPPER_LEFT);
         }
 
+        key->light_twoside = vc4->rasterizer->base.light_twoside;
+
         vc4->prog.fs = util_hash_table_get(vc4->fs_cache, key);
         if (vc4->prog.fs)
                 return;
@@ -1907,7 +1933,7 @@ vs_cache_compare(void *key1, void *key2)
 
 struct delete_state {
         struct vc4_context *vc4;
-        struct pipe_shader_state *shader_state;
+        struct vc4_uncompiled_shader *shader_state;
 };
 
 static enum pipe_error
@@ -1946,7 +1972,7 @@ static void
 vc4_shader_state_delete(struct pipe_context *pctx, void *hwcso)
 {
         struct vc4_context *vc4 = vc4_context(pctx);
-        struct pipe_shader_state *so = hwcso;
+        struct vc4_uncompiled_shader *so = hwcso;
         struct delete_state del;
 
         del.vc4 = vc4;
@@ -1954,7 +1980,9 @@ vc4_shader_state_delete(struct pipe_context *pctx, void *hwcso)
         util_hash_table_foreach(vc4->fs_cache, fs_delete_from_cache, &del);
         util_hash_table_foreach(vc4->vs_cache, vs_delete_from_cache, &del);
 
-        free((void *)so->tokens);
+        if (so->twoside_tokens != so->base.tokens)
+                free((void *)so->twoside_tokens);
+        free((void *)so->base.tokens);
         free(so);
 }
 




More information about the mesa-commit mailing list