diff options
Diffstat (limited to 'src/mesa/state_tracker/st_cb_eglimage.c')
-rw-r--r-- | src/mesa/state_tracker/st_cb_eglimage.c | 160 |
1 files changed, 160 insertions, 0 deletions
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..0fa1848e232 --- /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 + * THE AUTHORS OR COPYRIGHT HOLDERS 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 <[email protected]> + */ + +#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 = st_context(ctx); + struct st_renderbuffer *strb = st_renderbuffer(rb); + struct pipe_surface *ps; + unsigned usage; + + usage = PIPE_BIND_RENDER_TARGET | PIPE_BIND_BLIT_SOURCE | PIPE_BIND_BLIT_DESTINATION; + 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_resource_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); + + /* FIXME create a non-default sampler view from the pipe_surface? */ + pipe_resource_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 = st_context(ctx); + struct pipe_surface *ps; + unsigned usage; + + usage = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_BLIT_DESTINATION | PIPE_BIND_BLIT_SOURCE; + 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 */ |