link_directories(${CMAKE_ARCHIVE_OUTPUT_DIRECTORY})
flex_target(GLESv2 ${CMAKE_CURRENT_SOURCE_DIR}/yagl_glsl_lexer.l ${CMAKE_CURRENT_BINARY_DIR}/yagl_glsl_lexer.c)
-bison_target(GLESv2 ${CMAKE_CURRENT_SOURCE_DIR}/yagl_glsl_parser.y ${CMAKE_CURRENT_BINARY_DIR}/yagl_glsl_parser.c)
+bison_target(GLESv2 ${CMAKE_CURRENT_SOURCE_DIR}/yagl_glsl_parser.y ${CMAKE_CURRENT_BINARY_DIR}/yagl_glsl_parser.c
+ VERBOSE)
add_library(GLESv2 SHARED ${SOURCES} ${FLEX_GLESv2_OUTPUTS} ${BISON_GLESv2_OUTPUTS})
set_target_properties(GLESv2 PROPERTIES VERSION 2.0 SOVERSION 2)
if (have_strings) {
uint8_t *tmp_buff;
+ char *print_buff; // LKDEBUG
int ret;
int patched_len = 0;
char *patched_source;
tmp_buff[total_length] = '\0';
- YAGL_LOG_TRACE("orig source = %s", tmp_buff);
+ YAGL_LOG_DEBUG("orig source:", tmp_buff);
+ print_buff = (char*)tmp_buff;
+ while (print_buff)
+ {
+ char *next_line = strchr(print_buff, '\n');
+ if (next_line) *next_line = 0;
+ YAGL_LOG_DEBUG("%s", print_buff);
+ if (next_line) *next_line = '\n';
+ print_buff = next_line ? next_line + 1 : NULL;
+ }
yagl_glsl_state_init(&shader_obj->state,
shader_obj->type,
patched_source = yagl_glsl_state_get_output(&shader_obj->state,
&patched_len);
- YAGL_LOG_TRACE("patched source = %s", patched_source);
+ YAGL_LOG_DEBUG("patched source:");
+ print_buff = patched_source;
+ while (print_buff)
+ {
+ char *next_line = strchr(print_buff, '\n');
+ if (next_line) *next_line = 0;
+ YAGL_LOG_DEBUG("%s", print_buff);
+ if (next_line) *next_line = '\n';
+ print_buff = next_line ? next_line + 1 : NULL;
+ }
YAGL_LOG_TRACE("Macro and sampler extract summary:");
YAGL_LOG_TRACE(" Macros:");
/*
* Unable to parse source, pass as-is.
*/
- YAGL_LOG_TRACE("unable to patch shader source, passed as-is");
+ YAGL_LOG_DEBUG("unable to patch shader source, passed as-is");
yagl_gles2_shader_source(shader_obj,
(GLchar*)tmp_buff,
(GLchar*)tmp_buff,
%option prefix="yagl_glsl_lexer_"
%option extra-type="struct yagl_glsl_state *"
-%x COMMENT PP PP_IFDEF PP_IF PP_DEFINE PP_UNDEF UNIFORM PRECISION
+%x COMMENT PP_VERSION PP_IFDEF PP_IF PP_DEFINE PP_UNDEF UNIFORM PRECISION
WS [ \r\t\v\f]
PRECISION_QUAL "lowp"|"mediump"|"highp"
^{WS}*#{WS}*version {
struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
- BEGIN(PP);
+ BEGIN(PP_VERSION);
yagl_glsl_state_new_str_token(state, yylval, yytext);
return TOK_VERSION;
}
return TOK_TEXTURE2D;
}
-<PP>"texture2D" {
- struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
- yagl_glsl_state_new_str_token(state, yylval, yytext);
- return TOK_TEXTURE2D;
-}
-
"texture3DProjLod" {
struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
yagl_glsl_state_new_str_token(state, yylval, yytext);
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);
yagl_glsl_state_new_pending(state, yytext);
}
-<PP>\n {
+<PP_VERSION>\n {
struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
BEGIN(INITIAL);
yagl_glsl_state_new_str_token(state, yylval, yytext);
return TOK_EOL;
}
-<PP>{WS}+ {
+<PP_VERSION>{WS}+ {
struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
yagl_glsl_state_new_pending(state, yytext);
}
-<PP>[1-9][0-9]* {
+<PP_VERSION>[1-9][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;
}
-<PP>"es" {
+<PP_VERSION>"es" {
struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
yagl_glsl_state_new_str_token(state, yylval, yytext);
return TOK_ES;
}
-<PP>{PRECISION_ALL} {
- struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
- yagl_glsl_state_new_str_token(state, yylval, yytext);
- return TOK_PRECISION_ALL;
-}
-
-<PP>{CONTROL} {
+<PP_VERSION>{CONTROL} {
struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
yagl_glsl_state_new_str_token(state, yylval, yytext);
return TOK_STRING;
}
-<PP>{STRING} {
+<PP_VERSION>{STRING} {
struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
yagl_glsl_state_new_str_token(state, yylval, yytext);
return TOK_STRING;
yagl_glsl_state_new_comment(state, strlen(yytext));
}
-<PP_DEFINE>[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;
-}
-
<PP_DEFINE>{STRING} {
struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
yagl_glsl_state_new_str_token(state, yylval, yytext);
#include <GL/gl.h>
#include "yagl_glsl_state.h"
#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
#include <string.h>
#undef yyerror
%}
%pure-parser
-%name-prefix="yagl_glsl_"
+%name-prefix "yagl_glsl_"
%lex-param {struct yagl_glsl_state *state}
%parse-param {struct yagl_glsl_state *state}
%debug
%token <str> TOK_ES
%token <str> TOK_PRECISION
%token <str> TOK_PRECISION_QUAL
-%token <str> TOK_PRECISION_ALL
%token <str> TOK_MAXVERTEXUNIFORMVECTORS
%token <str> TOK_MAXFRAGMENTUNIFORMVECTORS
%token <str> TOK_MAXVARYINGVECTORS
yagl_glsl_state_flush_pending(state, $1.index);
yagl_glsl_state_append_output(state, $1.value);
}
-| TOK_DEFINE TOK_PRECISION_ALL
-{
- 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);
-}
-| TOK_DEFINE TOK_STRING TOK_STRING
+| TOK_DEFINE TOK_STRING TOK_STRING TOK_EOL
{
yagl_glsl_state_flush_pending(state, $1.index);
yagl_glsl_state_append_output(state, $1.value);
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(state, $4.value);
- if (yagl_glsl_state_pp_is_condition_met(state))
- yagl_glsl_state_pp_add_define_string(state, $2.value, $3.value);
-}
-| TOK_DEFINE TOK_STRING TOK_INTEGER
-{
- 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);
- sprintf(s, "%d", $3.value);
- yagl_glsl_state_append_output(state, s);
+ if (yagl_glsl_state_pp_is_condition_met(state)) {
+ // Determine if $3 is actually a string or an integer.
+ // We do this here because some shaders could use defines to
+ // place in different types of numbers (ex. floats like PI constant).
+ // However, for preprocessor condition resolution we only care about
+ // integers according to GLSL ES specification.
+ int isint = 1;
+ const char *str = $3.value;
+ while (str) {
+ if (!isdigit(*str) && (*str != '-') && (*str != '+')) {
+ isint = 0;
+ }
+ str++;
+ }
- if (yagl_glsl_state_pp_is_condition_met(state))
- yagl_glsl_state_pp_add_define_int(state, $2.value, $3.value);
+ if (isint) {
+ yagl_glsl_state_pp_add_define_int(state, $2.value, atoi($3.value));
+ } else {
+ yagl_glsl_state_pp_add_define_string(state, $2.value, $3.value);
+ }
+ }
}
-| TOK_DEFINE TOK_STRING
+| TOK_DEFINE TOK_STRING TOK_EOL
{
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);
if (yagl_glsl_state_pp_is_condition_met(state))
yagl_glsl_state_pp_add_define_int(state, $2.value, 1);
if (yagl_glsl_state_pp_is_condition_met(state))
yagl_glsl_state_pp_undef(state, $2.value);
}
-| TOK_DEFINE
-{
- yagl_glsl_state_flush_pending(state, $1.index);
- yagl_glsl_state_append_output(state, $1.value);
-}
| TOK_PP_IF
{
yagl_glsl_state_flush_pending(state, $1.index);
yagl_glsl_state_append_output(state, $2.value);
}
}
+| TOK_PRECISION_QUAL
+{
+ yagl_glsl_state_flush_pending(state, $1.index);
+ if (!state->patch_precision) {
+ yagl_glsl_state_append_output(state, $1.value);
+ }
+
+}
| TOK_ES
{
yagl_glsl_state_flush_pending(state, $1.index);