st_cb_texture.c File Reference

Include dependency graph for st_cb_texture.c:

Go to the source code of this file.

Defines

#define DBG   if (0) printf
#define __memcpy(a, b, c)   memcpy(a,b,c)
 From linux kernel i386 header files, copes with odd sizes better than COPY_DWORDS would: XXX Put this in src/mesa/main/imports.h ???

Functions

static enum pipe_texture_target gl_target_to_pipe (GLenum target)
static int compressed_num_bytes (GLuint mesaFormat)
 Return nominal bytes per texel for a compressed format, 0 for non-compressed format.
static struct gl_texture_image * st_NewTextureImage (GLcontext *ctx)
 called via ctx->Driver.NewTextureImage()
static struct gl_texture_object * st_NewTextureObject (GLcontext *ctx, GLuint name, GLenum target)
 called via ctx->Driver.NewTextureObject()
static void st_DeleteTextureObject (GLcontext *ctx, struct gl_texture_object *texObj)
 called via ctx->Driver.DeleteTextureImage()
static void st_FreeTextureImageData (GLcontext *ctx, struct gl_texture_image *texImage)
 called via ctx->Driver.FreeTexImageData()
static void * do_memcpy (void *dest, const void *src, size_t n)
 The system memcpy (at least on ubuntu 5.10) has problems copying to agp (writecombined) memory from a source which isn't 64-byte aligned - there is a 4x performance falloff.
static int logbase2 (int n)
static void guess_and_alloc_texture (struct st_context *st, struct st_texture_object *stObj, const struct st_texture_image *stImage)
 Allocate a pipe_texture object for the given st_texture_object using the given st_texture_image to guess the mipmap size/levels.
static void strip_texture_border (GLint border, GLint *width, GLint *height, GLint *depth, const struct gl_pixelstore_attrib *unpack, struct gl_pixelstore_attrib *unpackNew)
 Adjust pixel unpack params and image dimensions to strip off the texture border.
static void st_TexImage (GLcontext *ctx, GLint dims, GLenum target, GLint level, GLint internalFormat, GLint width, GLint height, GLint depth, GLint border, GLenum format, GLenum type, const void *pixels, const struct gl_pixelstore_attrib *unpack, struct gl_texture_object *texObj, struct gl_texture_image *texImage, GLsizei imageSize, int compressed)
 Do glTexImage1/2/3D().
static void st_TexImage3D (GLcontext *ctx, GLenum target, GLint level, GLint internalFormat, GLint width, GLint height, GLint depth, GLint border, GLenum format, GLenum type, const void *pixels, const struct gl_pixelstore_attrib *unpack, struct gl_texture_object *texObj, struct gl_texture_image *texImage)
static void st_TexImage2D (GLcontext *ctx, GLenum target, GLint level, GLint internalFormat, GLint width, GLint height, GLint border, GLenum format, GLenum type, const void *pixels, const struct gl_pixelstore_attrib *unpack, struct gl_texture_object *texObj, struct gl_texture_image *texImage)
static void st_TexImage1D (GLcontext *ctx, GLenum target, GLint level, GLint internalFormat, GLint width, GLint border, GLenum format, GLenum type, const void *pixels, const struct gl_pixelstore_attrib *unpack, struct gl_texture_object *texObj, struct gl_texture_image *texImage)
static void st_CompressedTexImage2D (GLcontext *ctx, GLenum target, GLint level, GLint internalFormat, GLint width, GLint height, GLint border, GLsizei imageSize, const GLvoid *data, struct gl_texture_object *texObj, struct gl_texture_image *texImage)
static void st_get_tex_image (GLcontext *ctx, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels, struct gl_texture_object *texObj, struct gl_texture_image *texImage, int compressed)
 Need to map texture image into memory before copying image data, then unmap it.
static void st_GetTexImage (GLcontext *ctx, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels, struct gl_texture_object *texObj, struct gl_texture_image *texImage)
static void st_GetCompressedTexImage (GLcontext *ctx, GLenum target, GLint level, GLvoid *pixels, const struct gl_texture_object *texObj, const struct gl_texture_image *texImage)
static void st_TexSubimage (GLcontext *ctx, GLint dims, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint width, GLint height, GLint depth, GLenum format, GLenum type, const void *pixels, const struct gl_pixelstore_attrib *packing, struct gl_texture_object *texObj, struct gl_texture_image *texImage)
static void st_TexSubImage3D (GLcontext *ctx, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels, const struct gl_pixelstore_attrib *packing, struct gl_texture_object *texObj, struct gl_texture_image *texImage)
static void st_TexSubImage2D (GLcontext *ctx, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels, const struct gl_pixelstore_attrib *packing, struct gl_texture_object *texObj, struct gl_texture_image *texImage)
static void st_TexSubImage1D (GLcontext *ctx, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels, const struct gl_pixelstore_attrib *packing, struct gl_texture_object *texObj, struct gl_texture_image *texImage)
static uint texture_face (GLenum target)
 Return 0 for GL_TEXTURE_CUBE_MAP_POSITIVE_X, 1 for GL_TEXTURE_CUBE_MAP_NEGATIVE_X, etc.
static void fallback_copy_texsubimage (GLcontext *ctx, GLenum target, GLint level, struct st_renderbuffer *strb, struct st_texture_image *stImage, GLenum baseFormat, GLint destX, GLint destY, GLint destZ, GLint srcX, GLint srcY, GLsizei width, GLsizei height)
 Do a CopyTexSubImage operation by mapping the source surface and dest surface and using get_tile()/put_tile() to access the pixels/texels.
static void st_copy_texsubimage (GLcontext *ctx, GLenum target, GLint level, GLint destX, GLint destY, GLint destZ, GLint srcX, GLint srcY, GLsizei width, GLsizei height)
 Do a CopyTex[Sub]Image1/2/3D() using a hardware (blit) path if possible.
static void st_CopyTexImage1D (GLcontext *ctx, GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border)
static void st_CopyTexImage2D (GLcontext *ctx, GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
static void st_CopyTexSubImage1D (GLcontext *ctx, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width)
static void st_CopyTexSubImage2D (GLcontext *ctx, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
static void st_CopyTexSubImage3D (GLcontext *ctx, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
static void calculate_first_last_level (struct st_texture_object *stObj)
 Compute which mipmap levels that really need to be sent to the hardware.
static void copy_image_data_to_texture (struct st_context *st, struct st_texture_object *stObj, GLuint dstLevel, struct st_texture_image *stImage)
GLboolean st_finalize_texture (GLcontext *ctx, struct pipe_context *pipe, struct gl_texture_object *tObj, GLboolean *needFlush)
 Called during state validation.
struct gl_texture_object * st_get_default_texture (struct st_context *st)
 Returns pointer to a default/dummy texture.
void st_init_texture_functions (struct dd_function_table *functions)


Define Documentation

#define __memcpy ( a,
b,
 )     memcpy(a,b,c)

From linux kernel i386 header files, copes with odd sizes better than COPY_DWORDS would: XXX Put this in src/mesa/main/imports.h ???

Definition at line 187 of file st_cb_texture.c.

#define DBG   if (0) printf

Definition at line 58 of file st_cb_texture.c.


Function Documentation

static void calculate_first_last_level ( struct st_texture_object stObj  )  [static]

Compute which mipmap levels that really need to be sent to the hardware.

This depends on the base image size, GL_TEXTURE_MIN_LOD, GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL.

Definition at line 1277 of file st_cb_texture.c.

References st_texture_object::base, st_texture_object::lastLevel, and MIN2.

01278 {
01279    struct gl_texture_object *tObj = &stObj->base;
01280 
01281    /* These must be signed values.  MinLod and MaxLod can be negative numbers,
01282     * and having firstLevel and lastLevel as signed prevents the need for
01283     * extra sign checks.
01284     */
01285    int firstLevel;
01286    int lastLevel;
01287 
01288    /* Yes, this looks overly complicated, but it's all needed.
01289     */
01290    switch (tObj->Target) {
01291    case GL_TEXTURE_1D:
01292    case GL_TEXTURE_2D:
01293    case GL_TEXTURE_3D:
01294    case GL_TEXTURE_CUBE_MAP:
01295       if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) {
01296          /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL.
01297           */
01298          firstLevel = lastLevel = tObj->BaseLevel;
01299       }
01300       else {
01301          firstLevel = 0;
01302          lastLevel = MIN2(tObj->MaxLevel,
01303                           (int) tObj->Image[0][tObj->BaseLevel]->WidthLog2);
01304       }
01305       break;
01306    case GL_TEXTURE_RECTANGLE_NV:
01307    case GL_TEXTURE_4D_SGIS:
01308       firstLevel = lastLevel = 0;
01309       break;
01310    default:
01311       return;
01312    }
01313 
01314    stObj->lastLevel = lastLevel;
01315 }

static int compressed_num_bytes ( GLuint  mesaFormat  )  [static]

Return nominal bytes per texel for a compressed format, 0 for non-compressed format.

Definition at line 90 of file st_cb_texture.c.

00091 {
00092    switch(mesaFormat) {
00093 #if FEATURE_texture_fxt1
00094    case MESA_FORMAT_RGB_FXT1:
00095    case MESA_FORMAT_RGBA_FXT1:
00096 #endif
00097 #if FEATURE_texture_s3tc
00098    case MESA_FORMAT_RGB_DXT1:
00099    case MESA_FORMAT_RGBA_DXT1:
00100       return 2;
00101    case MESA_FORMAT_RGBA_DXT3:
00102    case MESA_FORMAT_RGBA_DXT5:
00103       return 4;
00104 #endif
00105    default:
00106       return 0;
00107    }
00108 }

static void copy_image_data_to_texture ( struct st_context st,
struct st_texture_object stObj,
GLuint  dstLevel,
struct st_texture_image stImage 
) [static]

Definition at line 1319 of file st_cb_texture.c.

References assert, st_texture_image::base, pipe_texture::block, st_texture_image::face, st_context::pipe, pipe_texture_reference(), st_texture_object::pt, st_texture_image::pt, pipe_format_block::size, st_texture_image_copy(), and st_texture_image_data().

01323 {
01324    if (stImage->pt) {
01325       /* Copy potentially with the blitter:
01326        */
01327       st_texture_image_copy(st->pipe,
01328                             stObj->pt, dstLevel,  /* dest texture, level */
01329                             stImage->pt, /* src texture */
01330                             stImage->face
01331                             );
01332 
01333       pipe_texture_reference(&stImage->pt, NULL);
01334    }
01335    else if (stImage->base.Data) {
01336       assert(stImage->base.Data != NULL);
01337 
01338       /* More straightforward upload.  
01339        */
01340       st_texture_image_data(st->pipe,
01341                                stObj->pt,
01342                                stImage->face,
01343                                dstLevel,
01344                                stImage->base.Data,
01345                                stImage->base.RowStride * 
01346                                stObj->pt->block.size,
01347                                stImage->base.RowStride *
01348                                stImage->base.Height *
01349                                stObj->pt->block.size);
01350       _mesa_align_free(stImage->base.Data);
01351       stImage->base.Data = NULL;
01352    }
01353 
01354    pipe_texture_reference(&stImage->pt, stObj->pt);
01355 }

static void* do_memcpy ( void *  dest,
const void *  src,
size_t  n 
) [static]

The system memcpy (at least on ubuntu 5.10) has problems copying to agp (writecombined) memory from a source which isn't 64-byte aligned - there is a 4x performance falloff.

The x86 __memcpy is immune to this but is slightly slower (10-ish) than the system memcpy.

The sse_memcpy seems to have a slight cliff at 64/32 bytes, but isn't much faster than x86_memcpy for agp copies.

TODO: switch dynamically.

Definition at line 205 of file st_cb_texture.c.

References __memcpy.

00206 {
00207    if ((((unsigned) src) & 63) || (((unsigned) dest) & 63)) {
00208       return __memcpy(dest, src, n);
00209    }
00210    else
00211       return memcpy(dest, src, n);
00212 }

static void fallback_copy_texsubimage ( GLcontext *  ctx,
GLenum  target,
GLint  level,
struct st_renderbuffer strb,
struct st_texture_image stImage,
GLenum  baseFormat,
GLint  destX,
GLint  destY,
GLint  destZ,
GLint  srcX,
GLint  srcY,
GLsizei  width,
GLsizei  height 
) [static]

Do a CopyTexSubImage operation by mapping the source surface and dest surface and using get_tile()/put_tile() to access the pixels/texels.

Note: srcY=0=TOP of renderbuffer

Definition at line 925 of file st_cb_texture.c.

References assert, st_texture_image::base, st_renderbuffer::Base, pipe_screen::get_tex_surface, MAX_WIDTH, PIPE_BUFFER_USAGE_CPU_READ, PIPE_BUFFER_USAGE_CPU_WRITE, pipe_get_tile_rgba(), pipe_get_tile_z(), pipe_put_tile_z(), st_texture_image::pt, pipe_context::screen, st_fb_orientation(), st_texture_image_map(), st_texture_image_unmap(), pipe_surface::stride, st_texture_image::surface, pipe_screen::tex_surface_release, st_renderbuffer::texture, texture_face(), and Y_0_TOP.

00934 {
00935    struct pipe_context *pipe = ctx->st->pipe;
00936    struct pipe_screen *screen = pipe->screen;
00937    const uint face = texture_face(target);
00938    struct pipe_texture *pt = stImage->pt;
00939    struct pipe_surface *src_surf, *dest_surf;
00940 
00941    /* We'd use strb->surface, here but it's created for GPU read/write only */
00942    src_surf = pipe->screen->get_tex_surface( pipe->screen,
00943                                              strb->texture,
00944                                              0, 0, 0,
00945                                              PIPE_BUFFER_USAGE_CPU_READ);
00946 
00947    dest_surf = screen->get_tex_surface(screen, pt, face, level, destZ,
00948                                        PIPE_BUFFER_USAGE_CPU_WRITE);
00949 
00950    assert(width <= MAX_WIDTH);
00951 
00952    if (baseFormat == GL_DEPTH_COMPONENT) {
00953       const GLboolean scaleOrBias = (ctx->Pixel.DepthScale != 1.0F ||
00954                                      ctx->Pixel.DepthBias != 0.0F);
00955       GLint row, yStep;
00956 
00957       /* determine bottom-to-top vs. top-to-bottom order for src buffer */
00958       if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
00959          srcY = strb->Base.Height - 1 - srcY;
00960          yStep = -1;
00961       }
00962       else {
00963          yStep = 1;
00964       }
00965 
00966       /* To avoid a large temp memory allocation, do copy row by row */
00967       for (row = 0; row < height; row++, srcY += yStep, destY++) {
00968          uint data[MAX_WIDTH];
00969          pipe_get_tile_z(src_surf, srcX, srcY, width, 1, data);
00970          if (scaleOrBias) {
00971             _mesa_scale_and_bias_depth_uint(ctx, width, data);
00972          }
00973          pipe_put_tile_z(dest_surf, destX, destY, width, 1, data);
00974       }
00975    }
00976    else {
00977       /* RGBA format */
00978       GLfloat *tempSrc =
00979          (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
00980       GLvoid *texDest =
00981          st_texture_image_map(ctx->st, stImage, 0,PIPE_BUFFER_USAGE_CPU_WRITE);
00982 
00983       if (tempSrc && texDest) {
00984          const GLint dims = 2;
00985          struct gl_texture_image *texImage = &stImage->base;
00986          GLint dstRowStride = stImage->surface->stride;
00987          struct gl_pixelstore_attrib unpack = ctx->DefaultPacking;
00988 
00989          if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
00990             /* need to invert src */
00991             srcY = strb->Base.Height - srcY - height;
00992             unpack.Invert = GL_TRUE;
00993          }
00994 
00995          /* get float/RGBA image from framebuffer */
00996          /* XXX this usually involves a lot of int/float conversion.
00997           * try to avoid that someday.
00998           */
00999          pipe_get_tile_rgba(src_surf, srcX, srcY, width, height, tempSrc);
01000 
01001          /* Store into texture memory.
01002           * Note that this does some special things such as pixel transfer
01003           * ops and format conversion.  In particular, if the dest tex format
01004           * is actually RGBA but the user created the texture as GL_RGB we
01005           * need to fill-in/override the alpha channel with 1.0.
01006           */
01007          texImage->TexFormat->StoreImage(ctx, dims,
01008                                          texImage->_BaseFormat, 
01009                                          texImage->TexFormat, 
01010                                          texDest,
01011                                          destX, destY, destZ,
01012                                          dstRowStride,
01013                                          texImage->ImageOffsets,
01014                                          width, height, 1,
01015                                          GL_RGBA, GL_FLOAT, tempSrc, /* src */
01016                                          &unpack);
01017       }
01018       else {
01019          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
01020       }
01021 
01022       if (tempSrc)
01023          _mesa_free(tempSrc);
01024       if (texDest)
01025          st_texture_image_unmap(ctx->st, stImage);
01026    }
01027 
01028    screen->tex_surface_release(screen, &dest_surf);
01029    screen->tex_surface_release(screen, &src_surf);
01030 }

static enum pipe_texture_target gl_target_to_pipe ( GLenum  target  )  [static]

Definition at line 62 of file st_cb_texture.c.

References assert, PIPE_TEXTURE_1D, PIPE_TEXTURE_2D, PIPE_TEXTURE_3D, and PIPE_TEXTURE_CUBE.

00063 {
00064    switch (target) {
00065    case GL_TEXTURE_1D:
00066       return PIPE_TEXTURE_1D;
00067 
00068    case GL_TEXTURE_2D:
00069    case GL_TEXTURE_RECTANGLE_NV:
00070       return PIPE_TEXTURE_2D;
00071 
00072    case GL_TEXTURE_3D:
00073       return PIPE_TEXTURE_3D;
00074 
00075    case GL_TEXTURE_CUBE_MAP_ARB:
00076       return PIPE_TEXTURE_CUBE;
00077 
00078    default:
00079       assert(0);
00080       return 0;
00081    }
00082 }

static void guess_and_alloc_texture ( struct st_context st,
struct st_texture_object stObj,
const struct st_texture_image stImage 
) [static]

Allocate a pipe_texture object for the given st_texture_object using the given st_texture_image to guess the mipmap size/levels.

[comments...] Otherwise, store it in memory if (Border != 0) or (any dimension == 1).

Otherwise, if max_level >= level >= min_level, create texture with space for images from min_level down to max_level.

Otherwise, create texture with space for images from (level 0)..(1x1). Consider pruning this texture at a validation if the saving is worth it.

Definition at line 242 of file st_cb_texture.c.

References assert, st_texture_object::base, st_texture_image::base, compressed_num_bytes(), DBG, gl_target_to_pipe(), st_texture_image::level, logbase2(), MAX2, pf_is_depth_stencil(), PIPE_TEXTURE_USAGE_DEPTH_STENCIL, PIPE_TEXTURE_USAGE_RENDER_TARGET, PIPE_TEXTURE_USAGE_SAMPLER, st_texture_object::pt, st_mesa_format_to_pipe_format(), and st_texture_create().

00245 {
00246    GLuint firstLevel;
00247    GLuint lastLevel;
00248    GLuint width = stImage->base.Width2;  /* size w/out border */
00249    GLuint height = stImage->base.Height2;
00250    GLuint depth = stImage->base.Depth2;
00251    GLuint i, comp_byte = 0;
00252    enum pipe_format fmt;
00253 
00254    DBG("%s\n", __FUNCTION__);
00255 
00256    assert(!stObj->pt);
00257 
00258    if (stObj->pt &&
00259        (GLint) stImage->level > stObj->base.BaseLevel &&
00260        (stImage->base.Width == 1 ||
00261         (stObj->base.Target != GL_TEXTURE_1D &&
00262          stImage->base.Height == 1) ||
00263         (stObj->base.Target == GL_TEXTURE_3D &&
00264          stImage->base.Depth == 1)))
00265       return;
00266 
00267    /* If this image disrespects BaseLevel, allocate from level zero.
00268     * Usually BaseLevel == 0, so it's unlikely to happen.
00269     */
00270    if ((GLint) stImage->level < stObj->base.BaseLevel)
00271       firstLevel = 0;
00272    else
00273       firstLevel = stObj->base.BaseLevel;
00274 
00275 
00276    /* Figure out image dimensions at start level. 
00277     */
00278    for (i = stImage->level; i > firstLevel; i--) {
00279       if (width != 1)
00280          width <<= 1;
00281       if (height != 1)
00282          height <<= 1;
00283       if (depth != 1)
00284          depth <<= 1;
00285    }
00286 
00287    if (width == 0 || height == 0 || depth == 0) {
00288       /* no texture needed */
00289       return;
00290    }
00291 
00292    /* Guess a reasonable value for lastLevel.  This is probably going
00293     * to be wrong fairly often and might mean that we have to look at
00294     * resizable buffers, or require that buffers implement lazy
00295     * pagetable arrangements.
00296     */
00297    if ((stObj->base.MinFilter == GL_NEAREST ||
00298         stObj->base.MinFilter == GL_LINEAR) &&
00299        stImage->level == firstLevel) {
00300       lastLevel = firstLevel;
00301    }
00302    else {
00303       GLuint l2width = logbase2(width);
00304       GLuint l2height = logbase2(height);
00305       GLuint l2depth = logbase2(depth);
00306       lastLevel = firstLevel + MAX2(MAX2(l2width, l2height), l2depth);
00307    }
00308 
00309    if (stImage->base.IsCompressed)
00310       comp_byte = compressed_num_bytes(stImage->base.TexFormat->MesaFormat);
00311 
00312    fmt = st_mesa_format_to_pipe_format(stImage->base.TexFormat->MesaFormat);
00313    stObj->pt = st_texture_create(st,
00314                                  gl_target_to_pipe(stObj->base.Target),
00315                                  fmt,
00316                                  lastLevel,
00317                                  width,
00318                                  height,
00319                                  depth,
00320                                  comp_byte,
00321                                  ( (pf_is_depth_stencil(fmt) ?
00322                                    PIPE_TEXTURE_USAGE_DEPTH_STENCIL :
00323                                    PIPE_TEXTURE_USAGE_RENDER_TARGET) |
00324                                    PIPE_TEXTURE_USAGE_SAMPLER ));
00325 
00326    DBG("%s - success\n", __FUNCTION__);
00327 }

static int logbase2 ( int  n  )  [static]

Definition at line 216 of file st_cb_texture.c.

00217 {
00218    GLint i = 1, log2 = 0;
00219    while (n > i) {
00220       i *= 2;
00221       log2++;
00222    }
00223    return log2;
00224 }

static void st_CompressedTexImage2D ( GLcontext *  ctx,
GLenum  target,
GLint  level,
GLint  internalFormat,
GLint  width,
GLint  height,
GLint  border,
GLsizei  imageSize,
const GLvoid *  data,
struct gl_texture_object *  texObj,
struct gl_texture_image *  texImage 
) [static]

Definition at line 653 of file st_cb_texture.c.

References st_TexImage().

00659 {
00660    st_TexImage(ctx, 2, target, level,
00661                  internalFormat, width, height, 1, border,
00662                  0, 0, data, &ctx->Unpack, texObj, texImage, imageSize, 1);
00663 }

static void st_copy_texsubimage ( GLcontext *  ctx,
GLenum  target,
GLint  level,
GLint  destX,
GLint  destY,
GLint  destZ,
GLint  srcX,
GLint  srcY,
GLsizei  width,
GLsizei  height 
) [static]

Do a CopyTex[Sub]Image1/2/3D() using a hardware (blit) path if possible.

Note that the region to copy has already been clipped so we know we won't read from outside the source renderbuffer's bounds.

Note: srcY=0=Bottom of renderbuffer (GL convention)

Definition at line 1041 of file st_cb_texture.c.

References assert, st_renderbuffer::Base, st_texture_image::face, fallback_copy_texsubimage(), pipe_texture::format, pipe_surface::format, pipe_screen::get_tex_surface, pipe_surface::height, pipe_screen::is_format_supported, st_texture_image::level, PIPE_BUFFER_USAGE_GPU_WRITE, pipe_surface_reference(), PIPE_TEX_MIPFILTER_NEAREST, PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_RENDER_TARGET, PIPE_TEXTURE_USAGE_SAMPLER, st_texture_image::pt, pipe_context::screen, st_fb_orientation(), st_finish(), st_renderbuffer(), st_texture_image(), st_renderbuffer::surface, pipe_context::surface_copy, util_blit_pixels(), and Y_0_TOP.

01046 {
01047    struct gl_texture_unit *texUnit =
01048       &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
01049    struct gl_texture_object *texObj =
01050       _mesa_select_tex_object(ctx, texUnit, target);
01051    struct gl_texture_image *texImage =
01052       _mesa_select_tex_image(ctx, texObj, target, level);
01053    struct st_texture_image *stImage = st_texture_image(texImage);
01054    const GLenum texBaseFormat = texImage->InternalFormat;
01055    struct gl_framebuffer *fb = ctx->ReadBuffer;
01056    struct st_renderbuffer *strb;
01057    struct pipe_context *pipe = ctx->st->pipe;
01058    struct pipe_screen *screen = pipe->screen;
01059    enum pipe_format dest_format, src_format;
01060    GLboolean use_fallback = GL_TRUE;
01061    GLboolean matching_base_formats;
01062 
01063    /* any rendering in progress must complete before we grab the fb image */
01064    st_finish(ctx->st);
01065 
01066    /* determine if copying depth or color data */
01067    if (texBaseFormat == GL_DEPTH_COMPONENT) {
01068       strb = st_renderbuffer(fb->_DepthBuffer);
01069    }
01070    else if (texBaseFormat == GL_DEPTH_STENCIL_EXT) {
01071       strb = st_renderbuffer(fb->_StencilBuffer);
01072    }
01073    else {
01074       /* texBaseFormat == GL_RGB, GL_RGBA, GL_ALPHA, etc */
01075       strb = st_renderbuffer(fb->_ColorReadBuffer);
01076    }
01077 
01078    assert(strb);
01079    assert(strb->surface);
01080    assert(stImage->pt);
01081 
01082    src_format = strb->surface->format;
01083    dest_format = stImage->pt->format;
01084 
01085    /*
01086     * Determine if the src framebuffer and dest texture have the same
01087     * base format.  We need this to detect a case such as the framebuffer
01088     * being GL_RGBA but the texture being GL_RGB.  If the actual hardware
01089     * texture format stores RGBA we need to set A=1 (overriding the
01090     * framebuffer's alpha values).  We can't do that with the blit or
01091     * textured-quad paths.
01092     */
01093    matching_base_formats = (strb->Base._BaseFormat == texImage->_BaseFormat);
01094 
01095    if (matching_base_formats && ctx->_ImageTransferState == 0x0) {
01096       /* try potential hardware path */
01097       struct pipe_surface *dest_surface = NULL;
01098 
01099       if (src_format == dest_format) {
01100          /* use surface_copy() / blit */
01101          boolean do_flip = (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP);
01102 
01103          dest_surface = screen->get_tex_surface(screen, stImage->pt,
01104                                                 stImage->face, stImage->level,
01105                                                 destZ,
01106                                                 PIPE_BUFFER_USAGE_GPU_WRITE);
01107          if (do_flip)
01108             srcY = strb->surface->height - srcY - height;
01109 
01110          /* for surface_copy(), y=0=top, always */
01111          pipe->surface_copy(pipe,
01112                             do_flip,
01113                             /* dest */
01114                             dest_surface,
01115                             destX, destY,
01116                             /* src */
01117                             strb->surface,
01118                             srcX, srcY,
01119                             /* size */
01120                             width, height);
01121          use_fallback = GL_FALSE;
01122       }
01123       else if (screen->is_format_supported(screen, src_format,
01124                                            PIPE_TEXTURE_2D, 
01125                                            PIPE_TEXTURE_USAGE_SAMPLER,
01126                                            0) &&
01127                screen->is_format_supported(screen, dest_format,
01128                                            PIPE_TEXTURE_2D, 
01129                                            PIPE_TEXTURE_USAGE_RENDER_TARGET,
01130                                            0)) {
01131          /* draw textured quad to do the copy */
01132          boolean do_flip = (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP);
01133          int srcY0, srcY1;
01134 
01135          dest_surface = screen->get_tex_surface(screen, stImage->pt,
01136                                                 stImage->face, stImage->level,
01137                                                 destZ,
01138                                                 PIPE_BUFFER_USAGE_GPU_WRITE);
01139 
01140          if (do_flip) {
01141             srcY1 = strb->Base.Height - srcY - height;
01142             srcY0 = srcY1 + height;
01143          }
01144          else {
01145             srcY0 = srcY;
01146             srcY1 = srcY0 + height;
01147          }
01148          util_blit_pixels(ctx->st->blit,
01149                           strb->surface,
01150                           srcX, srcY0,
01151                           srcX + width, srcY1,
01152                           dest_surface,
01153                           destX, destY,
01154                           destX + width, destY + height,
01155                           0.0, PIPE_TEX_MIPFILTER_NEAREST);
01156          use_fallback = GL_FALSE;
01157       }
01158 
01159       if (dest_surface)
01160          pipe_surface_reference(&dest_surface, NULL);
01161    }
01162 
01163    if (use_fallback) {
01164       /* software fallback */
01165       fallback_copy_texsubimage(ctx, target, level,
01166                                 strb, stImage, texBaseFormat,
01167                                 destX, destY, destZ,
01168                                 srcX, srcY, width, height);
01169    }
01170 
01171    if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
01172       ctx->Driver.GenerateMipmap(ctx, target, texObj);
01173    }
01174 }

static void st_CopyTexImage1D ( GLcontext *  ctx,
GLenum  target,
GLint  level,
GLenum  internalFormat,
GLint  x,
GLint  y,
GLsizei  width,
GLint  border 
) [static]

Definition at line 1179 of file st_cb_texture.c.

References st_copy_texsubimage().

01182 {
01183    struct gl_texture_unit *texUnit =
01184       &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
01185    struct gl_texture_object *texObj =
01186       _mesa_select_tex_object(ctx, texUnit, target);
01187    struct gl_texture_image *texImage =
01188       _mesa_select_tex_image(ctx, texObj, target, level);
01189 
01190 #if 0
01191    if (border)
01192       goto fail;
01193 #endif
01194 
01195    /* Setup or redefine the texture object, texture and texture
01196     * image.  Don't populate yet.  
01197     */
01198    ctx->Driver.TexImage1D(ctx, target, level, internalFormat,
01199                           width, border,
01200                           GL_RGBA, CHAN_TYPE, NULL,
01201                           &ctx->DefaultPacking, texObj, texImage);
01202 
01203    st_copy_texsubimage(ctx, target, level,
01204                        0, 0, 0,  /* destX,Y,Z */
01205                        x, y, width, 1);  /* src X, Y, size */
01206 }

static void st_CopyTexImage2D ( GLcontext *  ctx,
GLenum  target,
GLint  level,
GLenum  internalFormat,
GLint  x,
GLint  y,
GLsizei  width,
GLsizei  height,
GLint  border 
) [static]

Definition at line 1210 of file st_cb_texture.c.

References st_copy_texsubimage().

01214 {
01215    struct gl_texture_unit *texUnit =
01216       &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
01217    struct gl_texture_object *texObj =
01218       _mesa_select_tex_object(ctx, texUnit, target);
01219    struct gl_texture_image *texImage =
01220       _mesa_select_tex_image(ctx, texObj, target, level);
01221 
01222    /* Setup or redefine the texture object, texture and texture
01223     * image.  Don't populate yet.  
01224     */
01225    ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
01226                           width, height, border,
01227                           GL_RGBA, CHAN_TYPE, NULL,
01228                           &ctx->DefaultPacking, texObj, texImage);
01229 
01230    st_copy_texsubimage(ctx, target, level,
01231                        0, 0, 0,  /* destX,Y,Z */
01232                        x, y, width, height);  /* src X, Y, size */
01233 }

static void st_CopyTexSubImage1D ( GLcontext *  ctx,
GLenum  target,
GLint  level,
GLint  xoffset,
GLint  x,
GLint  y,
GLsizei  width 
) [static]

Definition at line 1237 of file st_cb_texture.c.

References st_copy_texsubimage().

01239 {
01240    const GLint yoffset = 0, zoffset = 0;
01241    const GLsizei height = 1;
01242    st_copy_texsubimage(ctx, target, level,
01243                        xoffset, yoffset, zoffset,  /* destX,Y,Z */
01244                        x, y, width, height);  /* src X, Y, size */
01245 }

static void st_CopyTexSubImage2D ( GLcontext *  ctx,
GLenum  target,
GLint  level,
GLint  xoffset,
GLint  yoffset,
GLint  x,
GLint  y,
GLsizei  width,
GLsizei  height 
) [static]

Definition at line 1249 of file st_cb_texture.c.

References st_copy_texsubimage().

01252 {
01253    const GLint zoffset = 0;
01254    st_copy_texsubimage(ctx, target, level,
01255                        xoffset, yoffset, zoffset,  /* destX,Y,Z */
01256                        x, y, width, height);  /* src X, Y, size */
01257 }

static void st_CopyTexSubImage3D ( GLcontext *  ctx,
GLenum  target,
GLint  level,
GLint  xoffset,
GLint  yoffset,
GLint  zoffset,
GLint  x,
GLint  y,
GLsizei  width,
GLsizei  height 
) [static]

Definition at line 1261 of file st_cb_texture.c.

References st_copy_texsubimage().

01264 {
01265    st_copy_texsubimage(ctx, target, level,
01266                        xoffset, yoffset, zoffset,  /* destX,Y,Z */
01267                        x, y, width, height);  /* src X, Y, size */
01268 }

static void st_DeleteTextureObject ( GLcontext *  ctx,
struct gl_texture_object *  texObj 
) [static]

called via ctx->Driver.DeleteTextureImage()

Definition at line 135 of file st_cb_texture.c.

References pipe_texture_reference(), st_texture_object::pt, and st_texture_object().

00137 {
00138    struct st_texture_object *stObj = st_texture_object(texObj);
00139    if (stObj->pt)
00140       pipe_texture_reference(&stObj->pt, NULL);
00141 
00142    _mesa_delete_texture_object(ctx, texObj);
00143 }

GLboolean st_finalize_texture ( GLcontext *  ctx,
struct pipe_context pipe,
struct gl_texture_object *  tObj,
GLboolean *  needFlush 
)

Called during state validation.

When this function is finished, the texture object should be ready for rendering.

Returns:
GL_TRUE for success, GL_FALSE for failure (out of mem)

Definition at line 1364 of file st_cb_texture.c.

References assert, st_texture_image::base, st_texture_object::base, pipe_texture::block, calculate_first_last_level(), pipe_texture::compressed, compressed_num_bytes(), copy_image_data_to_texture(), pipe_texture::depth, pipe_texture::format, gl_target_to_pipe(), pipe_format_block::height, pipe_texture::height, pipe_texture::last_level, st_texture_object::lastLevel, st_texture_image::level, pf_is_depth_stencil(), pipe_texture_reference(), pipe_texture_release(), PIPE_TEXTURE_USAGE_DEPTH_STENCIL, PIPE_TEXTURE_USAGE_RENDER_TARGET, PIPE_TEXTURE_USAGE_SAMPLER, st_texture_object::pt, st_texture_image::pt, pipe_format_block::size, st_mesa_format_to_pipe_format(), ST_NEW_FRAMEBUFFER, st_texture_create(), st_texture_image(), st_texture_object(), pipe_texture::target, pipe_format_block::width, and pipe_texture::width.

01368 {
01369    struct st_texture_object *stObj = st_texture_object(tObj);
01370    const GLuint nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
01371    int comp_byte = 0;
01372    int cpp;
01373    GLuint face;
01374    struct st_texture_image *firstImage;
01375 
01376    *needFlush = GL_FALSE;
01377 
01378    /* We know/require this is true by now: 
01379     */
01380    assert(stObj->base._Complete);
01381 
01382    /* What levels must the texture include at a minimum?
01383     */
01384    calculate_first_last_level(stObj);
01385    firstImage = st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]);
01386 
01387    /* If both firstImage and stObj point to a texture which can contain
01388     * all active images, favour firstImage.  Note that because of the
01389     * completeness requirement, we know that the image dimensions
01390     * will match.
01391     */
01392    if (firstImage->pt &&
01393        firstImage->pt != stObj->pt &&
01394        firstImage->pt->last_level >= stObj->lastLevel) {
01395 
01396       pipe_texture_reference(&stObj->pt, firstImage->pt);
01397    }
01398 
01399    /* FIXME: determine format block instead of cpp */
01400    if (firstImage->base.IsCompressed) {
01401       comp_byte = compressed_num_bytes(firstImage->base.TexFormat->MesaFormat);
01402       cpp = comp_byte;
01403    }
01404    else {
01405       cpp = firstImage->base.TexFormat->TexelBytes;
01406    }
01407 
01408    /* If we already have a gallium texture, check that it matches the texture
01409     * object's format, target, size, num_levels, etc.
01410     */
01411    if (stObj->pt) {
01412       const enum pipe_format fmt =
01413          st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat);
01414       if (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) ||
01415           stObj->pt->format != fmt ||
01416           stObj->pt->last_level < stObj->lastLevel ||
01417           stObj->pt->width[0] != firstImage->base.Width2 ||
01418           stObj->pt->height[0] != firstImage->base.Height2 ||
01419           stObj->pt->depth[0] != firstImage->base.Depth2 ||
01420           stObj->pt->block.size != cpp ||
01421           stObj->pt->block.width != 1 ||
01422           stObj->pt->block.height != 1 ||
01423           stObj->pt->compressed != firstImage->base.IsCompressed) {
01424          pipe_texture_release(&stObj->pt);
01425          ctx->st->dirty.st |= ST_NEW_FRAMEBUFFER;
01426       }
01427    }
01428 
01429    /* May need to create a new gallium texture:
01430     */
01431    if (!stObj->pt) {
01432       const enum pipe_format fmt =
01433          st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat);
01434       stObj->pt = st_texture_create(ctx->st,
01435                                     gl_target_to_pipe(stObj->base.Target),
01436                                     fmt,
01437                                     stObj->lastLevel,
01438                                     firstImage->base.Width2,
01439                                     firstImage->base.Height2,
01440                                     firstImage->base.Depth2,
01441                                     comp_byte,
01442                                     ( (pf_is_depth_stencil(fmt) ?
01443                                       PIPE_TEXTURE_USAGE_DEPTH_STENCIL :
01444                                       PIPE_TEXTURE_USAGE_RENDER_TARGET) |
01445                                       PIPE_TEXTURE_USAGE_SAMPLER ));
01446 
01447       if (!stObj->pt) {
01448          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
01449          return GL_FALSE;
01450       }
01451    }
01452 
01453    /* Pull in any images not in the object's texture:
01454     */
01455    for (face = 0; face < nr_faces; face++) {
01456       GLuint level;
01457       for (level = 0; level <= stObj->lastLevel; level++) {
01458          struct st_texture_image *stImage =
01459             st_texture_image(stObj->base.Image[face][stObj->base.BaseLevel + level]);
01460 
01461          /* Need to import images in main memory or held in other textures.
01462           */
01463          if (stImage && stObj->pt != stImage->pt) {
01464             copy_image_data_to_texture(ctx->st, stObj, level, stImage);
01465             *needFlush = GL_TRUE;
01466          }
01467       }
01468    }
01469 
01470    return GL_TRUE;
01471 }

static void st_FreeTextureImageData ( GLcontext *  ctx,
struct gl_texture_image *  texImage 
) [static]

called via ctx->Driver.FreeTexImageData()

Definition at line 148 of file st_cb_texture.c.

References DBG, pipe_texture_reference(), st_texture_image::pt, and st_texture_image().

00149 {
00150    struct st_texture_image *stImage = st_texture_image(texImage);
00151 
00152    DBG("%s\n", __FUNCTION__);
00153 
00154    if (stImage->pt) {
00155       pipe_texture_reference(&stImage->pt, NULL);
00156    }
00157 
00158    if (texImage->Data) {
00159       _mesa_align_free(texImage->Data);
00160       texImage->Data = NULL;
00161    }
00162 }

struct gl_texture_object* st_get_default_texture ( struct st_context st  )  [read]

Returns pointer to a default/dummy texture.

This is typically used when the current shader has tex/sample instructions but the user has not provided a (any) texture(s).

Definition at line 1480 of file st_cb_texture.c.

References st_context::ctx, st_context::default_texture, and st_TexImage().

01481 {
01482    if (!st->default_texture) {
01483       static const GLenum target = GL_TEXTURE_2D;
01484       GLubyte pixels[16][16][4];
01485       struct gl_texture_object *texObj;
01486       struct gl_texture_image *texImg;
01487 
01488       /* init image to gray */
01489       memset(pixels, 127, sizeof(pixels));
01490 
01491       texObj = st->ctx->Driver.NewTextureObject(st->ctx, 0, target);
01492 
01493       texImg = _mesa_get_tex_image(st->ctx, texObj, target, 0);
01494 
01495       _mesa_init_teximage_fields(st->ctx, target, texImg,
01496                                  16, 16, 1, 0,  /* w, h, d, border */
01497                                  GL_RGBA);
01498 
01499       st_TexImage(st->ctx, 2, target,
01500                   0, GL_RGBA,    /* level, intformat */
01501                   16, 16, 1, 0,  /* w, h, d, border */
01502                   GL_RGBA, GL_UNSIGNED_BYTE, pixels,
01503                   &st->ctx->DefaultPacking,
01504                   texObj, texImg,
01505                   0, 0);
01506 
01507       texObj->MinFilter = GL_NEAREST;
01508       texObj->MagFilter = GL_NEAREST;
01509       texObj->_Complete = GL_TRUE;
01510 
01511       st->default_texture = texObj;
01512    }
01513    return st->default_texture;
01514 }

static void st_get_tex_image ( GLcontext *  ctx,
GLenum  target,
GLint  level,
GLenum  format,
GLenum  type,
GLvoid *  pixels,
struct gl_texture_object *  texObj,
struct gl_texture_image *  texImage,
int  compressed 
) [static]

Need to map texture image into memory before copying image data, then unmap it.

Definition at line 671 of file st_cb_texture.c.

References assert, pipe_texture::block, PIPE_BUFFER_USAGE_CPU_READ, st_texture_image::pt, pipe_format_block::size, st_texture_image(), st_texture_image_map(), st_texture_image_unmap(), pipe_surface::stride, and st_texture_image::surface.

00675 {
00676    struct st_texture_image *stImage = st_texture_image(texImage);
00677    GLuint dstImageStride = _mesa_image_image_stride(&ctx->Pack,
00678                                                     texImage->Width,
00679                                                     texImage->Height,
00680                                                     format, type);
00681    GLuint depth;
00682    GLuint i;
00683    GLubyte *dest;
00684 
00685    /* Map */
00686    if (stImage->pt) {
00687       /* Image is stored in hardware format in a buffer managed by the
00688        * kernel.  Need to explicitly map and unmap it.
00689        */
00690       texImage->Data = st_texture_image_map(ctx->st, stImage, 0,
00691                                             PIPE_BUFFER_USAGE_CPU_READ);
00692       texImage->RowStride = stImage->surface->stride / stImage->pt->block.size;
00693    }
00694    else {
00695       /* Otherwise, the image should actually be stored in
00696        * texImage->Data.  This is pretty confusing for
00697        * everybody, I'd much prefer to separate the two functions of
00698        * texImage->Data - storage for texture images in main memory
00699        * and access (ie mappings) of images.  In other words, we'd
00700        * create a new texImage->Map field and leave Data simply for
00701        * storage.
00702        */
00703       assert(texImage->Data);
00704    }
00705 
00706    depth = texImage->Depth;
00707    texImage->Depth = 1;
00708 
00709    dest = (GLubyte *) pixels;
00710 
00711    for (i = 0; i++ < depth;) {
00712       if (compressed) {
00713          _mesa_get_compressed_teximage(ctx, target, level, dest,
00714                                        texObj, texImage);
00715       } else {
00716          _mesa_get_teximage(ctx, target, level, format, type, dest,
00717                             texObj, texImage);
00718       }
00719 
00720       if (stImage->pt && i < depth) {
00721          st_texture_image_unmap(ctx->st, stImage);
00722          texImage->Data = st_texture_image_map(ctx->st, stImage, i,
00723                                                PIPE_BUFFER_USAGE_CPU_READ);
00724          dest += dstImageStride;
00725       }
00726    }
00727 
00728    texImage->Depth = depth;
00729 
00730    /* Unmap */
00731    if (stImage->pt) {
00732       st_texture_image_unmap(ctx->st, stImage);
00733       texImage->Data = NULL;
00734    }
00735 }

static void st_GetCompressedTexImage ( GLcontext *  ctx,
GLenum  target,
GLint  level,
GLvoid *  pixels,
const struct gl_texture_object *  texObj,
const struct gl_texture_image *  texImage 
) [static]

Definition at line 750 of file st_cb_texture.c.

References st_get_tex_image().

00754 {
00755    st_get_tex_image(ctx, target, level, 0, 0, pixels,
00756                     (struct gl_texture_object *) texObj,
00757                     (struct gl_texture_image *) texImage, 1);
00758 }

static void st_GetTexImage ( GLcontext *  ctx,
GLenum  target,
GLint  level,
GLenum  format,
GLenum  type,
GLvoid *  pixels,
struct gl_texture_object *  texObj,
struct gl_texture_image *  texImage 
) [static]

Definition at line 739 of file st_cb_texture.c.

References st_get_tex_image().

00743 {
00744    st_get_tex_image(ctx, target, level, format, type, pixels,
00745                     texObj, texImage, 0);
00746 }

void st_init_texture_functions ( struct dd_function_table *  functions  ) 

Definition at line 1518 of file st_cb_texture.c.

References do_memcpy(), st_ChooseTextureFormat(), st_CompressedTexImage2D(), st_CopyTexImage1D(), st_CopyTexImage2D(), st_CopyTexSubImage1D(), st_CopyTexSubImage2D(), st_CopyTexSubImage3D(), st_DeleteTextureObject(), st_FreeTextureImageData(), st_generate_mipmap(), st_GetCompressedTexImage(), st_GetTexImage(), st_NewTextureImage(), st_NewTextureObject(), st_TexImage1D(), st_TexImage2D(), st_TexImage3D(), st_TexSubImage1D(), st_TexSubImage2D(), and st_TexSubImage3D().

01519 {
01520    functions->ChooseTextureFormat = st_ChooseTextureFormat;
01521    functions->TexImage1D = st_TexImage1D;
01522    functions->TexImage2D = st_TexImage2D;
01523    functions->TexImage3D = st_TexImage3D;
01524    functions->TexSubImage1D = st_TexSubImage1D;
01525    functions->TexSubImage2D = st_TexSubImage2D;
01526    functions->TexSubImage3D = st_TexSubImage3D;
01527    functions->CopyTexImage1D = st_CopyTexImage1D;
01528    functions->CopyTexImage2D = st_CopyTexImage2D;
01529    functions->CopyTexSubImage1D = st_CopyTexSubImage1D;
01530    functions->CopyTexSubImage2D = st_CopyTexSubImage2D;
01531    functions->CopyTexSubImage3D = st_CopyTexSubImage3D;
01532    functions->GenerateMipmap = st_generate_mipmap;
01533 
01534    functions->GetTexImage = st_GetTexImage;
01535 
01536    /* compressed texture functions */
01537    functions->CompressedTexImage2D = st_CompressedTexImage2D;
01538    functions->GetCompressedTexImage = st_GetCompressedTexImage;
01539    functions->CompressedTextureSize = _mesa_compressed_texture_size;
01540 
01541    functions->NewTextureObject = st_NewTextureObject;
01542    functions->NewTextureImage = st_NewTextureImage;
01543    functions->DeleteTexture = st_DeleteTextureObject;
01544    functions->FreeTexImageData = st_FreeTextureImageData;
01545    functions->UpdateTexturePalette = 0;
01546 
01547    functions->TextureMemCpy = do_memcpy;
01548 
01549    /* XXX Temporary until we can query pipe's texture sizes */
01550    functions->TestProxyTexImage = _mesa_test_proxy_teximage;
01551 }

static struct gl_texture_image* st_NewTextureImage ( GLcontext *  ctx  )  [static, read]

called via ctx->Driver.NewTextureImage()

Definition at line 113 of file st_cb_texture.c.

References CALLOC_STRUCT, and DBG.

00114 {
00115    DBG("%s\n", __FUNCTION__);
00116    (void) ctx;
00117    return (struct gl_texture_image *) CALLOC_STRUCT(st_texture_image);
00118 }

static struct gl_texture_object* st_NewTextureObject ( GLcontext *  ctx,
GLuint  name,
GLenum  target 
) [static, read]

called via ctx->Driver.NewTextureObject()

Definition at line 123 of file st_cb_texture.c.

References st_texture_object::base, CALLOC_STRUCT, and DBG.

00124 {
00125    struct st_texture_object *obj = CALLOC_STRUCT(st_texture_object);
00126 
00127    DBG("%s\n", __FUNCTION__);
00128    _mesa_initialize_texture_object(&obj->base, name, target);
00129 
00130    return &obj->base;
00131 }

static void st_TexImage ( GLcontext *  ctx,
GLint  dims,
GLenum  target,
GLint  level,
GLint  internalFormat,
GLint  width,
GLint  height,
GLint  depth,
GLint  border,
GLenum  format,
GLenum  type,
const void *  pixels,
const struct gl_pixelstore_attrib *  unpack,
struct gl_texture_object *  texObj,
struct gl_texture_image *  texImage,
GLsizei  imageSize,
int  compressed 
) [static]

Do glTexImage1/2/3D().

Definition at line 372 of file st_cb_texture.c.

References assert, st_texture_image::base, DBG, st_texture_image::face, FALSE, guess_and_alloc_texture(), pipe_texture::last_level, st_texture_image::level, PIPE_BUFFER_USAGE_CPU_WRITE, PIPE_TEXTURE_CUBE, pipe_texture_reference(), st_texture_object::pt, st_texture_image::pt, st_ChooseTextureFormat(), st_finish(), st_texture_image(), st_texture_image_map(), st_texture_image_unmap(), st_texture_match_image(), st_texture_object(), pipe_surface::stride, strip_texture_border(), st_texture_image::surface, pipe_texture::target, and st_texture_object::teximage_realloc.

00383 {
00384    struct st_texture_object *stObj = st_texture_object(texObj);
00385    struct st_texture_image *stImage = st_texture_image(texImage);
00386    GLint postConvWidth, postConvHeight;
00387    GLint texelBytes, sizeInBytes;
00388    GLuint dstRowStride;
00389    struct gl_pixelstore_attrib unpackNB;
00390 
00391    DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__,
00392        _mesa_lookup_enum_by_nr(target), level, width, height, depth, border);
00393 
00394    /* gallium does not support texture borders, strip it off */
00395    if (border) {
00396       strip_texture_border(border, &width, &height, &depth,
00397                            unpack, &unpackNB);
00398       unpack = &unpackNB;
00399       texImage->Width = width;
00400       texImage->Height = height;
00401       texImage->Depth = depth;
00402       texImage->Border = 0;
00403       border = 0;
00404    }
00405 
00406    postConvWidth = width;
00407    postConvHeight = height;
00408 
00409    stImage->face = _mesa_tex_target_to_face(target);
00410    stImage->level = level;
00411 
00412 #if FEATURE_convolve
00413    if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
00414       _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth,
00415                                          &postConvHeight);
00416    }
00417 #endif
00418 
00419    /* choose the texture format */
00420    texImage->TexFormat = st_ChooseTextureFormat(ctx, internalFormat,
00421                                                 format, type);
00422 
00423    _mesa_set_fetch_functions(texImage, dims);
00424 
00425    if (texImage->TexFormat->TexelBytes == 0) {
00426       /* must be a compressed format */
00427       texelBytes = 0;
00428       texImage->IsCompressed = GL_TRUE;
00429       texImage->CompressedSize =
00430          ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
00431                                            texImage->Height, texImage->Depth,
00432                                            texImage->TexFormat->MesaFormat);
00433    }
00434    else {
00435       texelBytes = texImage->TexFormat->TexelBytes;
00436       
00437       /* Minimum pitch of 32 bytes */
00438       if (postConvWidth * texelBytes < 32) {
00439          postConvWidth = 32 / texelBytes;
00440          texImage->RowStride = postConvWidth;
00441       }
00442       
00443       /* we'll set RowStride elsewhere when the texture is a "mapped" state */
00444       /*assert(texImage->RowStride == postConvWidth);*/
00445    }
00446 
00447    /* Release the reference to a potentially orphaned buffer.   
00448     * Release any old malloced memory.
00449     */
00450    if (stImage->pt) {
00451       pipe_texture_reference(&stImage->pt, NULL);
00452       assert(!texImage->Data);
00453    }
00454    else if (texImage->Data) {
00455       _mesa_align_free(texImage->Data);
00456    }
00457 
00458    if (width == 0 || height == 0 || depth == 0) {
00459       /* stop after freeing old image */
00460       return;
00461    }
00462 
00463    /* If this is the only mipmap level in the texture, could call
00464     * bmBufferData with NULL data to free the old block and avoid
00465     * waiting on any outstanding fences.
00466     */
00467    if (stObj->pt &&
00468        (stObj->teximage_realloc ||
00469         (/*stObj->pt->first_level == level &&*/
00470          stObj->pt->last_level == level &&
00471          stObj->pt->target != PIPE_TEXTURE_CUBE &&
00472          !st_texture_match_image(stObj->pt, &stImage->base,
00473                                  stImage->face, stImage->level)))) {
00474 
00475       DBG("release it\n");
00476       pipe_texture_reference(&stObj->pt, NULL);
00477       assert(!stObj->pt);
00478       stObj->teximage_realloc = FALSE;
00479    }
00480 
00481    if (!stObj->pt) {
00482       guess_and_alloc_texture(ctx->st, stObj, stImage);
00483       if (!stObj->pt) {
00484          /* Probably out of memory.
00485           * Try flushing any pending rendering, then retry.
00486           */
00487          st_finish(ctx->st);
00488          guess_and_alloc_texture(ctx->st, stObj, stImage);
00489          if (!stObj->pt) {
00490             _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
00491             return;
00492          }
00493       }
00494    }
00495 
00496    assert(!stImage->pt);
00497 
00498    if (stObj->pt &&
00499        st_texture_match_image(stObj->pt, &stImage->base,
00500                                  stImage->face, stImage->level)) {
00501 
00502       pipe_texture_reference(&stImage->pt, stObj->pt);
00503       assert(stImage->pt);
00504    }
00505 
00506    if (!stImage->pt)
00507       DBG("XXX: Image did not fit into texture - storing in local memory!\n");
00508 
00509    /* st_CopyTexImage calls this function with pixels == NULL, with
00510     * the expectation that the texture will be set up but nothing
00511     * more will be done.  This is where those calls return:
00512     */
00513    if (compressed) {
00514       pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, pixels,
00515                                                       unpack,
00516                                                       "glCompressedTexImage");
00517    } else {
00518       pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1,
00519                                            format, type,
00520                                            pixels, unpack, "glTexImage");
00521    }
00522    if (!pixels)
00523       return;
00524 
00525    if (stImage->pt) {
00526       texImage->Data = st_texture_image_map(ctx->st, stImage, 0,
00527                                             PIPE_BUFFER_USAGE_CPU_WRITE);
00528       if (stImage->surface)
00529          dstRowStride = stImage->surface->stride;
00530    }
00531    else {
00532       /* Allocate regular memory and store the image there temporarily.   */
00533       if (texImage->IsCompressed) {
00534          sizeInBytes = texImage->CompressedSize;
00535          dstRowStride =
00536             _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
00537          assert(dims != 3);
00538       }
00539       else {
00540          dstRowStride = postConvWidth * texelBytes;
00541          sizeInBytes = depth * dstRowStride * postConvHeight;
00542       }
00543 
00544       texImage->Data = _mesa_align_malloc(sizeInBytes, 16);
00545    }
00546 
00547    if (!texImage->Data) {
00548       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
00549       return;
00550    }
00551 
00552    DBG("Upload image %dx%dx%d row_len %x pitch %x\n",
00553        width, height, depth, width * texelBytes, dstRowStride);
00554 
00555    /* Copy data.  Would like to know when it's ok for us to eg. use
00556     * the blitter to copy.  Or, use the hardware to do the format
00557     * conversion and copy:
00558     */
00559    if (compressed) {
00560       memcpy(texImage->Data, pixels, imageSize);
00561    }
00562    else {
00563       GLuint srcImageStride = _mesa_image_image_stride(unpack, width, height,
00564                                                        format, type);
00565       int i;
00566       const GLubyte *src = (const GLubyte *) pixels;
00567 
00568       for (i = 0; i++ < depth;) {
00569          if (!texImage->TexFormat->StoreImage(ctx, dims, 
00570                                               texImage->_BaseFormat, 
00571                                               texImage->TexFormat, 
00572                                               texImage->Data,
00573                                               0, 0, 0, /* dstX/Y/Zoffset */
00574                                               dstRowStride,
00575                                               texImage->ImageOffsets,
00576                                               width, height, 1,
00577                                               format, type, src, unpack)) {
00578             _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
00579          }
00580 
00581          if (stImage->pt && i < depth) {
00582             st_texture_image_unmap(ctx->st, stImage);
00583             texImage->Data = st_texture_image_map(ctx->st, stImage, i,
00584                                                   PIPE_BUFFER_USAGE_CPU_WRITE);
00585             src += srcImageStride;
00586          }
00587       }
00588    }
00589 
00590    _mesa_unmap_teximage_pbo(ctx, unpack);
00591 
00592    if (stImage->pt) {
00593       st_texture_image_unmap(ctx->st, stImage);
00594       texImage->Data = NULL;
00595    }
00596 
00597    if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
00598       ctx->Driver.GenerateMipmap(ctx, target, texObj);
00599    }
00600 }

static void st_TexImage1D ( GLcontext *  ctx,
GLenum  target,
GLint  level,
GLint  internalFormat,
GLint  width,
GLint  border,
GLenum  format,
GLenum  type,
const void *  pixels,
const struct gl_pixelstore_attrib *  unpack,
struct gl_texture_object *  texObj,
struct gl_texture_image *  texImage 
) [static]

Definition at line 637 of file st_cb_texture.c.

References st_TexImage().

00645 {
00646    st_TexImage(ctx, 1, target, level,
00647                  internalFormat, width, 1, 1, border,
00648                  format, type, pixels, unpack, texObj, texImage, 0, 0);
00649 }

static void st_TexImage2D ( GLcontext *  ctx,
GLenum  target,
GLint  level,
GLint  internalFormat,
GLint  width,
GLint  height,
GLint  border,
GLenum  format,
GLenum  type,
const void *  pixels,
const struct gl_pixelstore_attrib *  unpack,
struct gl_texture_object *  texObj,
struct gl_texture_image *  texImage 
) [static]

Definition at line 621 of file st_cb_texture.c.

References st_TexImage().

00629 {
00630    st_TexImage(ctx, 2, target, level,
00631                  internalFormat, width, height, 1, border,
00632                  format, type, pixels, unpack, texObj, texImage, 0, 0);
00633 }

static void st_TexImage3D ( GLcontext *  ctx,
GLenum  target,
GLint  level,
GLint  internalFormat,
GLint  width,
GLint  height,
GLint  depth,
GLint  border,
GLenum  format,
GLenum  type,
const void *  pixels,
const struct gl_pixelstore_attrib *  unpack,
struct gl_texture_object *  texObj,
struct gl_texture_image *  texImage 
) [static]

Definition at line 604 of file st_cb_texture.c.

References st_TexImage().

00613 {
00614    st_TexImage(ctx, 3, target, level,
00615                  internalFormat, width, height, depth, border,
00616                  format, type, pixels, unpack, texObj, texImage, 0, 0);
00617 }

static void st_TexSubimage ( GLcontext *  ctx,
GLint  dims,
GLenum  target,
GLint  level,
GLint  xoffset,
GLint  yoffset,
GLint  zoffset,
GLint  width,
GLint  height,
GLint  depth,
GLenum  format,
GLenum  type,
const void *  pixels,
const struct gl_pixelstore_attrib *  packing,
struct gl_texture_object *  texObj,
struct gl_texture_image *  texImage 
) [static]

Definition at line 763 of file st_cb_texture.c.

References DBG, PIPE_BUFFER_USAGE_CPU_WRITE, st_texture_image::pt, st_texture_image(), st_texture_image_map(), st_texture_image_unmap(), pipe_surface::stride, and st_texture_image::surface.

00772 {
00773    struct st_texture_image *stImage = st_texture_image(texImage);
00774    GLuint dstRowStride;
00775    GLuint srcImageStride = _mesa_image_image_stride(packing, width, height,
00776                                                     format, type);
00777    int i;
00778    const GLubyte *src;
00779 
00780    DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__,
00781        _mesa_lookup_enum_by_nr(target),
00782        level, xoffset, yoffset, width, height);
00783 
00784    pixels =
00785       _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, format,
00786                                   type, pixels, packing, "glTexSubImage2D");
00787    if (!pixels)
00788       return;
00789 
00790    /* Map buffer if necessary.  Need to lock to prevent other contexts
00791     * from uploading the buffer under us.
00792     */
00793    if (stImage->pt) {
00794       texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset, 
00795                                             PIPE_BUFFER_USAGE_CPU_WRITE);
00796       if (stImage->surface)
00797          dstRowStride = stImage->surface->stride;
00798    }
00799 
00800    if (!texImage->Data) {
00801       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
00802       return;
00803    }
00804 
00805    src = (const GLubyte *) pixels;
00806 
00807    for (i = 0; i++ < depth;) {
00808       if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat,
00809                                            texImage->TexFormat,
00810                                            texImage->Data,
00811                                            xoffset, yoffset, 0,
00812                                            dstRowStride,
00813                                            texImage->ImageOffsets,
00814                                            width, height, 1,
00815                                            format, type, src, packing)) {
00816          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
00817       }
00818 
00819       if (stImage->pt && i < depth) {
00820          /* map next slice of 3D texture */
00821          st_texture_image_unmap(ctx->st, stImage);
00822          texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset + i,
00823                                                PIPE_BUFFER_USAGE_CPU_WRITE);
00824          src += srcImageStride;
00825       }
00826    }
00827 
00828    if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
00829       ctx->Driver.GenerateMipmap(ctx, target, texObj);
00830    }
00831 
00832    _mesa_unmap_teximage_pbo(ctx, packing);
00833 
00834    if (stImage->pt) {
00835       st_texture_image_unmap(ctx->st, stImage);
00836       texImage->Data = NULL;
00837    }
00838 }

static void st_TexSubImage1D ( GLcontext *  ctx,
GLenum  target,
GLint  level,
GLint  xoffset,
GLsizei  width,
GLenum  format,
GLenum  type,
const GLvoid *  pixels,
const struct gl_pixelstore_attrib *  packing,
struct gl_texture_object *  texObj,
struct gl_texture_image *  texImage 
) [static]

Definition at line 881 of file st_cb_texture.c.

References st_TexSubimage().

00891 {
00892    st_TexSubimage(ctx, 1, target, level,
00893                   xoffset, 0, 0,
00894                   width, 1, 1,
00895                   format, type, pixels, packing, texObj, texImage);
00896 }

static void st_TexSubImage2D ( GLcontext *  ctx,
GLenum  target,
GLint  level,
GLint  xoffset,
GLint  yoffset,
GLsizei  width,
GLsizei  height,
GLenum  format,
GLenum  type,
const GLvoid *  pixels,
const struct gl_pixelstore_attrib *  packing,
struct gl_texture_object *  texObj,
struct gl_texture_image *  texImage 
) [static]

Definition at line 862 of file st_cb_texture.c.

References st_TexSubimage().

00872 {
00873    st_TexSubimage(ctx, 2, target, level,
00874                   xoffset, yoffset, 0,
00875                   width, height, 1,
00876                   format, type, pixels, packing, texObj, texImage);
00877 }

static void st_TexSubImage3D ( GLcontext *  ctx,
GLenum  target,
GLint  level,
GLint  xoffset,
GLint  yoffset,
GLint  zoffset,
GLsizei  width,
GLsizei  height,
GLsizei  depth,
GLenum  format,
GLenum  type,
const GLvoid *  pixels,
const struct gl_pixelstore_attrib *  packing,
struct gl_texture_object *  texObj,
struct gl_texture_image *  texImage 
) [static]

Definition at line 843 of file st_cb_texture.c.

References st_TexSubimage().

00853 {
00854    st_TexSubimage(ctx, 3, target, level,
00855                   xoffset, yoffset, zoffset,
00856                   width, height, depth,
00857                   format, type, pixels, packing, texObj, texImage);
00858 }

static void strip_texture_border ( GLint  border,
GLint *  width,
GLint *  height,
GLint *  depth,
const struct gl_pixelstore_attrib *  unpack,
struct gl_pixelstore_attrib *  unpackNew 
) [static]

Adjust pixel unpack params and image dimensions to strip off the texture border.

Gallium doesn't support texture borders. They've seldem been used and seldom been implemented correctly anyway.

Parameters:
unpackNew returns the new pixel unpack parameters

Definition at line 338 of file st_cb_texture.c.

References assert.

00342 {
00343    assert(border > 0);  /* sanity check */
00344 
00345    *unpackNew = *unpack;
00346 
00347    if (unpackNew->RowLength == 0)
00348       unpackNew->RowLength = *width;
00349 
00350    if (depth && unpackNew->ImageHeight == 0)
00351       unpackNew->ImageHeight = *height;
00352 
00353    unpackNew->SkipPixels += border;
00354    if (height)
00355       unpackNew->SkipRows += border;
00356    if (depth)
00357       unpackNew->SkipImages += border;
00358 
00359    assert(*width >= 3);
00360    *width = *width - 2 * border;
00361    if (height && *height >= 3)
00362       *height = *height - 2 * border;
00363    if (depth && *depth >= 3)
00364       *depth = *depth - 2 * border;
00365 }

static uint texture_face ( GLenum  target  )  [static]

Return 0 for GL_TEXTURE_CUBE_MAP_POSITIVE_X, 1 for GL_TEXTURE_CUBE_MAP_NEGATIVE_X, etc.

XXX duplicated from main/teximage.c

Definition at line 907 of file st_cb_texture.c.

00908 {
00909    if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
00910        target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)
00911       return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
00912    else
00913       return 0;
00914 }


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