From 0c87f16817ff0bf1f05e0d634944fd47b097faee Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Sun, 23 Oct 2011 18:52:38 +0800 Subject: [PATCH] mesa: add support for GL_OES_EGL_image_external This is an OpenGL ES specific extension. External textures are textures that may be sampled from, but not be updated (no glTexSubImage* and etc.). The image data are taken from an EGLImage. Reviewed-by: Brian Paul Acked-by: Jakob Bornecrantz --- src/mesa/main/APIspec.xml | 9 +++++++++ src/mesa/main/attrib.c | 2 ++ src/mesa/main/debug.c | 3 ++- src/mesa/main/enable.c | 13 +++++++++++++ src/mesa/main/ff_fragment_shader.cpp | 7 +++++++ src/mesa/main/get.c | 9 +++++++++ src/mesa/main/mipmap.c | 1 + src/mesa/main/mtypes.h | 5 +++++ src/mesa/main/shaderapi.c | 2 ++ src/mesa/main/shared.c | 1 + src/mesa/main/teximage.c | 26 +++++++++++++++----------- src/mesa/main/texobj.c | 18 +++++++++++++++--- src/mesa/main/texparam.c | 20 +++++++++++++++++++- src/mesa/main/texstate.c | 3 ++- src/mesa/main/uniforms.c | 1 + src/mesa/program/ir_to_mesa.cpp | 3 +++ 16 files changed, 106 insertions(+), 17 deletions(-) diff --git a/src/mesa/main/APIspec.xml b/src/mesa/main/APIspec.xml index a92bb437c91..99c726c83ad 100644 --- a/src/mesa/main/APIspec.xml +++ b/src/mesa/main/APIspec.xml @@ -288,6 +288,7 @@ + @@ -827,6 +828,7 @@ + @@ -884,6 +886,7 @@ + @@ -1477,6 +1480,7 @@ + @@ -1544,6 +1548,7 @@ + @@ -2071,6 +2076,7 @@ + @@ -3493,6 +3499,7 @@ + @@ -3830,6 +3837,7 @@ + @@ -4118,6 +4126,7 @@ + diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c index 1dc1c1b9706..f368eecc1b2 100644 --- a/src/mesa/main/attrib.c +++ b/src/mesa/main/attrib.c @@ -764,6 +764,8 @@ pop_texture_group(struct gl_context *ctx, struct texture_state *texstate) } else if (obj->Target == GL_TEXTURE_BUFFER) continue; + else if (obj->Target == GL_TEXTURE_EXTERNAL_OES) + continue; target = obj->Target; diff --git a/src/mesa/main/debug.c b/src/mesa/main/debug.c index 6e695d1474c..72aa8cb4f79 100644 --- a/src/mesa/main/debug.c +++ b/src/mesa/main/debug.c @@ -50,7 +50,8 @@ tex_target_name(GLenum tgt) { GL_TEXTURE_CUBE_MAP, "GL_TEXTURE_CUBE_MAP" }, { GL_TEXTURE_RECTANGLE, "GL_TEXTURE_RECTANGLE" }, { GL_TEXTURE_1D_ARRAY_EXT, "GL_TEXTURE_1D_ARRAY" }, - { GL_TEXTURE_2D_ARRAY_EXT, "GL_TEXTURE_2D_ARRAY" } + { GL_TEXTURE_2D_ARRAY_EXT, "GL_TEXTURE_2D_ARRAY" }, + { GL_TEXTURE_EXTERNAL_OES, "GL_TEXTURE_EXTERNAL_OES" } }; GLuint i; for (i = 0; i < Elements(tex_targets); i++) { diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c index 689dc8a99ec..b2c77243b50 100644 --- a/src/mesa/main/enable.c +++ b/src/mesa/main/enable.c @@ -916,6 +916,14 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) ctx->Color.sRGBEnabled = state; break; + /* GL_OES_EGL_image_external */ + case GL_TEXTURE_EXTERNAL_OES: + CHECK_EXTENSION(OES_EGL_image_external, cap); + if (!enable_texture(ctx, state, TEXTURE_EXTERNAL_BIT)) { + return; + } + break; + default: goto invalid_enum_error; } @@ -1417,6 +1425,11 @@ _mesa_IsEnabled( GLenum cap ) CHECK_EXTENSION(EXT_framebuffer_sRGB); return ctx->Color.sRGBEnabled; + /* GL_OES_EGL_image_external */ + case GL_TEXTURE_EXTERNAL_OES: + CHECK_EXTENSION(OES_EGL_image_external); + return is_texture_enabled(ctx, TEXTURE_EXTERNAL_BIT); + default: goto invalid_enum_error; } diff --git a/src/mesa/main/ff_fragment_shader.cpp b/src/mesa/main/ff_fragment_shader.cpp index f612325192d..2ce81fef61e 100644 --- a/src/mesa/main/ff_fragment_shader.cpp +++ b/src/mesa/main/ff_fragment_shader.cpp @@ -1041,6 +1041,11 @@ static void load_texture( struct texenv_fragment_program *p, GLuint unit ) sampler_type = p->shader->symbols->get_type("samplerCube"); coords = 3; break; + case TEXTURE_EXTERNAL_INDEX: + assert(!p->state->unit[unit].shadow); + sampler_type = p->shader->symbols->get_type("samplerExternalOES"); + coords = 2; + break; } p->src_texture[unit] = new(p->mem_ctx) ir_variable(glsl_type::vec4_type, @@ -1437,6 +1442,8 @@ create_new_program(struct gl_context *ctx, struct state_key *key) p.shader_program->InternalSeparateShader = GL_TRUE; state->language_version = 130; + if (ctx->Extensions.OES_EGL_image_external) + state->OES_EGL_image_external_enable = true; _mesa_glsl_initialize_types(state); _mesa_glsl_initialize_variables(p.instructions, state); diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c index 8925b75ebee..d8a063876d8 100644 --- a/src/mesa/main/get.c +++ b/src/mesa/main/get.c @@ -332,6 +332,7 @@ EXTRA_EXT(ARB_color_buffer_float); EXTRA_EXT(ARB_copy_buffer); EXTRA_EXT(EXT_framebuffer_sRGB); EXTRA_EXT(ARB_texture_buffer_object); +EXTRA_EXT(OES_EGL_image_external); static const int extra_ARB_vertex_program_ARB_fragment_program_NV_vertex_program[] = { @@ -762,6 +763,12 @@ static const struct value_desc values[] = { { GL_SHADER_BINARY_FORMATS, CONST(0), NO_EXTRA }, #endif /* FEATURE_ES2 */ + /* GL_OES_EGL_image_external */ + { GL_TEXTURE_BINDING_EXTERNAL_OES, LOC_CUSTOM, + TYPE_INT, TEXTURE_EXTERNAL_INDEX, extra_OES_EGL_image_external }, + { GL_TEXTURE_EXTERNAL_OES, LOC_CUSTOM, + TYPE_BOOLEAN, 0, extra_OES_EGL_image_external }, + #if FEATURE_GL /* Remaining enums are only in OpenGL */ { 0, 0, TYPE_API_MASK, API_OPENGL_BIT, NO_EXTRA }, @@ -1419,6 +1426,7 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu case GL_TEXTURE_2D_ARRAY_EXT: case GL_TEXTURE_CUBE_MAP_ARB: case GL_TEXTURE_RECTANGLE_NV: + case GL_TEXTURE_EXTERNAL_OES: v->value_bool = _mesa_IsEnabled(d->pname); break; @@ -1596,6 +1604,7 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu case GL_TEXTURE_BINDING_2D_ARRAY_EXT: case GL_TEXTURE_BINDING_CUBE_MAP_ARB: case GL_TEXTURE_BINDING_RECTANGLE_NV: + case GL_TEXTURE_BINDING_EXTERNAL_OES: unit = ctx->Texture.CurrentUnit; v->value_int = ctx->Texture.Unit[unit].CurrentTex[d->offset]->Name; diff --git a/src/mesa/main/mipmap.c b/src/mesa/main/mipmap.c index 46d71bb2218..461de9d1bb2 100644 --- a/src/mesa/main/mipmap.c +++ b/src/mesa/main/mipmap.c @@ -1751,6 +1751,7 @@ _mesa_generate_mipmap_level(GLenum target, } break; case GL_TEXTURE_RECTANGLE_NV: + case GL_TEXTURE_EXTERNAL_OES: /* no mipmaps, do nothing */ break; default: diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 9a0f3cfb90f..61909727d16 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1166,6 +1166,7 @@ typedef enum TEXTURE_BUFFER_INDEX, TEXTURE_2D_ARRAY_INDEX, TEXTURE_1D_ARRAY_INDEX, + TEXTURE_EXTERNAL_INDEX, TEXTURE_CUBE_INDEX, TEXTURE_3D_INDEX, TEXTURE_RECT_INDEX, @@ -1183,6 +1184,7 @@ typedef enum #define TEXTURE_BUFFER_BIT (1 << TEXTURE_BUFFER_INDEX) #define TEXTURE_2D_ARRAY_BIT (1 << TEXTURE_2D_ARRAY_INDEX) #define TEXTURE_1D_ARRAY_BIT (1 << TEXTURE_1D_ARRAY_INDEX) +#define TEXTURE_EXTERNAL_BIT (1 << TEXTURE_EXTERNAL_INDEX) #define TEXTURE_CUBE_BIT (1 << TEXTURE_CUBE_INDEX) #define TEXTURE_3D_BIT (1 << TEXTURE_3D_INDEX) #define TEXTURE_RECT_BIT (1 << TEXTURE_RECT_INDEX) @@ -1344,6 +1346,9 @@ struct gl_texture_object struct gl_buffer_object *BufferObject; GLenum BufferObjectFormat; + /** GL_OES_EGL_image_external */ + GLint RequiredTextureImageUnits; + /** * \name For device driver. * Note: instead of attaching driver data to this pointer, it's preferable diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c index 6868dfab09e..56d955c5397 100644 --- a/src/mesa/main/shaderapi.c +++ b/src/mesa/main/shaderapi.c @@ -152,6 +152,7 @@ _mesa_sizeof_glsl_type(GLenum type) case GL_SAMPLER_1D_ARRAY_SHADOW_EXT: case GL_SAMPLER_2D_ARRAY_SHADOW_EXT: case GL_SAMPLER_CUBE_SHADOW_EXT: + case GL_SAMPLER_EXTERNAL_OES: return 1; case GL_FLOAT_VEC2: case GL_INT_VEC2: @@ -918,6 +919,7 @@ validate_samplers(const struct gl_program *prog, char *errMsg) "TEXTURE_BUFFER", "TEXTURE_2D_ARRAY", "TEXTURE_1D_ARRAY", + "TEXTURE_EXTERNAL", "TEXTURE_CUBE", "TEXTURE_3D", "TEXTURE_RECT", diff --git a/src/mesa/main/shared.c b/src/mesa/main/shared.c index 8b7159db09c..caa6132d4ab 100644 --- a/src/mesa/main/shared.c +++ b/src/mesa/main/shared.c @@ -108,6 +108,7 @@ _mesa_alloc_shared_state(struct gl_context *ctx) GL_TEXTURE_BUFFER, GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_1D_ARRAY_EXT, + GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_3D, GL_TEXTURE_RECTANGLE_NV, diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index 58b0e5d089c..a84d6873d3d 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -549,7 +549,8 @@ _mesa_set_tex_image(struct gl_texture_object *tObj, ASSERT(tObj); ASSERT(texImage); - ASSERT(target != GL_TEXTURE_RECTANGLE_NV || level == 0); + if (target == GL_TEXTURE_RECTANGLE_NV || target == GL_TEXTURE_EXTERNAL_OES) + assert(level == 0); tObj->Image[face][level] = texImage; @@ -607,10 +608,11 @@ _mesa_delete_texture_image(struct gl_context *ctx, GLboolean _mesa_is_proxy_texture(GLenum target) { - /* NUM_TEXTURE_TARGETS should match number of terms below, - * except there's no proxy for GL_TEXTURE_BUFFER. + /* + * NUM_TEXTURE_TARGETS should match number of terms below, except there's no + * proxy for GL_TEXTURE_BUFFER and GL_TEXTURE_EXTERNAL_OES. */ - assert(NUM_TEXTURE_TARGETS == 8); + assert(NUM_TEXTURE_TARGETS == 7 + 2); return (target == GL_PROXY_TEXTURE_1D || target == GL_PROXY_TEXTURE_2D || @@ -723,6 +725,9 @@ _mesa_select_tex_object(struct gl_context *ctx, case GL_TEXTURE_BUFFER: return ctx->Extensions.ARB_texture_buffer_object ? texUnit->CurrentTex[TEXTURE_BUFFER_INDEX] : NULL; + case GL_TEXTURE_EXTERNAL_OES: + return ctx->Extensions.OES_EGL_image_external + ? texUnit->CurrentTex[TEXTURE_EXTERNAL_INDEX] : NULL; default: _mesa_problem(NULL, "bad target in _mesa_select_tex_object()"); return NULL; @@ -911,6 +916,7 @@ _mesa_max_texture_levels(struct gl_context *ctx, GLenum target) ctx->Extensions.EXT_texture_array) ? ctx->Const.MaxTextureLevels : 0; case GL_TEXTURE_BUFFER: + case GL_TEXTURE_EXTERNAL_OES: /* fall-through */ default: return 0; /* bad target */ @@ -942,6 +948,7 @@ _mesa_get_texture_dimensions(GLenum target) case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: case GL_TEXTURE_1D_ARRAY: case GL_PROXY_TEXTURE_1D_ARRAY: + case GL_TEXTURE_EXTERNAL_OES: return 2; case GL_TEXTURE_3D: case GL_PROXY_TEXTURE_3D: @@ -2533,13 +2540,10 @@ _mesa_EGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image) GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - if (!ctx->Extensions.OES_EGL_image) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glEGLImageTargetTexture2DOES(unsupported)"); - return; - } - - if (target != GL_TEXTURE_2D) { + if ((target == GL_TEXTURE_2D && + !ctx->Extensions.OES_EGL_image) || + (target == GL_TEXTURE_EXTERNAL_OES && + !ctx->Extensions.OES_EGL_image_external)) { _mesa_error(ctx, GL_INVALID_ENUM, "glEGLImageTargetTexture2D(target=%d)", target); return; diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c index a8c0b8ee8b9..e2f0dc8b643 100644 --- a/src/mesa/main/texobj.c +++ b/src/mesa/main/texobj.c @@ -107,6 +107,7 @@ _mesa_initialize_texture_object( struct gl_texture_object *obj, target == GL_TEXTURE_RECTANGLE_NV || target == GL_TEXTURE_1D_ARRAY_EXT || target == GL_TEXTURE_2D_ARRAY_EXT || + target == GL_TEXTURE_EXTERNAL_OES || target == GL_TEXTURE_BUFFER); memset(obj, 0, sizeof(*obj)); @@ -119,8 +120,12 @@ _mesa_initialize_texture_object( struct gl_texture_object *obj, obj->BaseLevel = 0; obj->MaxLevel = 1000; + /* must be one; no support for (YUV) planes in separate buffers */ + obj->RequiredTextureImageUnits = 1; + /* sampler state */ - if (target == GL_TEXTURE_RECTANGLE_NV) { + if (target == GL_TEXTURE_RECTANGLE_NV || + target == GL_TEXTURE_EXTERNAL_OES) { obj->Sampler.WrapS = GL_CLAMP_TO_EDGE; obj->Sampler.WrapT = GL_CLAMP_TO_EDGE; obj->Sampler.WrapR = GL_CLAMP_TO_EDGE; @@ -161,7 +166,8 @@ finish_texture_init(struct gl_context *ctx, GLenum target, { assert(obj->Target == 0); - if (target == GL_TEXTURE_RECTANGLE_NV) { + if (target == GL_TEXTURE_RECTANGLE_NV || + target == GL_TEXTURE_EXTERNAL_OES) { /* have to init wrap and filter state here - kind of klunky */ obj->Sampler.WrapS = GL_CLAMP_TO_EDGE; obj->Sampler.WrapT = GL_CLAMP_TO_EDGE; @@ -259,6 +265,8 @@ _mesa_copy_texture_object( struct gl_texture_object *dest, dest->_Complete = src->_Complete; COPY_4V(dest->Swizzle, src->Swizzle); dest->_Swizzle = src->_Swizzle; + + dest->RequiredTextureImageUnits = src->RequiredTextureImageUnits; } @@ -306,6 +314,7 @@ valid_texture_object(const struct gl_texture_object *tex) case GL_TEXTURE_1D_ARRAY_EXT: case GL_TEXTURE_2D_ARRAY_EXT: case GL_TEXTURE_BUFFER: + case GL_TEXTURE_EXTERNAL_OES: return GL_TRUE; case 0x99: _mesa_problem(NULL, "invalid reference to a deleted texture object"); @@ -470,7 +479,8 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, t->Image[0][baseLevel]->HeightLog2); maxLevels = ctx->Const.MaxCubeTextureLevels; } - else if (t->Target == GL_TEXTURE_RECTANGLE_NV) { + else if (t->Target == GL_TEXTURE_RECTANGLE_NV || + t->Target == GL_TEXTURE_EXTERNAL_OES) { maxLog2 = 0; /* not applicable */ maxLevels = 1; /* no mipmapping */ } @@ -1005,6 +1015,8 @@ target_enum_to_index(GLenum target) return TEXTURE_2D_ARRAY_INDEX; case GL_TEXTURE_BUFFER_ARB: return TEXTURE_BUFFER_INDEX; + case GL_TEXTURE_EXTERNAL_OES: + return TEXTURE_EXTERNAL_INDEX; default: return -1; } diff --git a/src/mesa/main/texparam.c b/src/mesa/main/texparam.c index 226aba03769..17eac5fc996 100644 --- a/src/mesa/main/texparam.c +++ b/src/mesa/main/texparam.c @@ -60,6 +60,10 @@ validate_texture_wrap_mode(struct gl_context * ctx, GLenum target, GLenum wrap) (wrap == GL_CLAMP_TO_BORDER && e->ARB_texture_border_clamp)) return GL_TRUE; } + else if (target == GL_TEXTURE_EXTERNAL_OES) { + if (wrap == GL_CLAMP_TO_EDGE) + return GL_TRUE; + } else { switch (wrap) { case GL_CLAMP: @@ -139,6 +143,11 @@ get_texobj(struct gl_context *ctx, GLenum target, GLboolean get) return texUnit->CurrentTex[TEXTURE_2D_ARRAY_INDEX]; } break; + case GL_TEXTURE_EXTERNAL_OES: + if (ctx->Extensions.OES_EGL_image_external) { + return texUnit->CurrentTex[TEXTURE_EXTERNAL_INDEX]; + } + break; default: ; } @@ -238,7 +247,8 @@ set_tex_parameteri(struct gl_context *ctx, case GL_LINEAR_MIPMAP_NEAREST: case GL_NEAREST_MIPMAP_LINEAR: case GL_LINEAR_MIPMAP_LINEAR: - if (texObj->Target != GL_TEXTURE_RECTANGLE_NV) { + if (texObj->Target != GL_TEXTURE_RECTANGLE_NV && + texObj->Target != GL_TEXTURE_EXTERNAL_OES) { incomplete(ctx, texObj); texObj->Sampler.MinFilter = params[0]; return GL_TRUE; @@ -319,6 +329,8 @@ set_tex_parameteri(struct gl_context *ctx, return GL_TRUE; case GL_GENERATE_MIPMAP_SGIS: + if (params[0] && texObj->Target == GL_TEXTURE_EXTERNAL_OES) + goto invalid_param; if (texObj->GenerateMipmap != params[0]) { /* no flush() */ texObj->GenerateMipmap = params[0] ? GL_TRUE : GL_FALSE; @@ -1388,6 +1400,12 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ) *params = (GLint) obj->Immutable; break; + case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES: + if (!ctx->Extensions.OES_EGL_image_external) + goto invalid_pname; + *params = obj->RequiredTextureImageUnits; + break; + default: goto invalid_pname; } diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index 9f14d8a0d17..7cd285803d5 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -690,7 +690,8 @@ alloc_proxy_textures( struct gl_context *ctx ) GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_1D_ARRAY_EXT, GL_TEXTURE_2D_ARRAY_EXT, - GL_TEXTURE_BUFFER + GL_TEXTURE_BUFFER, + GL_TEXTURE_EXTERNAL_OES }; GLint tgt; diff --git a/src/mesa/main/uniforms.c b/src/mesa/main/uniforms.c index ccaedf9f1d6..68e44b27244 100644 --- a/src/mesa/main/uniforms.c +++ b/src/mesa/main/uniforms.c @@ -148,6 +148,7 @@ is_sampler_type(GLenum type) case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: + case GL_SAMPLER_EXTERNAL_OES: return GL_TRUE; default: return GL_FALSE; diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp index 3bf2cc725b9..3c2eb570749 100644 --- a/src/mesa/program/ir_to_mesa.cpp +++ b/src/mesa/program/ir_to_mesa.cpp @@ -2273,6 +2273,9 @@ ir_to_mesa_visitor::visit(ir_texture *ir) case GLSL_SAMPLER_DIM_BUF: assert(!"FINISHME: Implement ARB_texture_buffer_object"); break; + case GLSL_SAMPLER_DIM_EXTERNAL: + inst->tex_target = TEXTURE_EXTERNAL_INDEX; + break; default: assert(!"Should not get here."); } -- 2.30.2