From 29285882676388aacff123e8bdf025904abf8ea9 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 24 Jun 2010 15:32:15 -0700 Subject: glsl2: Move the compiler to the subdirectory it will live in in Mesa. --- src/glsl/glcpp/glcpp.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 src/glsl/glcpp/glcpp.c (limited to 'src/glsl/glcpp/glcpp.c') diff --git a/src/glsl/glcpp/glcpp.c b/src/glsl/glcpp/glcpp.c new file mode 100644 index 0000000000..cc87e14950 --- /dev/null +++ b/src/glsl/glcpp/glcpp.c @@ -0,0 +1,88 @@ +/* + * Copyright © 2010 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include "glcpp.h" + +extern int yydebug; + +static char * +load_text_file(void *ctx, const char *file_name) +{ + char *text = NULL; + struct stat st; + ssize_t total_read = 0; + int fd = file_name == NULL ? STDIN_FILENO : open(file_name, O_RDONLY); + + if (fd < 0) { + return NULL; + } + + if (fstat(fd, & st) == 0) { + text = (char *) talloc_size(ctx, st.st_size + 1); + if (text != NULL) { + do { + ssize_t bytes = read(fd, text + total_read, + st.st_size - total_read); + if (bytes < 0) { + text = NULL; + break; + } + + if (bytes == 0) { + break; + } + + total_read += bytes; + } while (total_read < st.st_size); + + text[total_read] = '\0'; + } + } + + close(fd); + + return text; +} + +int +preprocess(void *talloc_ctx, const char **shader, char **info_log); + +int +main (void) +{ + void *ctx = talloc(NULL, void*); + const char *shader = load_text_file(ctx, NULL); + char *info_log = talloc_strdup(ctx, ""); + int ret = preprocess(ctx, &shader, &info_log); + + printf("%s", shader); + fprintf(stderr, "%s", info_log); + + talloc_free(ctx); + + return ret; +} -- cgit v1.2.3 From 06143ea09411aa283ac3633bfbfa4326584cd952 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 30 Jun 2010 16:27:22 -0700 Subject: glsl2: Conditionally define preprocessor tokens for optional extensions The only optional extension currently supported by the compiler is GL_EXT_texture_array. --- src/glsl/glcpp/glcpp-parse.y | 10 +++++++++- src/glsl/glcpp/glcpp.c | 5 +---- src/glsl/glcpp/glcpp.h | 7 +++++-- src/glsl/glcpp/pp.c | 5 +++-- src/glsl/glsl_parser_extras.h | 3 ++- src/glsl/main.cpp | 4 +++- src/mesa/shader/ir_to_mesa.cpp | 3 ++- 7 files changed, 25 insertions(+), 12 deletions(-) (limited to 'src/glsl/glcpp/glcpp.c') diff --git a/src/glsl/glcpp/glcpp-parse.y b/src/glsl/glcpp/glcpp-parse.y index d4cb006bbc..e5544fe29b 100644 --- a/src/glsl/glcpp/glcpp-parse.y +++ b/src/glsl/glcpp/glcpp-parse.y @@ -28,6 +28,7 @@ #include #include "glcpp.h" +#include "main/mtypes.h" #define glcpp_print(stream, str) stream = talloc_strdup_append(stream, str) #define glcpp_printf(stream, fmt, args...) \ @@ -894,7 +895,7 @@ yyerror (YYLTYPE *locp, glcpp_parser_t *parser, const char *error) } glcpp_parser_t * -glcpp_parser_create (void) +glcpp_parser_create (const struct gl_extensions *extensions) { glcpp_parser_t *parser; token_t *tok; @@ -932,6 +933,13 @@ glcpp_parser_create (void) _token_list_append(list, tok); _define_object_macro(parser, NULL, "GL_ARB_texture_rectangle", list); + if ((extensions != NULL) && extensions->EXT_texture_array) { + list = _token_list_create(parser); + _token_list_append(list, tok); + _define_object_macro(parser, NULL, + "GL_EXT_texture_array", list); + } + talloc_unlink(parser, tok); return parser; diff --git a/src/glsl/glcpp/glcpp.c b/src/glsl/glcpp/glcpp.c index cc87e14950..a245cb5406 100644 --- a/src/glsl/glcpp/glcpp.c +++ b/src/glsl/glcpp/glcpp.c @@ -68,16 +68,13 @@ load_text_file(void *ctx, const char *file_name) return text; } -int -preprocess(void *talloc_ctx, const char **shader, char **info_log); - int main (void) { void *ctx = talloc(NULL, void*); const char *shader = load_text_file(ctx, NULL); char *info_log = talloc_strdup(ctx, ""); - int ret = preprocess(ctx, &shader, &info_log); + int ret = preprocess(ctx, &shader, &info_log, NULL); printf("%s", shader); fprintf(stderr, "%s", info_log); diff --git a/src/glsl/glcpp/glcpp.h b/src/glsl/glcpp/glcpp.h index 2cfa98d2b1..fc9511a67a 100644 --- a/src/glsl/glcpp/glcpp.h +++ b/src/glsl/glcpp/glcpp.h @@ -158,8 +158,10 @@ struct glcpp_parser { int error; }; +struct gl_extensions; + glcpp_parser_t * -glcpp_parser_create (void); +glcpp_parser_create (const struct gl_extensions *extensions); int glcpp_parser_parse (glcpp_parser_t *parser); @@ -168,7 +170,8 @@ void glcpp_parser_destroy (glcpp_parser_t *parser); int -preprocess(void *talloc_ctx, const char **shader, char **info_log); +preprocess(void *talloc_ctx, const char **shader, char **info_log, + const struct gl_extensions *extensions); /* Functions for writing to the info log */ diff --git a/src/glsl/glcpp/pp.c b/src/glsl/glcpp/pp.c index a25b7b72a6..1ce829a2c9 100644 --- a/src/glsl/glcpp/pp.c +++ b/src/glsl/glcpp/pp.c @@ -134,10 +134,11 @@ remove_line_continuations(glcpp_parser_t *ctx, const char *shader) } extern int -preprocess(void *talloc_ctx, const char **shader, char **info_log) +preprocess(void *talloc_ctx, const char **shader, char **info_log, + const struct gl_extensions *extensions) { int errors; - glcpp_parser_t *parser = glcpp_parser_create (); + glcpp_parser_t *parser = glcpp_parser_create (extensions); *shader = remove_line_continuations(parser, *shader); glcpp_lex_set_source_string (parser, *shader); diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h index 3aeba83cc5..dc3d23ac54 100644 --- a/src/glsl/glsl_parser_extras.h +++ b/src/glsl/glsl_parser_extras.h @@ -115,7 +115,8 @@ extern void _mesa_glsl_warning(const YYLTYPE *locp, const char *fmt, ...); extern "C" { -extern int preprocess(void *ctx, const char **shader, char **info_log); +extern int preprocess(void *ctx, const char **shader, char **info_log, + const struct gl_extensions *extensions); } extern void _mesa_glsl_lexer_ctor(struct _mesa_glsl_parse_state *state, diff --git a/src/glsl/main.cpp b/src/glsl/main.cpp index c833c9cde6..deaab7e033 100644 --- a/src/glsl/main.cpp +++ b/src/glsl/main.cpp @@ -109,6 +109,7 @@ void compile_shader(struct gl_shader *shader) { struct _mesa_glsl_parse_state *state; + struct gl_extensions ext; state = talloc_zero(talloc_parent(shader), struct _mesa_glsl_parse_state); @@ -127,11 +128,12 @@ compile_shader(struct gl_shader *shader) state->loop_or_switch_nesting = NULL; state->ARB_texture_rectangle_enable = true; + memset(&ext, 0, sizeof(ext)); state->Const.MaxDrawBuffers = 2; state->Const.MaxTextureCoords = 4; const char *source = shader->Source; - state->error = preprocess(state, &source, &state->info_log); + state->error = preprocess(state, &source, &state->info_log, &ext); if (!state->error) { _mesa_glsl_lexer_ctor(state, source); diff --git a/src/mesa/shader/ir_to_mesa.cpp b/src/mesa/shader/ir_to_mesa.cpp index 14abf602af..918004c79f 100644 --- a/src/mesa/shader/ir_to_mesa.cpp +++ b/src/mesa/shader/ir_to_mesa.cpp @@ -1713,7 +1713,8 @@ _mesa_glsl_compile_shader(GLcontext *ctx, struct gl_shader *shader) state->Const.MaxTextureCoords = ctx->Const.MaxTextureCoordUnits; const char *source = shader->Source; - state->error = preprocess(state, &source, &state->info_log); + state->error = preprocess(state, &source, &state->info_log, + &ctx->Extensions); if (!state->error) { _mesa_glsl_lexer_ctor(state, source); -- cgit v1.2.3 From 97638aa77c509cd37dea499202d31357926a0e2a Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Tue, 17 Aug 2010 23:13:56 -0700 Subject: glcpp: Allow standalone glcpp to accept a filename as first argument. This is useful for debugging the preprocessor. --- src/glsl/glcpp/glcpp.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'src/glsl/glcpp/glcpp.c') diff --git a/src/glsl/glcpp/glcpp.c b/src/glsl/glcpp/glcpp.c index a245cb5406..e49a1df79c 100644 --- a/src/glsl/glcpp/glcpp.c +++ b/src/glsl/glcpp/glcpp.c @@ -69,12 +69,20 @@ load_text_file(void *ctx, const char *file_name) } int -main (void) +main (int argc, char *argv[]) { + char *filename = NULL; void *ctx = talloc(NULL, void*); - const char *shader = load_text_file(ctx, NULL); char *info_log = talloc_strdup(ctx, ""); - int ret = preprocess(ctx, &shader, &info_log, NULL); + const char *shader; + int ret; + + if (argc) { + filename = argv[1]; + } + + shader = load_text_file(ctx, filename); + ret = preprocess(ctx, &shader, &info_log, NULL); printf("%s", shader); fprintf(stderr, "%s", info_log); -- cgit v1.2.3 From cf8bb19a114d753bca94f920b87dcf51aa26af99 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Mon, 23 Aug 2010 09:42:14 -0700 Subject: glcpp: Fix segfault in standalone preprocessor for "file not found", etc. This error message was missing so that the program would simply segfault if the provided filename could not be opened for some reason. While we're at it, we add explicit support for a filename of "-" to indicate input from stdin. --- src/glsl/glcpp/glcpp.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'src/glsl/glcpp/glcpp.c') diff --git a/src/glsl/glcpp/glcpp.c b/src/glsl/glcpp/glcpp.c index e49a1df79c..011058a36a 100644 --- a/src/glsl/glcpp/glcpp.c +++ b/src/glsl/glcpp/glcpp.c @@ -25,6 +25,8 @@ #include #include #include +#include +#include #include "glcpp.h" extern int yydebug; @@ -35,10 +37,18 @@ load_text_file(void *ctx, const char *file_name) char *text = NULL; struct stat st; ssize_t total_read = 0; - int fd = file_name == NULL ? STDIN_FILENO : open(file_name, O_RDONLY); - - if (fd < 0) { - return NULL; + int fd; + + if (file_name == NULL || strcmp(file_name, "-") == 0) { + fd = STDIN_FILENO; + } else { + fd = open (file_name, O_RDONLY); + + if (fd < 0) { + fprintf (stderr, "Failed to open file %s: %s\n", + file_name, strerror (errno)); + return NULL; + } } if (fstat(fd, & st) == 0) { @@ -82,6 +92,9 @@ main (int argc, char *argv[]) } shader = load_text_file(ctx, filename); + if (shader == NULL) + return 1; + ret = preprocess(ctx, &shader, &info_log, NULL); printf("%s", shader); -- cgit v1.2.3 From 61f73fec532b24ef5ec4b5baef81f5e6b9f20918 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Mon, 23 Aug 2010 10:43:27 -0700 Subject: glcpp: Make standalone preprocessor work with a tty as stdin Previously glcpp would silently abort if it couldn't fstat the file being read, (so it would work with stdin redirected from a file, but would not work with stdin as a tty). The stat was so that glcpp could allocate a buffer for the file content in a single call. We now use talloc_realloc instead, (even if the fstat is possible). This is theoretically less efficient, but quite irrelevant, (particularly because the standalone preprocessor is used only for testing). --- src/glsl/glcpp/glcpp.c | 82 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 33 deletions(-) (limited to 'src/glsl/glcpp/glcpp.c') diff --git a/src/glsl/glcpp/glcpp.c b/src/glsl/glcpp/glcpp.c index 011058a36a..56714936bb 100644 --- a/src/glsl/glcpp/glcpp.c +++ b/src/glsl/glcpp/glcpp.c @@ -31,48 +31,64 @@ extern int yydebug; +/* Read from fd until EOF and return a string of everything read. + */ static char * -load_text_file(void *ctx, const char *file_name) +load_text_fd (void *ctx, int fd) { +#define CHUNK 4096 char *text = NULL; - struct stat st; + ssize_t text_size = 0; ssize_t total_read = 0; - int fd; + ssize_t bytes; + + while (1) { + if (total_read + CHUNK + 1 > text_size) { + text_size = text_size ? text_size * 2 : CHUNK + 1; + text = talloc_realloc_size (ctx, text, text_size); + if (text == NULL) { + fprintf (stderr, "Out of memory\n"); + return NULL; + } + } + bytes = read (fd, text + total_read, CHUNK); + if (bytes < 0) { + fprintf (stderr, "Error while reading: %s\n", + strerror (errno)); + talloc_free (text); + return NULL; + } - if (file_name == NULL || strcmp(file_name, "-") == 0) { - fd = STDIN_FILENO; - } else { - fd = open (file_name, O_RDONLY); + if (bytes == 0) { + break; + } - if (fd < 0) { - fprintf (stderr, "Failed to open file %s: %s\n", - file_name, strerror (errno)); - return NULL; - } + total_read += bytes; } - if (fstat(fd, & st) == 0) { - text = (char *) talloc_size(ctx, st.st_size + 1); - if (text != NULL) { - do { - ssize_t bytes = read(fd, text + total_read, - st.st_size - total_read); - if (bytes < 0) { - text = NULL; - break; - } - - if (bytes == 0) { - break; - } - - total_read += bytes; - } while (total_read < st.st_size); - - text[total_read] = '\0'; - } + text[total_read] = '\0'; + + return text; +} + +static char * +load_text_file(void *ctx, const char *filename) +{ + char *text; + int fd; + + if (filename == NULL || strcmp (filename, "-") == 0) + return load_text_fd (ctx, STDIN_FILENO); + + fd = open (filename, O_RDONLY); + if (fd < 0) { + fprintf (stderr, "Failed to open file %s: %s\n", + filename, strerror (errno)); + return NULL; } + text = load_text_fd (ctx, fd); + close(fd); return text; @@ -91,7 +107,7 @@ main (int argc, char *argv[]) filename = argv[1]; } - shader = load_text_file(ctx, filename); + shader = load_text_file (ctx, filename); if (shader == NULL) return 1; -- cgit v1.2.3