X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fshader%2Fslang%2Fslang_preprocess.c;h=e9a24cc009af923bf396ac133c9623343f848eaa;hb=766f3ccbda7def1a81a3d07002e500e8bb1a898e;hp=89aaa3a6213d642eee0a1ec34894a1c51269fd1f;hpb=e97681c7f551a2a2a6bd5eff0f4192a870c816c0;p=mesa.git diff --git a/src/mesa/shader/slang/slang_preprocess.c b/src/mesa/shader/slang/slang_preprocess.c index 89aaa3a6213..e9a24cc009a 100644 --- a/src/mesa/shader/slang/slang_preprocess.c +++ b/src/mesa/shader/slang/slang_preprocess.c @@ -530,14 +530,6 @@ pp_ext_set(pp_ext *self, const char *name, GLboolean enable) } -static void -pp_pragmas_init(struct gl_sl_pragmas *pragmas) -{ - pragmas->Optimize = GL_TRUE; - pragmas->Debug = GL_FALSE; -} - - /** * Called in response to #pragma. For example, "#pragma debug(on)" would * call this function as pp_pragma("debug", "on"). @@ -553,10 +545,12 @@ pp_pragma(struct gl_sl_pragmas *pragmas, const char *pragma, const char *param) if (!param) return GL_FALSE; /* missing required param */ if (_mesa_strcmp(param, "on") == 0) { - pragmas->Optimize = GL_TRUE; + if (!pragmas->IgnoreOptimize) + pragmas->Optimize = GL_TRUE; } else if (_mesa_strcmp(param, "off") == 0) { - pragmas->Optimize = GL_FALSE; + if (!pragmas->IgnoreOptimize) + pragmas->Optimize = GL_FALSE; } else { return GL_FALSE; /* invalid param */ @@ -566,10 +560,12 @@ pp_pragma(struct gl_sl_pragmas *pragmas, const char *pragma, const char *param) if (!param) return GL_FALSE; /* missing required param */ if (_mesa_strcmp(param, "on") == 0) { - pragmas->Debug = GL_TRUE; + if (!pragmas->IgnoreDebug) + pragmas->Debug = GL_TRUE; } else if (_mesa_strcmp(param, "off") == 0) { - pragmas->Debug = GL_FALSE; + if (!pragmas->IgnoreDebug) + pragmas->Debug = GL_FALSE; } else { return GL_FALSE; /* invalid param */ @@ -945,7 +941,6 @@ preprocess_source (slang_string *output, const char *source, } pp_state_init (&state, elog, extensions); - pp_pragmas_init (pragmas); /* add the predefined symbols to the symbol table */ for (i = 0; predefined[i]; i++) { @@ -1040,11 +1035,11 @@ preprocess_source (slang_string *output, const char *source, /* Parse optional macro parameters. */ while (prod[i++] != PARAM_END) { - if (state.cond.top->effective) { - pp_symbol *param; + pp_symbol *param; - id = (const char *) (&prod[i]); - idlen = _mesa_strlen (id); + id = (const char *) (&prod[i]); + idlen = _mesa_strlen (id); + if (state.cond.top->effective) { pp_annotate (output, "%s, ", id); param = pp_symbols_push (&symbol->parameters); if (param == NULL) @@ -1058,8 +1053,23 @@ preprocess_source (slang_string *output, const char *source, id = (const char *) (&prod[i]); idlen = _mesa_strlen (id); if (state.cond.top->effective) { + slang_string replacement; + expand_state es; + pp_annotate (output, ") %s", id); - slang_string_pushs (&symbol->replacement, id, idlen); + + slang_string_init(&replacement); + slang_string_pushs(&replacement, id, idlen); + + /* Expand macro replacement. */ + es.output = &symbol->replacement; + es.input = slang_string_cstr(&replacement); + es.state = &state; + if (!expand(&es, &state.symbols)) { + slang_string_free(&replacement); + goto error; + } + slang_string_free(&replacement); } i += idlen + 1; } @@ -1290,12 +1300,53 @@ error: } +/** + * Remove the continuation characters from the input string. + * This is the very first step in preprocessing and is effective + * even inside comment blocks. + * If there is a whitespace between a backslash and a newline, + * this is not considered as a line continuation. + * \return GL_TRUE for success, GL_FALSE otherwise. + */ +static GLboolean +_slang_preprocess_backslashes(slang_string *output, + const char *input) +{ + while (*input) { + if (input[0] == '\\') { + /* If a newline follows, eat the backslash and the newline. */ + if (input[1] == '\r') { + if (input[2] == '\n') { + input += 3; + } else { + input += 2; + } + } else if (input[1] == '\n') { + if (input[2] == '\r') { + input += 3; + } else { + input += 2; + } + } else { + /* Leave the backslash alone. */ + slang_string_pushc(output, *input++); + } + } else { + slang_string_pushc(output, *input++); + } + } + return GL_TRUE; +} + + /** * Run preprocessor on source code. * \param extensions indicates which GL extensions are enabled * \param output the post-process results * \param input the input text * \param elog log to record warnings, errors + * \param extensions out extension settings + * \param pragmas in/out #pragma settings * \return GL_TRUE for success, GL_FALSE for error */ GLboolean @@ -1307,6 +1358,7 @@ _slang_preprocess_directives(slang_string *output, { grammar pid, eid; GLboolean success; + slang_string without_backslashes; pid = grammar_load_from_text ((const byte *) (slang_pp_directives_syn)); if (pid == 0) { @@ -1319,9 +1371,36 @@ _slang_preprocess_directives(slang_string *output, grammar_destroy (pid); return GL_FALSE; } - success = preprocess_source (output, input, pid, eid, elog, extensions, pragmas); + + slang_string_init(&without_backslashes); + success = _slang_preprocess_backslashes(&without_backslashes, input); + + if (0) { + _mesa_printf("Pre-processed shader:\n"); + _mesa_printf("%s", slang_string_cstr(&without_backslashes)); + _mesa_printf("----------------------\n"); + } + + if (success) { + success = preprocess_source(output, + slang_string_cstr(&without_backslashes), + pid, + eid, + elog, + extensions, + pragmas); + } + + slang_string_free(&without_backslashes); grammar_destroy (eid); grammar_destroy (pid); + + if (0) { + _mesa_printf("Post-processed shader:\n"); + _mesa_printf("%s", slang_string_cstr(output)); + _mesa_printf("----------------------\n"); + } + return success; }