summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukasz Kostyra <l.kostyra@samsung.com>2021-01-22 17:12:16 +0100
committerLukasz Kostyra <l.kostyra@samsung.com>2021-01-22 17:21:17 +0100
commitc9e7befe1af5d776226e635e8e6af204aa1349ac (patch)
treeed76401b83a3866128c521112a6f515ae63225fe
parentfc6b56c5fb1ed811faf62c89689aa9ac4a813de9 (diff)
downloademulator-yagl-c9e7befe1af5d776226e635e8e6af204aa1349ac.tar.gz
emulator-yagl-c9e7befe1af5d776226e635e8e6af204aa1349ac.tar.bz2
emulator-yagl-c9e7befe1af5d776226e635e8e6af204aa1349ac.zip
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.c22
-rw-r--r--GLES_common/yagl_gles_context.c45
-rw-r--r--GLESv2/yagl_gles2_context.c48
-rw-r--r--GLESv2/yagl_gles2_program.c159
-rw-r--r--GLESv2/yagl_gles2_program.h13
-rw-r--r--GLESv2/yagl_glsl_state.c4
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);
}