summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukasz Kostyra <l.kostyra@samsung.com>2020-12-29 12:08:05 +0100
committerLukasz Kostyra <l.kostyra@samsung.com>2021-01-07 17:40:54 +0100
commit2c7783b1fef54254001594636906eb27baeebd2e (patch)
treef6f019e391f4e654935420ec498cf725f327c59f
parent680bb1745b92ed22b4325f170f338cf21e63f507 (diff)
downloademulator-yagl-2c7783b1fef54254001594636906eb27baeebd2e.tar.gz
emulator-yagl-2c7783b1fef54254001594636906eb27baeebd2e.tar.bz2
emulator-yagl-2c7783b1fef54254001594636906eb27baeebd2e.zip
Parse GLSL #define preprocessor macros
GLSL lexer/parser now handles #define macros in order to properly discover samplerExternalOES/sampler2D type. Change-Id: I77f01bb722d31f980bf8a1d6b00a717c108a15b0
-rw-r--r--GLESv2/yagl_gles2_calls.c19
-rw-r--r--GLESv2/yagl_gles2_context.c7
-rw-r--r--GLESv2/yagl_glsl_lexer.l17
-rw-r--r--GLESv2/yagl_glsl_parser.y57
-rw-r--r--GLESv2/yagl_glsl_state.c40
-rw-r--r--GLESv2/yagl_glsl_state.h15
6 files changed, 119 insertions, 36 deletions
diff --git a/GLESv2/yagl_gles2_calls.c b/GLESv2/yagl_gles2_calls.c
index fec51f5..029a680 100644
--- a/GLESv2/yagl_gles2_calls.c
+++ b/GLESv2/yagl_gles2_calls.c
@@ -1438,11 +1438,30 @@ YAGL_API void glShaderSource(GLuint shader, GLsizei count, const GLchar * const
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,
diff --git a/GLESv2/yagl_gles2_context.c b/GLESv2/yagl_gles2_context.c
index b3018e2..928d900 100644
--- a/GLESv2/yagl_gles2_context.c
+++ b/GLESv2/yagl_gles2_context.c
@@ -641,6 +641,13 @@ void yagl_gles2_context_pre_draw(struct yagl_gles2_context *ctx,
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.
diff --git a/GLESv2/yagl_glsl_lexer.l b/GLESv2/yagl_glsl_lexer.l
index 84be821..8ec6599 100644
--- a/GLESv2/yagl_glsl_lexer.l
+++ b/GLESv2/yagl_glsl_lexer.l
@@ -264,26 +264,20 @@ STRING [^ \r\t\v\f\n()\[\]{},;?:/%*&|^!+\-=<>\.]+
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;
}
@@ -365,6 +359,7 @@ int yagl_glsl_state_init(struct yagl_glsl_state *state,
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;
}
diff --git a/GLESv2/yagl_glsl_parser.y b/GLESv2/yagl_glsl_parser.y
index d42aafb..d6ae2b1 100644
--- a/GLESv2/yagl_glsl_parser.y
+++ b/GLESv2/yagl_glsl_parser.y
@@ -41,6 +41,7 @@ static int yagl_glsl_lex(union YYSTYPE *val, struct yagl_glsl_state *state)
}
%token <str> TOK_EOL
+%token <str> TOK_EOI
%token <str> TOK_VERSION
%token <str> TOK_DEFINE
%token <str> TOK_EXTENSION
@@ -55,8 +56,6 @@ static int yagl_glsl_lex(union YYSTYPE *val, struct yagl_glsl_state *state)
%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
@@ -187,6 +186,19 @@ expression
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);
@@ -330,14 +342,7 @@ expression
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);
@@ -345,24 +350,26 @@ expression
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
{
diff --git a/GLESv2/yagl_glsl_state.c b/GLESv2/yagl_glsl_state.c
index c1c3a5d..ee7f33f 100644
--- a/GLESv2/yagl_glsl_state.c
+++ b/GLESv2/yagl_glsl_state.c
@@ -38,6 +38,7 @@
#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)
{
@@ -324,3 +325,42 @@ void yagl_glsl_state_add_sampler_2D(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);
+}
diff --git a/GLESv2/yagl_glsl_state.h b/GLESv2/yagl_glsl_state.h
index 2f9184f..4091339 100644
--- a/GLESv2/yagl_glsl_state.h
+++ b/GLESv2/yagl_glsl_state.h
@@ -52,6 +52,12 @@ struct yagl_glsl_pending
#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;
@@ -134,6 +140,9 @@ struct yagl_glsl_state
// strdup'ed strings.
struct yagl_vector strings;
+ // preprocessor defines
+ struct yagl_vector defines;
+
// names of samplerExternalOES uniforms
struct yagl_vector samplers_ExternalOES;
@@ -196,6 +205,12 @@ void yagl_glsl_state_add_sampler_ExternalOES(struct yagl_glsl_state *state,
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