GLSL parser: Rework precision qualifier patching 93/253693/1 accepted/tizen/unified/20210222.114534 submit/tizen/20210222.040422
authorLukasz Kostyra <l.kostyra@samsung.com>
Tue, 16 Feb 2021 13:34:24 +0000 (14:34 +0100)
committerLukasz Kostyra <l.kostyra@samsung.com>
Tue, 16 Feb 2021 13:36:48 +0000 (14:36 +0100)
Since precision qualifiers can be used in multiple places (or can be
provided using preprocessor), they are now handled by adding following
statements to shader header (if needed):
    #define highp
    #define mediump
    #define lowp

Parser has been adjusted to pass forward precision qualifiers instead of
patching them.

Change-Id: I002fb62b7ddee0d00a81a60f6b082694c2f9653e

GLESv2/yagl_glsl_lexer.l
GLESv2/yagl_glsl_parser.y
GLESv2/yagl_glsl_state.c
GLESv2/yagl_glsl_state.h

index 026aba04e018d7adcdd330eeafff8b15596070ef..c0515726834c3c9076ec279623724490b3236bc0 100644 (file)
@@ -252,12 +252,6 @@ PP_FUNCTION {STRING}{WS}*\([^\n]+
     return TOK_GLFRAGCOLOR;
 }
 
-{PRECISION_QUAL} {
-    struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
-    yagl_glsl_state_new_str_token(state, yylval, yytext);
-    return TOK_PRECISION_QUAL;
-}
-
 "precision" {
     struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
     BEGIN(PRECISION);
@@ -574,12 +568,6 @@ PP_FUNCTION {STRING}{WS}*\([^\n]+
     return TOK_INTEGER;
 }
 
-<UNIFORM>{PRECISION_QUAL} {
-    struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
-    yagl_glsl_state_new_str_token(state, yylval, yytext);
-    return TOK_PRECISION_QUAL;
-}
-
 <UNIFORM>{STRING} {
     struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
     yagl_glsl_state_new_str_token(state, yylval, yytext);
index 723694dd1dce938ff1c837dcee841f2312ea45ba..095bd71dc09d8190bde1bbceceec5ecb893ab8ba 100644 (file)
@@ -673,16 +673,14 @@ 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
+| TOK_UNIFORM TOK_STRING 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_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);
@@ -765,14 +763,12 @@ expression
         }
     }
 }
-| TOK_UNIFORM TOK_PRECISION_QUAL TOK_STRING TOK_STRING TOK_EOI
+| TOK_UNIFORM TOK_STRING TOK_STRING TOK_STRING TOK_EOI
 {
     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_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);
index 2dcbb115ce535d09cc5a03f2c6558346af696ba4..2c538357db884cc2fd20b367c7733bf80792e849 100644 (file)
@@ -106,13 +106,15 @@ static void yagl_glsl_state_flush_version(struct yagl_glsl_state *state)
 {
     int have_version = state->have_version;
     int have_extensions = state->have_extensions;
+    int have_precision = state->have_precision;
 
-    if (have_version && have_extensions) {
+    if (have_version && have_extensions && have_precision) {
         return;
     }
 
     state->have_version = 1;
     state->have_extensions = 1;
+    state->have_precision = 1;
 
     if (!have_version) {
         switch (state->patch_version) {
@@ -139,6 +141,14 @@ static void yagl_glsl_state_flush_version(struct yagl_glsl_state *state)
             break;
         }
     }
+
+    if (!have_precision) {
+        if (state->patch_precision) {
+            yagl_glsl_state_append_header(state, "#define highp\n");
+            yagl_glsl_state_append_header(state, "#define mediump\n");
+            yagl_glsl_state_append_header(state, "#define lowp\n");
+        }
+    }
 }
 
 static void yagl_glsl_state_move_pending(struct yagl_glsl_state *state)
@@ -843,3 +853,14 @@ clean:
 
     return result;
 }
+
+yagl_glsl_qualifier_type yagl_glsl_recognize_qualifier(const char *str)
+{
+    if (strcmp(str, "lowp") == 0 ||
+        strcmp(str, "mediump") == 0 ||
+        strcmp(str, "highp") == 0) {
+        return yagl_glsl_qualifier_precision;
+    }
+
+    return yagl_glsl_qualifier_other;
+}
index 7e4a87b276cff07e8c6c52000e74a9c317f51d12..1d334da58ff195e7f39a9e94a06c4744ad0ad55b 100644 (file)
@@ -111,6 +111,12 @@ typedef enum
     yagl_glsl_pp_op_par_close,
 } yagl_glsl_pp_expr_op;
 
+typedef enum
+{
+    yagl_glsl_qualifier_other = 0,
+    yagl_glsl_qualifier_precision,
+} yagl_glsl_qualifier_type;
+
 struct yagl_glsl_pp_token
 {
     char* macro;
@@ -160,6 +166,8 @@ struct yagl_glsl_state
 
     int have_extensions;
 
+    int have_precision;
+
     int have_samplerexternaloes;
 
     int frag_color_declared;
@@ -332,6 +340,8 @@ yagl_glsl_pp_condition_status yagl_glsl_state_pp_condition_resolve(struct yagl_g
  * @}
  */
 
+yagl_glsl_qualifier_type yagl_glsl_recognize_qualifier(const char *str);
+
 int yagl_glsl_parse(struct yagl_glsl_state *state);
 
 #endif