From a1aa53b2a934ca026bb115aca18a46fd920f9e8d Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Thu, 25 Feb 2010 23:10:47 +0800 Subject: [PATCH] st/mesa: Implement GL_OES_EGL_image driver hooks. Use st_manager::get_egl_image to look up GLeglImageOES and implement EGLImageTargetTexture2D and EGLImageTargetRenderbufferStorage. --- src/mesa/SConscript | 1 + src/mesa/sources.mak | 1 + src/mesa/state_tracker/st_cb_eglimage.c | 160 ++++++++++++++++++++++++ src/mesa/state_tracker/st_cb_eglimage.h | 48 +++++++ src/mesa/state_tracker/st_context.c | 3 + src/mesa/state_tracker/st_manager.c | 28 +++++ src/mesa/state_tracker/st_manager.h | 4 + 7 files changed, 245 insertions(+) create mode 100644 src/mesa/state_tracker/st_cb_eglimage.c create mode 100644 src/mesa/state_tracker/st_cb_eglimage.h diff --git a/src/mesa/SConscript b/src/mesa/SConscript index 5a04dfd68fb..424232a1d21 100644 --- a/src/mesa/SConscript +++ b/src/mesa/SConscript @@ -167,6 +167,7 @@ if env['platform'] != 'winddk': 'state_tracker/st_cb_condrender.c', 'state_tracker/st_cb_flush.c', 'state_tracker/st_cb_drawpixels.c', + 'state_tracker/st_cb_eglimage.c', 'state_tracker/st_cb_fbo.c', 'state_tracker/st_cb_feedback.c', 'state_tracker/st_cb_program.c', diff --git a/src/mesa/sources.mak b/src/mesa/sources.mak index 996172d9a50..f6d52b8e0f7 100644 --- a/src/mesa/sources.mak +++ b/src/mesa/sources.mak @@ -199,6 +199,7 @@ STATETRACKER_SOURCES = \ state_tracker/st_cb_condrender.c \ state_tracker/st_cb_flush.c \ state_tracker/st_cb_drawpixels.c \ + state_tracker/st_cb_eglimage.c \ state_tracker/st_cb_fbo.c \ state_tracker/st_cb_feedback.c \ state_tracker/st_cb_program.c \ diff --git a/src/mesa/state_tracker/st_cb_eglimage.c b/src/mesa/state_tracker/st_cb_eglimage.c new file mode 100644 index 00000000000..935b29a3242 --- /dev/null +++ b/src/mesa/state_tracker/st_cb_eglimage.c @@ -0,0 +1,160 @@ +/* + * Mesa 3-D graphics library + * Version: 7.9 + * + * Copyright (C) 2010 LunarG Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Chia-I Wu + */ + +#include "main/texobj.h" +#include "main/texfetch.h" +#include "main/teximage.h" +#include "util/u_inlines.h" +#include "util/u_format.h" +#include "st_cb_eglimage.h" +#include "st_cb_fbo.h" +#include "st_texture.h" +#include "st_format.h" +#include "st_manager.h" + +#if FEATURE_OES_EGL_image + +/** + * Return the base format just like _mesa_base_fbo_format does. + */ +static GLenum +st_pipe_format_to_base_format(enum pipe_format format) +{ + GLenum base_format; + + if (util_format_is_depth_or_stencil(format)) { + if (util_format_is_depth_and_stencil(format)) { + base_format = GL_DEPTH_STENCIL; + } + else { + if (format == PIPE_FORMAT_S8_USCALED) + base_format = GL_STENCIL_INDEX; + else + base_format = GL_DEPTH_COMPONENT; + } + } + else { + /* is this enough? */ + if (util_format_has_alpha(format)) + base_format = GL_RGBA; + else + base_format = GL_RGB; + } + + return base_format; +} + +static void +st_egl_image_target_renderbuffer_storage(GLcontext *ctx, + struct gl_renderbuffer *rb, + GLeglImageOES image_handle) +{ + struct st_context *st = ctx->st; + struct st_renderbuffer *strb = st_renderbuffer(rb); + struct pipe_surface *ps; + unsigned usage; + + usage = PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE; + ps = st_manager_get_egl_image_surface(st, (void *) image_handle, usage); + if (ps) { + strb->Base.Width = ps->width; + strb->Base.Height = ps->height; + strb->Base.Format = st_pipe_format_to_mesa_format(ps->format); + strb->Base.DataType = st_format_datatype(ps->format); + strb->Base._BaseFormat = st_pipe_format_to_base_format(ps->format); + strb->Base.InternalFormat = strb->Base._BaseFormat; + + pipe_surface_reference(&strb->surface, ps); + pipe_texture_reference(&strb->texture, ps->texture); + + pipe_surface_reference(&ps, NULL); + } +} + +static void +st_bind_surface(GLcontext *ctx, GLenum target, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, + struct pipe_surface *ps) +{ + struct st_texture_object *stObj; + struct st_texture_image *stImage; + GLenum internalFormat; + + /* map pipe format to base format */ + if (util_format_get_component_bits(ps->format, UTIL_FORMAT_COLORSPACE_RGB, 3) > 0) + internalFormat = GL_RGBA; + else + internalFormat = GL_RGB; + + stObj = st_texture_object(texObj); + stImage = st_texture_image(texImage); + + /* switch to surface based */ + if (!stObj->surface_based) { + _mesa_clear_texture_object(ctx, texObj); + stObj->surface_based = GL_TRUE; + } + + _mesa_init_teximage_fields(ctx, target, texImage, + ps->width, ps->height, 1, 0, internalFormat); + texImage->TexFormat = st_pipe_format_to_mesa_format(ps->format); + _mesa_set_fetch_functions(texImage, 2); + + stObj->pipe = ctx->st->pipe; + /* FIXME create a non-default sampler view from the pipe_surface? */ + pipe_texture_reference(&stImage->pt, ps->texture); + + _mesa_dirty_texobj(ctx, texObj, GL_TRUE); +} + +static void +st_egl_image_target_texture_2d(GLcontext *ctx, GLenum target, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, + GLeglImageOES image_handle) +{ + struct st_context *st = ctx->st; + struct pipe_surface *ps; + unsigned usage; + + usage = PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE; + ps = st_manager_get_egl_image_surface(st, (void *) image_handle, usage); + if (ps) { + st_bind_surface(ctx, target, texObj, texImage, ps); + pipe_surface_reference(&ps, NULL); + } +} + +void +st_init_eglimage_functions(struct dd_function_table *functions) +{ + functions->EGLImageTargetTexture2D = st_egl_image_target_texture_2d; + functions->EGLImageTargetRenderbufferStorage = st_egl_image_target_renderbuffer_storage; +} + +#endif /* FEATURE_OES_EGL_image */ diff --git a/src/mesa/state_tracker/st_cb_eglimage.h b/src/mesa/state_tracker/st_cb_eglimage.h new file mode 100644 index 00000000000..77e668d9199 --- /dev/null +++ b/src/mesa/state_tracker/st_cb_eglimage.h @@ -0,0 +1,48 @@ +/* + * Mesa 3-D graphics library + * Version: 7.9 + * + * Copyright (C) 2010 LunarG Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Chia-I Wu + */ + +#ifndef ST_CB_EGLIMAGE_H +#define ST_CB_EGLIMAGE_H + +#include "main/mtypes.h" +#include "main/dd.h" + +#if FEATURE_OES_EGL_image + +extern void +st_init_eglimage_functions(struct dd_function_table *functions); + +#else + +static INLINE void +st_init_eglimage_functions(struct dd_function_table *functions) +{ +} + +#endif + +#endif /* ST_CB_EGLIMAGE_H */ diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index 72f5a9c1e0b..83580591fc3 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -46,6 +46,7 @@ #if FEATURE_OES_draw_texture #include "st_cb_drawtex.h" #endif +#include "st_cb_eglimage.h" #include "st_cb_fbo.h" #if FEATURE_feedback #include "st_cb_feedback.h" @@ -359,6 +360,8 @@ void st_init_driver_functions(struct dd_function_table *functions) st_init_drawtex_functions(functions); #endif + st_init_eglimage_functions(functions); + st_init_fbo_functions(functions); #if FEATURE_feedback st_init_feedback_functions(functions); diff --git a/src/mesa/state_tracker/st_manager.c b/src/mesa/state_tracker/st_manager.c index cac62e4a14c..696d8aa7922 100644 --- a/src/mesa/state_tracker/st_manager.c +++ b/src/mesa/state_tracker/st_manager.c @@ -720,6 +720,34 @@ st_manager_flush_frontbuffer(struct st_context *st) stfb->iface->flush_front(stfb->iface, ST_ATTACHMENT_FRONT_LEFT); } +/** + * Return the surface of an EGLImage. + */ +struct pipe_surface * +st_manager_get_egl_image_surface(struct st_context *st, + void *eglimg, unsigned usage) +{ + struct st_manager *smapi = + (struct st_manager *) st->iface.st_context_private; + struct st_egl_image stimg; + struct pipe_surface *ps; + + if (!smapi || !smapi->get_egl_image) + return NULL; + + memset(&stimg, 0, sizeof(stimg)); + stimg.stctxi = &st->iface; + stimg.egl_image = eglimg; + if (!smapi->get_egl_image(smapi, &stimg)) + return NULL; + + ps = smapi->screen->get_tex_surface(smapi->screen, + stimg.texture, stimg.face, stimg.level, stimg.zslice, usage); + pipe_texture_reference(&stimg.texture, NULL); + + return ps; +} + /** * Re-validate the framebuffers. */ diff --git a/src/mesa/state_tracker/st_manager.h b/src/mesa/state_tracker/st_manager.h index a3f51992237..0d3f8f7de4f 100644 --- a/src/mesa/state_tracker/st_manager.h +++ b/src/mesa/state_tracker/st_manager.h @@ -31,6 +31,10 @@ #include "state_tracker/st_api.h" #include "st_context.h" +struct pipe_surface * +st_manager_get_egl_image_surface(struct st_context *st, + void *eglimg, unsigned usage); + void st_manager_flush_frontbuffer(struct st_context *st); -- 2.30.2