Home | History | Annotate | Download | only in state_tracker
      1 /*
      2  * Mesa 3-D graphics library
      3  *
      4  * Copyright (C) 2010 LunarG Inc.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  * and/or sell copies of the Software, and to permit persons to whom the
     11  * Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included
     14  * in all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     22  * DEALINGS IN THE SOFTWARE.
     23  *
     24  * Authors:
     25  *    Chia-I Wu <olv (at) lunarg.com>
     26  */
     27 
     28 #include "main/texobj.h"
     29 #include "main/teximage.h"
     30 #include "util/u_inlines.h"
     31 #include "util/u_format.h"
     32 #include "st_cb_eglimage.h"
     33 #include "st_cb_fbo.h"
     34 #include "st_context.h"
     35 #include "st_texture.h"
     36 #include "st_format.h"
     37 #include "st_manager.h"
     38 #include "st_sampler_view.h"
     39 
     40 
     41 /**
     42  * Return the base format just like _mesa_base_fbo_format does.
     43  */
     44 static GLenum
     45 st_pipe_format_to_base_format(enum pipe_format format)
     46 {
     47    GLenum base_format;
     48 
     49    if (util_format_is_depth_or_stencil(format)) {
     50       if (util_format_is_depth_and_stencil(format)) {
     51          base_format = GL_DEPTH_STENCIL;
     52       }
     53       else {
     54          if (format == PIPE_FORMAT_S8_UINT)
     55             base_format = GL_STENCIL_INDEX;
     56          else
     57             base_format = GL_DEPTH_COMPONENT;
     58       }
     59    }
     60    else {
     61       /* is this enough? */
     62       if (util_format_has_alpha(format))
     63          base_format = GL_RGBA;
     64       else
     65          base_format = GL_RGB;
     66    }
     67 
     68    return base_format;
     69 }
     70 
     71 static void
     72 st_egl_image_target_renderbuffer_storage(struct gl_context *ctx,
     73 					 struct gl_renderbuffer *rb,
     74 					 GLeglImageOES image_handle)
     75 {
     76    struct st_context *st = st_context(ctx);
     77    struct st_renderbuffer *strb = st_renderbuffer(rb);
     78    struct pipe_surface *ps;
     79 
     80    ps = st_manager_get_egl_image_surface(st, (void *) image_handle);
     81    if (ps) {
     82       strb->Base.Width = ps->width;
     83       strb->Base.Height = ps->height;
     84       strb->Base.Format = st_pipe_format_to_mesa_format(ps->format);
     85       strb->Base._BaseFormat = st_pipe_format_to_base_format(ps->format);
     86       strb->Base.InternalFormat = strb->Base._BaseFormat;
     87 
     88       pipe_surface_reference(&strb->surface, ps);
     89       pipe_resource_reference(&strb->texture, ps->texture);
     90 
     91       pipe_surface_reference(&ps, NULL);
     92    }
     93 }
     94 
     95 static void
     96 st_bind_surface(struct gl_context *ctx, GLenum target,
     97                 struct gl_texture_object *texObj,
     98                 struct gl_texture_image *texImage,
     99                 struct pipe_surface *ps)
    100 {
    101    struct st_context *st = st_context(ctx);
    102    struct st_texture_object *stObj;
    103    struct st_texture_image *stImage;
    104    GLenum internalFormat;
    105    mesa_format texFormat;
    106 
    107    /* map pipe format to base format */
    108    if (util_format_get_component_bits(ps->format, UTIL_FORMAT_COLORSPACE_RGB, 3) > 0)
    109       internalFormat = GL_RGBA;
    110    else
    111       internalFormat = GL_RGB;
    112 
    113    stObj = st_texture_object(texObj);
    114    stImage = st_texture_image(texImage);
    115 
    116    /* switch to surface based */
    117    if (!stObj->surface_based) {
    118       _mesa_clear_texture_object(ctx, texObj);
    119       stObj->surface_based = GL_TRUE;
    120    }
    121 
    122    texFormat = st_pipe_format_to_mesa_format(ps->format);
    123 
    124    /* TODO RequiredTextureImageUnits should probably be reset back
    125     * to 1 somewhere if different texture is bound??
    126     */
    127    if (texFormat == MESA_FORMAT_NONE) {
    128       switch (ps->format) {
    129       case PIPE_FORMAT_NV12:
    130          texFormat = MESA_FORMAT_R_UNORM8;
    131          texObj->RequiredTextureImageUnits = 2;
    132          break;
    133       case PIPE_FORMAT_IYUV:
    134          texFormat = MESA_FORMAT_R_UNORM8;
    135          texObj->RequiredTextureImageUnits = 3;
    136          break;
    137       default:
    138          unreachable("bad YUV format!");
    139       }
    140    }
    141 
    142    _mesa_init_teximage_fields(ctx, texImage,
    143                               ps->width, ps->height, 1, 0, internalFormat,
    144                               texFormat);
    145 
    146    /* FIXME create a non-default sampler view from the pipe_surface? */
    147    pipe_resource_reference(&stObj->pt, ps->texture);
    148    st_texture_release_all_sampler_views(st, stObj);
    149    pipe_resource_reference(&stImage->pt, stObj->pt);
    150 
    151    stObj->surface_format = ps->format;
    152 
    153    _mesa_dirty_texobj(ctx, texObj);
    154 }
    155 
    156 static void
    157 st_egl_image_target_texture_2d(struct gl_context *ctx, GLenum target,
    158 			       struct gl_texture_object *texObj,
    159 			       struct gl_texture_image *texImage,
    160 			       GLeglImageOES image_handle)
    161 {
    162    struct st_context *st = st_context(ctx);
    163    struct pipe_surface *ps;
    164 
    165    ps = st_manager_get_egl_image_surface(st, (void *) image_handle);
    166    if (ps) {
    167       st_bind_surface(ctx, target, texObj, texImage, ps);
    168       pipe_surface_reference(&ps, NULL);
    169    }
    170 }
    171 
    172 void
    173 st_init_eglimage_functions(struct dd_function_table *functions)
    174 {
    175    functions->EGLImageTargetTexture2D = st_egl_image_target_texture_2d;
    176    functions->EGLImageTargetRenderbufferStorage = st_egl_image_target_renderbuffer_storage;
    177 }
    178