st_gen_mipmap.c

Go to the documentation of this file.
00001 /**************************************************************************
00002  * 
00003  * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
00004  * All Rights Reserved.
00005  * 
00006  * Permission is hereby granted, free of charge, to any person obtaining a
00007  * copy of this software and associated documentation files (the
00008  * "Software"), to deal in the Software without restriction, including
00009  * without limitation the rights to use, copy, modify, merge, publish,
00010  * distribute, sub license, and/or sell copies of the Software, and to
00011  * permit persons to whom the Software is furnished to do so, subject to
00012  * the following conditions:
00013  * 
00014  * The above copyright notice and this permission notice (including the
00015  * next paragraph) shall be included in all copies or substantial portions
00016  * of the Software.
00017  * 
00018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00019  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00020  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
00021  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
00022  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
00023  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
00024  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00025  * 
00026  **************************************************************************/
00027 
00028 
00029 #include "main/imports.h"
00030 #include "main/mipmap.h"
00031 #include "main/teximage.h"
00032 #include "main/texformat.h"
00033 
00034 #include "shader/prog_instruction.h"
00035 
00036 #include "pipe/p_context.h"
00037 #include "pipe/p_defines.h"
00038 #include "pipe/p_inlines.h"
00039 #include "util/u_gen_mipmap.h"
00040 
00041 #include "cso_cache/cso_cache.h"
00042 #include "cso_cache/cso_context.h"
00043 
00044 #include "st_context.h"
00045 #include "st_draw.h"
00046 #include "st_gen_mipmap.h"
00047 #include "st_program.h"
00048 #include "st_texture.h"
00049 #include "st_cb_texture.h"
00050 
00051 
00057 void
00058 st_init_generate_mipmap(struct st_context *st)
00059 {
00060    st->gen_mipmap = util_create_gen_mipmap(st->pipe, st->cso_context);
00061 }
00062 
00063 
00064 void
00065 st_destroy_generate_mipmap(struct st_context *st)
00066 {
00067    util_destroy_gen_mipmap(st->gen_mipmap);
00068    st->gen_mipmap = NULL;
00069 }
00070 
00071 
00076 static boolean
00077 st_render_mipmap(struct st_context *st,
00078                  GLenum target,
00079                  struct pipe_texture *pt,
00080                  uint baseLevel, uint lastLevel)
00081 {
00082    struct pipe_context *pipe = st->pipe;
00083    struct pipe_screen *screen = pipe->screen;
00084    const uint face = _mesa_tex_target_to_face(target);
00085 
00086    assert(target != GL_TEXTURE_3D); /* not done yet */
00087 
00088    /* check if we can render in the texture's format */
00089    if (!screen->is_format_supported(screen, pt->format, target,
00090                                     PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) {
00091       return FALSE;
00092    }
00093 
00094    util_gen_mipmap(st->gen_mipmap, pt, face, baseLevel, lastLevel,
00095                    PIPE_TEX_FILTER_LINEAR);
00096 
00097    return TRUE;
00098 }
00099 
00100 
00101 static void
00102 fallback_generate_mipmap(GLcontext *ctx, GLenum target,
00103                          struct gl_texture_object *texObj)
00104 {
00105    struct pipe_context *pipe = ctx->st->pipe;
00106    struct pipe_screen *screen = pipe->screen;
00107    struct pipe_texture *pt = st_get_texobj_texture(texObj);
00108    const uint baseLevel = texObj->BaseLevel;
00109    const uint lastLevel = pt->last_level;
00110    const uint face = _mesa_tex_target_to_face(target), zslice = 0;
00111    uint dstLevel;
00112    GLenum datatype;
00113    GLuint comps;
00114 
00115    assert(target != GL_TEXTURE_3D); /* not done yet */
00116 
00117    _mesa_format_to_type_and_comps(texObj->Image[face][baseLevel]->TexFormat,
00118                                   &datatype, &comps);
00119 
00120    for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
00121       const uint srcLevel = dstLevel - 1;
00122       struct pipe_surface *srcSurf, *dstSurf;
00123       const ubyte *srcData;
00124       ubyte *dstData;
00125 
00126       srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice,
00127                                         PIPE_BUFFER_USAGE_CPU_READ);
00128       dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice,
00129                                         PIPE_BUFFER_USAGE_CPU_WRITE);
00130 
00131       srcData = (ubyte *) pipe_buffer_map(pipe->screen, srcSurf->buffer,
00132                                           PIPE_BUFFER_USAGE_CPU_READ)
00133               + srcSurf->offset;
00134       dstData = (ubyte *) pipe_buffer_map(pipe->screen, dstSurf->buffer,
00135                                           PIPE_BUFFER_USAGE_CPU_WRITE)
00136               + dstSurf->offset;
00137 
00138       _mesa_generate_mipmap_level(target, datatype, comps,
00139                    0 /*border*/,
00140                    pt->width[srcLevel], pt->height[srcLevel], pt->depth[srcLevel],
00141                    srcSurf->stride, /* stride in bytes */
00142                    srcData,
00143                    pt->width[dstLevel], pt->height[dstLevel], pt->depth[dstLevel],
00144                    dstSurf->stride, /* stride in bytes */
00145                    dstData);
00146 
00147       pipe_buffer_unmap(pipe->screen, srcSurf->buffer);
00148       pipe_buffer_unmap(pipe->screen, dstSurf->buffer);
00149 
00150       pipe_surface_reference(&srcSurf, NULL);
00151       pipe_surface_reference(&dstSurf, NULL);
00152    }
00153 }
00154 
00155 
00156 void
00157 st_generate_mipmap(GLcontext *ctx, GLenum target,
00158                    struct gl_texture_object *texObj)
00159 {
00160    struct st_context *st = ctx->st;
00161    struct pipe_texture *pt = st_get_texobj_texture(texObj);
00162    const uint baseLevel = texObj->BaseLevel;
00163    const uint lastLevel = pt->last_level;
00164    uint dstLevel;
00165 
00166    if (!st_render_mipmap(st, target, pt, baseLevel, lastLevel)) {
00167       fallback_generate_mipmap(ctx, target, texObj);
00168    }
00169 
00170    /* Fill in the Mesa gl_texture_image fields */
00171    for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
00172       const uint srcLevel = dstLevel - 1;
00173       const struct gl_texture_image *srcImage
00174          = _mesa_get_tex_image(ctx, texObj, target, srcLevel);
00175       struct gl_texture_image *dstImage;
00176       struct st_texture_image *stImage;
00177       uint dstWidth = pt->width[dstLevel];
00178       uint dstHeight = pt->height[dstLevel];
00179       uint dstDepth = pt->depth[dstLevel];
00180       uint border = srcImage->Border;
00181 
00182       dstImage = _mesa_get_tex_image(ctx, texObj, target, dstLevel);
00183       if (!dstImage) {
00184          _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
00185          return;
00186       }
00187 
00188       if (dstImage->ImageOffsets)
00189          _mesa_free(dstImage->ImageOffsets);
00190 
00191       /* Free old image data */
00192       if (dstImage->Data)
00193          ctx->Driver.FreeTexImageData(ctx, dstImage);
00194 
00195       /* initialize new image */
00196       _mesa_init_teximage_fields(ctx, target, dstImage, dstWidth, dstHeight,
00197                                  dstDepth, border, srcImage->InternalFormat);
00198 
00199       dstImage->TexFormat = srcImage->TexFormat;
00200 
00201       stImage = (struct st_texture_image *) dstImage;
00202       pipe_texture_reference(&stImage->pt, pt);
00203    }
00204 }

Generated on Tue Sep 29 06:25:18 2009 for Gallium3D by  doxygen 1.5.4