#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;
bool is_lines;
bool alpha_test;
bool point_coord_upper_left;
+ bool light_twoside;
uint8_t alpha_test_func;
uint32_t point_sprite_mask;
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) {
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);
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;
};
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;
}
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;
struct delete_state {
struct vc4_context *vc4;
- struct pipe_shader_state *shader_state;
+ struct vc4_uncompiled_shader *shader_state;
};
static enum pipe_error
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;
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);
}