ret = yagl_glsl_parse(&shader_obj->state);
if ((ret == 0) && !shader_obj->state.have_error) {
+ struct yagl_glsl_sampler *samplers = NULL;
+ struct yagl_glsl_define *defines = NULL;
+ int i = 0, size = 0;
+
patched_source = yagl_glsl_state_get_output(&shader_obj->state,
&patched_len);
YAGL_LOG_TRACE("patched source = %s", patched_source);
+ YAGL_LOG_DEBUG("extract summary:");
+ YAGL_LOG_DEBUG(" defines extracted from source:");
+ defines = yagl_vector_data(&shader_obj->state.defines);
+ size = yagl_vector_size(&shader_obj->state.defines);
+ for (i = 0; i < size; ++i) {
+ YAGL_LOG_DEBUG(" -> %s => %s", defines[i].name_orig, defines[i].name_new);
+ }
+
+ YAGL_LOG_DEBUG(" samplersExternalOES extracted from source:");
+ samplers = yagl_vector_data(&shader_obj->state.samplers_ExternalOES);
+ size = yagl_vector_size(&shader_obj->state.samplers_ExternalOES);
+ for (i = 0; i < size; ++i) {
+ YAGL_LOG_DEBUG(" -> %s: at %d unit %d", samplers[i].name, samplers[i].location, samplers[i].value);
+ }
+
yagl_gles2_shader_source(shader_obj,
(GLchar*)tmp_buff,
patched_source,
struct yagl_glsl_sampler *samplers = NULL;
int i = 0, samplers_size = 0;
+ YAGL_LOG_DEBUG("samplersExternalOES extracted from source:");
+ samplers = yagl_vector_data(&fragment_shader->state.samplers_ExternalOES);
+ samplers_size = yagl_vector_size(&fragment_shader->state.samplers_ExternalOES);
+ for (i = 0; i < samplers_size; ++i) {
+ YAGL_LOG_DEBUG(" -> %s: at %d unit %d", samplers[i].name, samplers[i].location, samplers[i].value);
+ }
+
ctx->base.have_externaloes_rebinds = 1;
// FIXME for now assume user is always right and there is no error cases.
return TOK_STRING;
}
-<UNIFORM>{WS}+ {
- struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
- yagl_glsl_state_new_pending(state, yytext);
-}
-
-<UNIFORM>"samplerExternalOES" {
+<UNIFORM>{WS}*; {
struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+ BEGIN(INITIAL);
yagl_glsl_state_new_str_token(state, yylval, yytext);
- return TOK_SAMPLEREXTERNALOES;
+ return TOK_EOI;
}
-<UNIFORM>"sampler2D" {
+<UNIFORM>{WS}+ {
struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
- yagl_glsl_state_new_str_token(state, yylval, yytext);
- return TOK_SAMPLER2D;
+ yagl_glsl_state_new_pending(state, yytext);
}
<UNIFORM>{STRING} {
struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
- BEGIN(INITIAL);
yagl_glsl_state_new_str_token(state, yylval, yytext);
return TOK_STRING;
}
yagl_vector_init(&state->strings, sizeof(char*), 0);
yagl_vector_init(&state->samplers_ExternalOES, sizeof(struct yagl_glsl_sampler), 0);
yagl_vector_init(&state->samplers_2D, sizeof(struct yagl_glsl_sampler), 0);
+ yagl_vector_init(&state->defines, sizeof(struct yagl_glsl_define), 0);
return 1;
}
}
%token <str> TOK_EOL
+%token <str> TOK_EOI
%token <str> TOK_VERSION
%token <str> TOK_DEFINE
%token <str> TOK_EXTENSION
%token <str> TOK_ATTRIBUTE
%token <str> TOK_VARYING
%token <str> TOK_UNIFORM
-%token <str> TOK_SAMPLEREXTERNALOES
-%token <str> TOK_SAMPLER2D
%token <str> TOK_TEXTURE1D
%token <str> TOK_TEXTURE1DPROJ
%token <str> TOK_TEXTURE1DLOD
yagl_glsl_state_flush_pending(state, $2.index);
yagl_glsl_state_append_output(state, $2.value);
}
+| 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_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(state, $4.value);
+
+ yagl_glsl_state_add_define(state, $2.value, $3.value);
+}
| TOK_DEFINE
{
yagl_glsl_state_flush_pending(state, $1.index);
yagl_glsl_state_append_output(state, $1.value);
}
}
-| TOK_UNIFORM TOK_STRING
-{
- 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_UNIFORM TOK_SAMPLEREXTERNALOES TOK_STRING
+| TOK_UNIFORM TOK_STRING TOK_STRING TOK_EOI
{
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 (!state->have_samplerexternaloes) {
- yagl_glsl_state_append_header(state, "#define samplerExternalOES sampler2D\n");
- state->have_samplerexternaloes = 1;
- }
+ // 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;
+ yagl_glsl_state_resolve_define(state, $2.value, &type_resolved);
- yagl_glsl_state_add_sampler_ExternalOES(state, $3.value);
-}
-| TOK_UNIFORM TOK_SAMPLER2D TOK_STRING
-{
- 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 (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);
+ }
- yagl_glsl_state_add_sampler_2D(state, $3.value);
+ free(type_resolved);
}
| TOK_TEXTURE1D
{
#include "yagl_state.h"
#include <string.h>
#include <stdio.h>
+#include <assert.h>
static void yagl_glsl_state_flush_version(struct yagl_glsl_state *state)
{
sampler.replaced_tex2d = YAGL_GLSL_SAMPLER_VALUE_UNKNOWN;
yagl_vector_push_back(&state->samplers_2D, &sampler);
}
+
+void yagl_glsl_state_add_define(struct yagl_glsl_state *state,
+ const char *tok_orig, const char *tok_new)
+{
+ struct yagl_glsl_define define;
+ define.name_orig = strdup(tok_orig);
+ define.name_new = strdup(tok_new);
+ yagl_vector_push_back(&state->defines, &define);
+}
+
+void yagl_glsl_state_resolve_define(struct yagl_glsl_state *state,
+ const char *token, char **resolved)
+{
+ struct yagl_glsl_define *defines = yagl_vector_data(&state->defines);
+ int i = 0, defines_size = yagl_vector_size(&state->defines);
+ const char* to_resolve = token;
+ YAGL_LOG_FUNC_SET(yagl_glsl_state_resolve_define);
+
+ assert(resolved != NULL);
+
+ YAGL_LOG_DEBUG("LKDEBUG resolving define %s", to_resolve);
+ while (1) {
+ for (i = 0; i < defines_size; ++i) {
+ if (strcmp(to_resolve, defines[i].name_orig) == 0) {
+ YAGL_LOG_DEBUG(" * %s -> %s", to_resolve, defines[i].name_new);
+ to_resolve = defines[i].name_new;
+ break;
+ }
+ }
+
+ if (i == defines_size)
+ // we went through everything we know and name did not appear
+ // assume this is the end
+ break;
+ }
+
+ *resolved = strdup(to_resolve);
+ YAGL_LOG_DEBUG("resolved as %s", *resolved);
+}
#define YAGL_GLSL_SAMPLER_LOCATION_UNKNOWN (-1)
#define YAGL_GLSL_SAMPLER_VALUE_UNKNOWN (-1)
+struct yagl_glsl_define
+{
+ char* name_orig;
+ char* name_new;
+};
+
struct yagl_glsl_sampler
{
char* name;
// strdup'ed strings.
struct yagl_vector strings;
+ // preprocessor defines
+ struct yagl_vector defines;
+
// names of samplerExternalOES uniforms
struct yagl_vector samplers_ExternalOES;
void yagl_glsl_state_add_sampler_2D(struct yagl_glsl_state *state,
const char *str);
+void yagl_glsl_state_add_define(struct yagl_glsl_state *state,
+ const char *tok_orig, const char *tok_new);
+
+void yagl_glsl_state_resolve_define(struct yagl_glsl_state *state,
+ const char *token, char **resolved);
+
int yagl_glsl_parse(struct yagl_glsl_state *state);
#endif