summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/vc4/vc4_program.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/vc4/vc4_program.c')
-rw-r--r--src/gallium/drivers/vc4/vc4_program.c62
1 files changed, 45 insertions, 17 deletions
diff --git a/src/gallium/drivers/vc4/vc4_program.c b/src/gallium/drivers/vc4/vc4_program.c
index 21d0ec9cf69..030577b196d 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);
}