diff options
author | Lukasz Kostyra <l.kostyra@samsung.com> | 2021-01-22 17:12:16 +0100 |
---|---|---|
committer | Lukasz Kostyra <l.kostyra@samsung.com> | 2021-01-22 17:21:17 +0100 |
commit | c9e7befe1af5d776226e635e8e6af204aa1349ac (patch) | |
tree | ed76401b83a3866128c521112a6f515ae63225fe | |
parent | fc6b56c5fb1ed811faf62c89689aa9ac4a813de9 (diff) | |
download | emulator-yagl-c9e7befe1af5d776226e635e8e6af204aa1349ac.tar.gz emulator-yagl-c9e7befe1af5d776226e635e8e6af204aa1349ac.tar.bz2 emulator-yagl-c9e7befe1af5d776226e635e8e6af204aa1349ac.zip |
Keep sampler information with Program object & cleanupsubmit/tizen_6.0/20210125.002404submit/tizen/20210125.002716accepted/tizen/unified/20210125.073655
GL/GLES specification allows (and recommends) following sequence of
events:
glAttachShader(); glAttachShader();
glLinkProgram();
glDetachShader(); glDetachShader();
glDeleteShader(); glDeleteShader();
This makes program->vertex_shader and program->fragment_shader NULL
and forgoes any information regarding sampler types, which was used
for pre/post draw calls and TEXTURE_EXTERNAL_OES support. This
information is now cached in program object and all further actions
related to them refer to these cached copies.
Additional:
* Assume sampler uniform value to be 0 (as per GLES spec)
* Adjust some logging and cleanup code
* glTexParameter* functions are now recognizing TEXTURE_EXTERNAL_OES
target and react accordingly
* glGetActiveUniform() returns correct type of uniform to user if
uniform type is samplerExternalOES
Change-Id: Ib5f35730dd9f2f0139780a735ea8ec4f7ba84609
-rw-r--r-- | GLES_common/yagl_gles_calls.c | 22 | ||||
-rw-r--r-- | GLES_common/yagl_gles_context.c | 45 | ||||
-rw-r--r-- | GLESv2/yagl_gles2_context.c | 48 | ||||
-rw-r--r-- | GLESv2/yagl_gles2_program.c | 159 | ||||
-rw-r--r-- | GLESv2/yagl_gles2_program.h | 13 | ||||
-rw-r--r-- | GLESv2/yagl_glsl_state.c | 4 |
6 files changed, 238 insertions, 53 deletions
diff --git a/GLES_common/yagl_gles_calls.c b/GLES_common/yagl_gles_calls.c index 69de0c3..6181ff9 100644 --- a/GLES_common/yagl_gles_calls.c +++ b/GLES_common/yagl_gles_calls.c @@ -306,7 +306,16 @@ YAGL_API void glTexParameteri(GLenum target, GLenum pname, GLint param) tex_target_state->texture->mag_filter = param; } - yagl_host_glTexParameteri(target, pname, param); + if (target == GL_TEXTURE_EXTERNAL_OES) { + struct yagl_gles_texture_target_state *tex2d_target_state = + yagl_gles_context_get_active_texture_target_state(ctx, yagl_gles_texture_target_2d); + + yagl_host_glBindTexture(GL_TEXTURE_2D, tex_target_state->texture->global_name); + yagl_host_glTexParameteri(GL_TEXTURE_2D, pname, param); + yagl_host_glBindTexture(GL_TEXTURE_2D, tex2d_target_state->texture->global_name); + } else { + yagl_host_glTexParameteri(target, pname, param); + } out: YAGL_LOG_FUNC_EXIT(NULL); @@ -337,7 +346,16 @@ YAGL_API void glTexParameteriv(GLenum target, GLenum pname, const GLint *params) tex_target_state->texture->mag_filter = params[0]; } - yagl_host_glTexParameteriv(target, pname, params, 1); + if (target == GL_TEXTURE_EXTERNAL_OES) { + struct yagl_gles_texture_target_state *tex2d_target_state = + yagl_gles_context_get_active_texture_target_state(ctx, yagl_gles_texture_target_2d); + + yagl_host_glBindTexture(GL_TEXTURE_2D, tex_target_state->texture->global_name); + yagl_host_glTexParameteriv(GL_TEXTURE_2D, pname, params, 1); + yagl_host_glBindTexture(GL_TEXTURE_2D, tex2d_target_state->texture->global_name); + } else { + yagl_host_glTexParameteriv(target, pname, params, 1); + } out: YAGL_LOG_FUNC_EXIT(NULL); diff --git a/GLES_common/yagl_gles_context.c b/GLES_common/yagl_gles_context.c index 8c23e66..b57d949 100644 --- a/GLES_common/yagl_gles_context.c +++ b/GLES_common/yagl_gles_context.c @@ -2341,7 +2341,16 @@ void yagl_gles_context_tex_parameterf(struct yagl_gles_context *ctx, tex_target_state->texture->mag_filter = param; } - yagl_host_glTexParameterf(target, pname, param); + if (target == GL_TEXTURE_EXTERNAL_OES) { + struct yagl_gles_texture_target_state *tex2d_target_state = + yagl_gles_context_get_active_texture_target_state(ctx, yagl_gles_texture_target_2d); + + yagl_host_glBindTexture(GL_TEXTURE_2D, tex_target_state->texture->global_name); + yagl_host_glTexParameterf(GL_TEXTURE_2D, pname, param); + yagl_host_glBindTexture(GL_TEXTURE_2D, tex2d_target_state->texture->global_name); + } else { + yagl_host_glTexParameterf(target, pname, param); + } } void yagl_gles_context_tex_parameterfv(struct yagl_gles_context *ctx, @@ -2370,7 +2379,17 @@ void yagl_gles_context_tex_parameterfv(struct yagl_gles_context *ctx, tex_target_state->texture->mag_filter = params[0]; } - yagl_host_glTexParameterfv(target, pname, params, 1); + if (target == GL_TEXTURE_EXTERNAL_OES) { + struct yagl_gles_texture_target_state *tex2d_target_state = + yagl_gles_context_get_active_texture_target_state(ctx, yagl_gles_texture_target_2d); + + yagl_host_glBindTexture(GL_TEXTURE_2D, tex_target_state->texture->global_name); + yagl_host_glTexParameterfv(GL_TEXTURE_2D, pname, params, 1); + yagl_host_glBindTexture(GL_TEXTURE_2D, tex2d_target_state->texture->global_name); + } else { + yagl_host_glTexParameterfv(target, pname, params, 1); + } + } int yagl_gles_context_get_tex_parameterfv(struct yagl_gles_context *ctx, @@ -2399,7 +2418,16 @@ int yagl_gles_context_get_tex_parameterfv(struct yagl_gles_context *ctx, break; } - yagl_host_glGetTexParameterfv(target, pname, params); + if (target == GL_TEXTURE_EXTERNAL_OES) { + struct yagl_gles_texture_target_state *tex2d_target_state = + yagl_gles_context_get_active_texture_target_state(ctx, yagl_gles_texture_target_2d); + + yagl_host_glBindTexture(GL_TEXTURE_2D, texture_obj->global_name); + yagl_host_glGetTexParameterfv(GL_TEXTURE_2D, pname, params); + yagl_host_glBindTexture(GL_TEXTURE_2D, tex2d_target_state->texture->global_name); + } else { + yagl_host_glGetTexParameterfv(target, pname, params); + } return 1; } @@ -2430,7 +2458,16 @@ int yagl_gles_context_get_tex_parameteriv(struct yagl_gles_context *ctx, break; } - yagl_host_glGetTexParameteriv(target, pname, params); + if (target == GL_TEXTURE_EXTERNAL_OES) { + struct yagl_gles_texture_target_state *tex2d_target_state = + yagl_gles_context_get_active_texture_target_state(ctx, yagl_gles_texture_target_2d); + + yagl_host_glBindTexture(GL_TEXTURE_2D, texture_obj->global_name); + yagl_host_glGetTexParameteriv(GL_TEXTURE_2D, pname, params); + yagl_host_glBindTexture(GL_TEXTURE_2D, tex2d_target_state->texture->global_name); + } else { + yagl_host_glGetTexParameteriv(target, pname, params); + } return 1; } diff --git a/GLESv2/yagl_gles2_context.c b/GLESv2/yagl_gles2_context.c index 64fedad..2959308 100644 --- a/GLESv2/yagl_gles2_context.c +++ b/GLESv2/yagl_gles2_context.c @@ -474,19 +474,19 @@ struct yagl_gles_array } static void yagl_gles2_context_bind_externaloes(struct yagl_gles2_context *ctx, - struct yagl_gles2_shader *shader) + struct yagl_gles2_program_sampler_info *sampler_info) { struct yagl_glsl_sampler *samplers; int i = 0, samplers_size = 0; YAGL_LOG_FUNC_SET(yagl_gles2_context_bind_externaloes); - YAGL_LOG_DEBUG("Binding samplerExternalOES units into GL_TEXTURE_2D slots:"); + YAGL_LOG_TRACE("Binding samplerExternalOES units into GL_TEXTURE_2D slots:"); // FIXME for now assume user is always right and there is no error cases. // Errors to consider: // * samplerExternalOES and sampler2D attempting to access same unit // * samplerExternalOES points at unit having no texture bound - samplers = yagl_vector_data(&shader->state.samplers_ExternalOES); - samplers_size = yagl_vector_size(&shader->state.samplers_ExternalOES); + samplers = yagl_vector_data(&sampler_info->samplers_ExternalOES); + samplers_size = yagl_vector_size(&sampler_info->samplers_ExternalOES); for (i = 0; i < samplers_size; ++i) { struct yagl_gles_texture_target_state *texture_2d_state, *texture_external_state; @@ -500,22 +500,14 @@ static void yagl_gles2_context_bind_externaloes(struct yagl_gles2_context *ctx, //continue; // TODO error GL_INVALID_OPERATION? } - if (samplers[i].location == YAGL_GLSL_SAMPLER_LOCATION_UNKNOWN || - samplers[i].value == YAGL_GLSL_SAMPLER_VALUE_UNKNOWN) { - YAGL_LOG_WARN(" #%d: Unknown location/value of uniform %s - skipping", i, samplers[i].name); - continue; - } - // we could have currently bound either an actual texture 2d or a "zero texture" (for binding = 0) // store whatever is bound from cached info, we'll restore it post-draw if (texture_2d_state->texture != texture_2d_state->texture_zero) { samplers[i].replaced_tex2d = texture_2d_state->texture->global_name; - YAGL_LOG_DEBUG(" -> Binding in place of existing texture"); } else { samplers[i].replaced_tex2d = texture_2d_state->texture_zero->global_name; - YAGL_LOG_DEBUG(" -> Binding in place of zero texture"); } - YAGL_LOG_DEBUG(" #%d: slot %d texture2D %d => textureExternal %d", i, samplers[i].value, samplers[i].replaced_tex2d, + YAGL_LOG_TRACE(" #%d: slot %d texture2D %d => textureExternal %d", i, samplers[i].value, samplers[i].replaced_tex2d, texture_external_state->texture->global_name); // samplers[i].value is unit requested by app from shader - replace it @@ -524,22 +516,22 @@ static void yagl_gles2_context_bind_externaloes(struct yagl_gles2_context *ctx, } } -static void yagl_gles2_context_restore_externaloes_binds(struct yagl_gles2_shader *shader) +static void yagl_gles2_context_restore_externaloes_binds(struct yagl_gles2_program_sampler_info *sampler_info) { struct yagl_glsl_sampler *samplers; int i = 0, samplers_size = 0; YAGL_LOG_FUNC_SET(yagl_gles2_context_restore_externaloes_binds); - YAGL_LOG_DEBUG("Restoring TEXTURE_2D bindings:"); - samplers = yagl_vector_data(&shader->state.samplers_ExternalOES); - samplers_size = yagl_vector_size(&shader->state.samplers_ExternalOES); + YAGL_LOG_TRACE("Restoring TEXTURE_2D bindings:"); + samplers = yagl_vector_data(&sampler_info->samplers_ExternalOES); + samplers_size = yagl_vector_size(&sampler_info->samplers_ExternalOES); for (i = 0; i < samplers_size; ++i) { if (samplers[i].location == YAGL_GLSL_SAMPLER_LOCATION_UNKNOWN || samplers[i].value == YAGL_GLSL_SAMPLER_VALUE_UNKNOWN) { continue; } - YAGL_LOG_DEBUG(" #%d: %d unit => %d texture", i, samplers[i].value, samplers[i].replaced_tex2d); + YAGL_LOG_TRACE(" #%d: %d unit => %d texture", i, samplers[i].value, samplers[i].replaced_tex2d); yagl_host_glActiveTexture(GL_TEXTURE0 + samplers[i].value); yagl_host_glBindTexture(GL_TEXTURE_2D, samplers[i].replaced_tex2d); samplers[i].replaced_tex2d = YAGL_GLSL_SAMPLER_VALUE_UNKNOWN; @@ -709,18 +701,18 @@ void yagl_gles2_context_pre_draw(struct yagl_gles2_context *ctx, * Check for currently bound shaders if any samplers are of samplerExternalOES type. * If they are, do some extra checks and bind some textures temporarily. */ - struct yagl_gles2_shader *vertex_shader = ctx->program->vertex_shader; - if (vertex_shader && vertex_shader->state.have_samplerexternaloes) { + if (ctx->program->vertex_shader_sampler_info.fetched && + ctx->program->vertex_shader_sampler_info.have_samplerexternaloes) { ctx->have_externaloes_rebinds_vs = 1; - YAGL_LOG_DEBUG("======= Vertex shader has samplerExternalOES ========"); - yagl_gles2_context_bind_externaloes(ctx, vertex_shader); + YAGL_LOG_TRACE("======= Vertex shader has samplerExternalOES ========"); + yagl_gles2_context_bind_externaloes(ctx, &ctx->program->vertex_shader_sampler_info); } - struct yagl_gles2_shader *fragment_shader = ctx->program->fragment_shader; - if (fragment_shader && fragment_shader->state.have_samplerexternaloes) { + if (ctx->program->fragment_shader_sampler_info.fetched && + ctx->program->fragment_shader_sampler_info.have_samplerexternaloes) { ctx->have_externaloes_rebinds_fs = 1; - YAGL_LOG_DEBUG("======= Fragment shader has samplerExternalOES ========"); - yagl_gles2_context_bind_externaloes(ctx, fragment_shader); + YAGL_LOG_TRACE("======= Fragment shader has samplerExternalOES ========"); + yagl_gles2_context_bind_externaloes(ctx, &ctx->program->fragment_shader_sampler_info); } } @@ -758,11 +750,11 @@ void yagl_gles2_context_post_draw(struct yagl_gles2_context *ctx, * Restore original TEXTURE_2D bindings */ if (ctx->have_externaloes_rebinds_vs) { - yagl_gles2_context_restore_externaloes_binds(ctx->program->vertex_shader); + yagl_gles2_context_restore_externaloes_binds(&ctx->program->vertex_shader_sampler_info); } if (ctx->have_externaloes_rebinds_fs) { - yagl_gles2_context_restore_externaloes_binds(ctx->program->fragment_shader); + yagl_gles2_context_restore_externaloes_binds(&ctx->program->fragment_shader_sampler_info); } /* diff --git a/GLESv2/yagl_gles2_program.c b/GLESv2/yagl_gles2_program.c index 9fe3966..1d0c343 100644 --- a/GLESv2/yagl_gles2_program.c +++ b/GLESv2/yagl_gles2_program.c @@ -41,6 +41,7 @@ #include "yagl_log.h" #include "yagl_utils.h" #include "yagl_host_gles_calls.h" +#include "yagl_glsl_state.h" #include <string.h> #include <stdlib.h> #include <pthread.h> @@ -50,6 +51,11 @@ */ #define GL_INTERLEAVED_ATTRIBS 0x8C8C +/* + * GL_OES_EGL_image_external extension + */ +#define GL_SAMPLER_EXTERNAL_OES 0x8D66 + struct yagl_gles2_location_v { GLchar *name; @@ -110,6 +116,88 @@ static void yagl_gles2_transform_feedback_info_copy( } } +static void yagl_gles2_program_sampler_info_copy_from_shader(struct yagl_gles2_program_sampler_info *info, + struct yagl_gles2_shader *shader) +{ + struct yagl_glsl_sampler *samplers_src; + int i = 0, samplers_size = 0; + YAGL_LOG_FUNC_SET(yagl_gles2_program_sampler_info_copy_from_shader); + + if (!shader) { + YAGL_LOG_TRACE("No shader info available for copy"); + return; + } + + if (shader->state.have_error) { + YAGL_LOG_TRACE("Shader's GLSL state is invalid/has error"); + return; + } + + info->have_samplerexternaloes = shader->state.have_samplerexternaloes; + + samplers_size = yagl_vector_size(&shader->state.samplers_ExternalOES); + samplers_src = yagl_vector_data(&shader->state.samplers_ExternalOES); + + yagl_vector_init(&info->samplers_ExternalOES, sizeof(struct yagl_glsl_sampler), samplers_size); + + for (i = 0; i < samplers_size; ++i) { + struct yagl_glsl_sampler s; + s.name = strdup(samplers_src[i].name); + s.location = samplers_src[i].location; + s.replaced_tex2d = samplers_src[i].replaced_tex2d; + s.value = samplers_src[i].value; + + yagl_vector_push_back(&info->samplers_ExternalOES, &s); + } + + samplers_size = yagl_vector_size(&shader->state.samplers_2D); + samplers_src = yagl_vector_data(&shader->state.samplers_2D); + + yagl_vector_init(&info->samplers_2D, sizeof(struct yagl_glsl_sampler), samplers_size); + + for (i = 0; i < samplers_size; ++i) { + struct yagl_glsl_sampler s; + s.name = strdup(samplers_src[i].name); + s.location = samplers_src[i].location; + s.replaced_tex2d = samplers_src[i].replaced_tex2d; + s.value = samplers_src[i].value; + + yagl_vector_push_back(&info->samplers_2D, &s); + } + + info->fetched = 1; +} + +static void yagl_gles2_program_sampler_info_init(struct yagl_gles2_program_sampler_info *info) +{ + info->fetched = 0; + info->have_samplerexternaloes = 0; +} + +static void yagl_gles2_program_sampler_info_reset(struct yagl_gles2_program_sampler_info *info) +{ + struct yagl_glsl_sampler *samplers; + int i = 0, samplers_size = 0; + + info->fetched = 0; + info->have_samplerexternaloes = 0; + + samplers_size = yagl_vector_size(&info->samplers_ExternalOES); + samplers = yagl_vector_data(&info->samplers_ExternalOES); + for (i = 0; i < samplers_size; ++i) { + yagl_free(samplers[i].name); + } + + samplers_size = yagl_vector_size(&info->samplers_2D); + samplers = yagl_vector_data(&info->samplers_2D); + for (i = 0; i < samplers_size; ++i) { + yagl_free(samplers[i].name); + } + + yagl_vector_cleanup(&info->samplers_ExternalOES); + yagl_vector_cleanup(&info->samplers_2D); +} + static void yagl_gles2_program_reset_cached(struct yagl_gles2_program *program) { int i; @@ -177,6 +265,9 @@ static void yagl_gles2_program_reset_cached(struct yagl_gles2_program *program) yagl_free(location_l); } } + + yagl_gles2_program_sampler_info_reset(&program->vertex_shader_sampler_info); + yagl_gles2_program_sampler_info_reset(&program->fragment_shader_sampler_info); } static void yagl_gles2_program_destroy(struct yagl_ref *ref) @@ -262,6 +353,9 @@ struct yagl_gles2_program *yagl_gles2_program_create(int gen_locations) program->transform_feedback_info.buffer_mode = GL_INTERLEAVED_ATTRIBS; + yagl_gles2_program_sampler_info_init(&program->vertex_shader_sampler_info); + yagl_gles2_program_sampler_info_init(&program->fragment_shader_sampler_info); + yagl_host_glCreateProgram(program->global_name); return program; @@ -356,6 +450,15 @@ void yagl_gles2_program_link(struct yagl_gles2_program *program) yagl_gles2_transform_feedback_info_copy( &program->transform_feedback_info, &program->linked_transform_feedback_info); + + /* + * There is a possibility (and even a GLES spec recommendation) to call + * glDetachShader/glDeleteShader after this call. Thus, program->vertex_shader + * and program->fragment_shader pointers become NULL and we could have no access + * to shader info. Copy necessary for us info to program-local space for further use. + */ + yagl_gles2_program_sampler_info_copy_from_shader(&program->vertex_shader_sampler_info, program->vertex_shader); + yagl_gles2_program_sampler_info_copy_from_shader(&program->fragment_shader_sampler_info, program->fragment_shader); } int yagl_gles2_program_get_uniform_location(struct yagl_gles2_program *program, @@ -417,13 +520,13 @@ int yagl_gles2_program_get_uniform_location(struct yagl_gles2_program *program, * Luckily, uniform location does not change so it has to be done * only once. */ - if (program->vertex_shader && - program->vertex_shader->state.have_samplerexternaloes) { + if (program->vertex_shader_sampler_info.fetched && + program->vertex_shader_sampler_info.have_samplerexternaloes) { struct yagl_glsl_sampler *data = NULL; int i = 0, data_size = 0; - data = yagl_vector_data(&program->vertex_shader->state.samplers_ExternalOES); - data_size = yagl_vector_size(&program->vertex_shader->state.samplers_ExternalOES); + data = yagl_vector_data(&program->vertex_shader_sampler_info.samplers_ExternalOES); + data_size = yagl_vector_size(&program->vertex_shader_sampler_info.samplers_ExternalOES); for (i = 0; i < data_size; ++i) { if (strcmp(data[i].name, name) == 0) { data[i].location = ret; @@ -432,13 +535,13 @@ int yagl_gles2_program_get_uniform_location(struct yagl_gles2_program *program, } } - if (program->fragment_shader && - program->fragment_shader->state.have_samplerexternaloes) { + if (program->fragment_shader_sampler_info.fetched && + program->fragment_shader_sampler_info.have_samplerexternaloes) { struct yagl_glsl_sampler *data = NULL; int i = 0, data_size = 0; - data = yagl_vector_data(&program->fragment_shader->state.samplers_ExternalOES); - data_size = yagl_vector_size(&program->fragment_shader->state.samplers_ExternalOES); + data = yagl_vector_data(&program->fragment_shader_sampler_info.samplers_ExternalOES); + data_size = yagl_vector_size(&program->fragment_shader_sampler_info.samplers_ExternalOES); for (i = 0; i < data_size; ++i) { if (strcmp(data[i].name, name) == 0) { data[i].location = ret; @@ -500,7 +603,7 @@ void yagl_gles2_program_get_active_uniform(struct yagl_gles2_program *program, if (!var->generic_fetched) { yagl_free(var->name); - var->name = yagl_malloc(program->max_active_uniform_bufsize); + var->name = yagl_malloc(program->max_active_uniform_bufsize + 1); var->name[0] = '\0'; yagl_host_glGetActiveUniform(program->global_name, @@ -513,6 +616,28 @@ void yagl_gles2_program_get_active_uniform(struct yagl_gles2_program *program, var->name_fetched = 1; var->generic_fetched = 1; + + var->name[var->name_size] = 0; + + // It is possible that our sampler2D could actually be samplerExternalOES + // Host doesn't know about this. In case we encounter a GL_SAMPLER_2D type + // of uniform, go through GLSL program state and see if we should "replace" + // it with GL_SAMPLER_EXTERNAL_OES. + if (var->type == GL_SAMPLER_2D) { + if (program->fragment_shader_sampler_info.fetched) { + struct yagl_glsl_sampler *samplers = yagl_vector_data(&program->fragment_shader_sampler_info.samplers_ExternalOES); + int i = 0, samplers_size = yagl_vector_size(&program->fragment_shader_sampler_info.samplers_ExternalOES); + + for (i = 0; i < samplers_size; ++i) { + if (strcmp(samplers[i].name, var->name) == 0) { + // also store location because we're here anyway + samplers[i].location = index; + var->type = GL_SAMPLER_EXTERNAL_OES; + break; + } + } + } + } } yagl_gles2_set_name(var->name, var->name_size, @@ -698,13 +823,13 @@ int yagl_gles2_program_uniform1i(struct yagl_gles2_program *program, /* * Update shader state for pre_draw/post_draw analysis */ - if (program->vertex_shader && - program->vertex_shader->state.have_samplerexternaloes) { + if (program->vertex_shader_sampler_info.fetched && + program->vertex_shader_sampler_info.have_samplerexternaloes) { struct yagl_glsl_sampler *data = NULL; int i = 0, data_size = 0; - data = yagl_vector_data(&program->vertex_shader->state.samplers_ExternalOES); - data_size = yagl_vector_size(&program->vertex_shader->state.samplers_ExternalOES); + data = yagl_vector_data(&program->vertex_shader_sampler_info.samplers_ExternalOES); + data_size = yagl_vector_size(&program->vertex_shader_sampler_info.samplers_ExternalOES); for (i = 0; i < data_size; ++i) { if (data[i].location == location) { data[i].value = x; @@ -713,13 +838,13 @@ int yagl_gles2_program_uniform1i(struct yagl_gles2_program *program, } } - if (program->fragment_shader && - program->fragment_shader->state.have_samplerexternaloes) { + if (program->fragment_shader_sampler_info.fetched && + program->fragment_shader_sampler_info.have_samplerexternaloes) { struct yagl_glsl_sampler *data = NULL; int i = 0, data_size = 0; - data = yagl_vector_data(&program->fragment_shader->state.samplers_ExternalOES); - data_size = yagl_vector_size(&program->fragment_shader->state.samplers_ExternalOES); + data = yagl_vector_data(&program->fragment_shader_sampler_info.samplers_ExternalOES); + data_size = yagl_vector_size(&program->fragment_shader_sampler_info.samplers_ExternalOES); for (i = 0; i < data_size; ++i) { if (data[i].location == location) { data[i].value = x; diff --git a/GLESv2/yagl_gles2_program.h b/GLESv2/yagl_gles2_program.h index 9179f52..5088013 100644 --- a/GLESv2/yagl_gles2_program.h +++ b/GLESv2/yagl_gles2_program.h @@ -188,6 +188,15 @@ struct yagl_gles2_transform_feedback_info GLint max_varying_bufsize; }; +struct yagl_gles2_program_sampler_info +{ + int fetched; + + int have_samplerexternaloes; + struct yagl_vector samplers_ExternalOES; + struct yagl_vector samplers_2D; +}; + struct yagl_gles2_program { /* @@ -213,6 +222,10 @@ struct yagl_gles2_program struct yagl_gles2_shader *fragment_shader; + struct yagl_gles2_program_sampler_info vertex_shader_sampler_info; + + struct yagl_gles2_program_sampler_info fragment_shader_sampler_info; + union { struct yagl_list uniform_locations_l; diff --git a/GLESv2/yagl_glsl_state.c b/GLESv2/yagl_glsl_state.c index 74def14..2dcbb11 100644 --- a/GLESv2/yagl_glsl_state.c +++ b/GLESv2/yagl_glsl_state.c @@ -397,7 +397,7 @@ void yagl_glsl_state_add_sampler_ExternalOES(struct yagl_glsl_state *state, struct yagl_glsl_sampler sampler; sampler.name = strdup(str); sampler.location = YAGL_GLSL_SAMPLER_LOCATION_UNKNOWN; - sampler.value = YAGL_GLSL_SAMPLER_VALUE_UNKNOWN; + sampler.value = 0; // GL spec predefines uniform value as 0 sampler.replaced_tex2d = YAGL_GLSL_SAMPLER_VALUE_UNKNOWN; yagl_vector_push_back(&state->samplers_ExternalOES, &sampler); } @@ -408,7 +408,7 @@ void yagl_glsl_state_add_sampler_2D(struct yagl_glsl_state *state, struct yagl_glsl_sampler sampler; sampler.name = strdup(str); sampler.location = YAGL_GLSL_SAMPLER_LOCATION_UNKNOWN; - sampler.value = YAGL_GLSL_SAMPLER_VALUE_UNKNOWN; + sampler.value = 0; // GL spec predefines uniform value as 0 sampler.replaced_tex2d = YAGL_GLSL_SAMPLER_VALUE_UNKNOWN; yagl_vector_push_back(&state->samplers_2D, &sampler); } |