summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukasz Kostyra <l.kostyra@samsung.com>2021-01-15 13:09:12 +0100
committerLukasz Kostyra <l.kostyra@samsung.com>2021-01-18 12:37:12 +0100
commit79df58cdaf8ff8e4fe9168b00f2bfae77047e402 (patch)
tree51ee54227c1d67abdaad215835306c6142a5f9e4
parent5163a79760d43d4ccd016fa0b11a8051d1f53cc1 (diff)
downloademulator-yagl-79df58cdaf8ff8e4fe9168b00f2bfae77047e402.tar.gz
emulator-yagl-79df58cdaf8ff8e4fe9168b00f2bfae77047e402.tar.bz2
emulator-yagl-79df58cdaf8ff8e4fe9168b00f2bfae77047e402.zip
Add GLSL lexer/parser support for uniform arrays
Using uniform arrays caused syntax error. GLSL lexer/parser now understands these statements. Change-Id: Ia5345594ab356fa3977447fe6f3434a06371f946
-rw-r--r--GLESv2/yagl_glsl_lexer.l26
-rw-r--r--GLESv2/yagl_glsl_parser.y100
2 files changed, 119 insertions, 7 deletions
diff --git a/GLESv2/yagl_glsl_lexer.l b/GLESv2/yagl_glsl_lexer.l
index de5d511..9190c7b 100644
--- a/GLESv2/yagl_glsl_lexer.l
+++ b/GLESv2/yagl_glsl_lexer.l
@@ -534,16 +534,34 @@ STRING [^ \r\t\v\f\n()\[\]{},;?:/%*&|^!+\-=<>\.]+
return TOK_STRING;
}
-<UNIFORM>{WS}*; {
+<UNIFORM>{WS}+ {
+ struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+ yagl_glsl_state_new_pending(state, yytext);
+}
+
+<UNIFORM>; {
struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
BEGIN(INITIAL);
- yagl_glsl_state_new_str_token(state, yylval, yytext);
+ yagl_glsl_state_new_character_token(state, yylval, *yytext);
return TOK_EOI;
}
-<UNIFORM>{WS}+ {
+<UNIFORM>\[ {
struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
- yagl_glsl_state_new_pending(state, yytext);
+ yagl_glsl_state_new_character_token(state, yylval, *yytext);
+ return TOK_ARR_PAREN_OPEN;
+}
+
+<UNIFORM>\] {
+ struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+ yagl_glsl_state_new_character_token(state, yylval, *yytext);
+ return TOK_ARR_PAREN_CLOSE;
+}
+
+<UNIFORM>[0-9]* {
+ struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+ yagl_glsl_state_new_integer_token(state, yylval, strtol(yytext, NULL, 10));
+ return TOK_INTEGER;
}
<UNIFORM>{PRECISION_QUAL} {
diff --git a/GLESv2/yagl_glsl_parser.y b/GLESv2/yagl_glsl_parser.y
index 538f340..61dbbe2 100644
--- a/GLESv2/yagl_glsl_parser.y
+++ b/GLESv2/yagl_glsl_parser.y
@@ -47,7 +47,9 @@ static int yagl_glsl_lex(union YYSTYPE *val, struct yagl_glsl_state *state)
}
%token <str> TOK_EOL
-%token <str> TOK_EOI
+%token <character> TOK_EOI
+%token <character> TOK_ARR_PAREN_OPEN
+%token <character> TOK_ARR_PAREN_CLOSE
%token <str> TOK_VERSION
%token <str> TOK_DEFINE
%token <str> TOK_UNDEF
@@ -652,6 +654,98 @@ expression
yagl_glsl_state_append_output(state, $1.value);
}
}
+| TOK_UNIFORM TOK_PRECISION_QUAL TOK_STRING TOK_STRING TOK_ARR_PAREN_OPEN TOK_INTEGER TOK_ARR_PAREN_CLOSE TOK_EOI
+{
+ char s[100];
+
+ yagl_glsl_state_flush_pending(state, $1.index);
+ yagl_glsl_state_append_output(state, $1.value);
+
+ // precision qualifier should only be flushed here, GLSL non-ES does not support it
+ yagl_glsl_state_flush_pending(state, $2.index);
+
+ yagl_glsl_state_flush_pending(state, $3.index);
+ yagl_glsl_state_append_output(state, $3.value);
+ yagl_glsl_state_flush_pending(state, $4.index);
+ yagl_glsl_state_append_output(state, $4.value);
+ yagl_glsl_state_flush_pending(state, $5.index);
+ yagl_glsl_state_append_output_char(state, $5.c);
+ yagl_glsl_state_flush_pending(state, $6.index);
+ sprintf(s, "%d", $6.value);
+ yagl_glsl_state_append_output(state, s);
+ yagl_glsl_state_flush_pending(state, $7.index);
+ yagl_glsl_state_append_output_char(state, $7.c);
+ yagl_glsl_state_flush_pending(state, $8.index);
+ yagl_glsl_state_append_output_char(state, $8.c);
+
+ // TODO this should also take into account TOK_INTEGER, because it could be an array of samplers
+ if (yagl_glsl_state_pp_is_condition_met(state)) {
+ // locally try to resolve the define based on current knowledge
+ // it won't matter if our type is not a macro but an actual sampler type
+ char* type_resolved = NULL;
+ int int_resolved = 0;
+ yagl_glsl_state_pp_resolve_define(state, $3.value, &type_resolved, &int_resolved);
+
+ if (type_resolved != NULL) {
+ if (strcmp(type_resolved, "samplerExternalOES") == 0) {
+ if (!state->have_samplerexternaloes) {
+ yagl_glsl_state_append_header(state, "#define samplerExternalOES sampler2D\n");
+ state->have_samplerexternaloes = 1;
+ }
+
+ yagl_glsl_state_add_sampler_ExternalOES(state, $4.value);
+ } else if (strcmp(type_resolved, "sampler2D") == 0) {
+ yagl_glsl_state_add_sampler_2D(state, $4.value);
+ }
+
+ free(type_resolved);
+ }
+ }
+}
+| TOK_UNIFORM TOK_STRING TOK_STRING TOK_ARR_PAREN_OPEN TOK_INTEGER TOK_ARR_PAREN_CLOSE TOK_EOI
+{
+ char s[100];
+
+ yagl_glsl_state_flush_pending(state, $1.index);
+ yagl_glsl_state_append_output(state, $1.value);
+ yagl_glsl_state_flush_pending(state, $2.index);
+ yagl_glsl_state_append_output(state, $2.value);
+ yagl_glsl_state_flush_pending(state, $3.index);
+ yagl_glsl_state_append_output(state, $3.value);
+ yagl_glsl_state_flush_pending(state, $4.index);
+ yagl_glsl_state_append_output_char(state, $4.c);
+ yagl_glsl_state_flush_pending(state, $5.index);
+ sprintf(s, "%d", $5.value);
+ yagl_glsl_state_append_output(state, s);
+ yagl_glsl_state_flush_pending(state, $6.index);
+ yagl_glsl_state_append_output_char(state, $6.c);
+ yagl_glsl_state_flush_pending(state, $7.index);
+ yagl_glsl_state_append_output_char(state, $7.c);
+
+ // TODO this should also take into account TOK_INTEGER, because it is an array of samplers (not a single sampler)
+ if (yagl_glsl_state_pp_is_condition_met(state)) {
+ // locally try to resolve the define based on current knowledge
+ // it won't matter if our type is not a macro but an actual sampler type
+ char* type_resolved = NULL;
+ int int_resolved = 0;
+ yagl_glsl_state_pp_resolve_define(state, $2.value, &type_resolved, &int_resolved);
+
+ if (type_resolved != NULL) {
+ if (strcmp(type_resolved, "samplerExternalOES") == 0) {
+ if (!state->have_samplerexternaloes) {
+ yagl_glsl_state_append_header(state, "#define samplerExternalOES sampler2D\n");
+ state->have_samplerexternaloes = 1;
+ }
+
+ yagl_glsl_state_add_sampler_ExternalOES(state, $3.value);
+ } else if (strcmp(type_resolved, "sampler2D") == 0) {
+ yagl_glsl_state_add_sampler_2D(state, $3.value);
+ }
+
+ free(type_resolved);
+ }
+ }
+}
| TOK_UNIFORM TOK_PRECISION_QUAL TOK_STRING TOK_STRING TOK_EOI
{
yagl_glsl_state_flush_pending(state, $1.index);
@@ -665,7 +759,7 @@ expression
yagl_glsl_state_flush_pending(state, $4.index);
yagl_glsl_state_append_output(state, $4.value);
yagl_glsl_state_flush_pending(state, $5.index);
- yagl_glsl_state_append_output(state, $5.value);
+ yagl_glsl_state_append_output_char(state, $5.c);
if (yagl_glsl_state_pp_is_condition_met(state)) {
// locally try to resolve the define based on current knowledge
@@ -699,7 +793,7 @@ expression
yagl_glsl_state_flush_pending(state, $3.index);
yagl_glsl_state_append_output(state, $3.value);
yagl_glsl_state_flush_pending(state, $4.index);
- yagl_glsl_state_append_output(state, $4.value);
+ yagl_glsl_state_append_output_char(state, $4.c);
if (yagl_glsl_state_pp_is_condition_met(state)) {
// locally try to resolve the define based on current knowledge