st_texture.c File Reference

Include dependency graph for st_texture.c:

Go to the source code of this file.

Defines

#define DBG   if(0) printf

Functions

struct pipe_texturest_texture_create (struct st_context *st, enum pipe_texture_target target, enum pipe_format format, GLuint last_level, GLuint width0, GLuint height0, GLuint depth0, GLuint compress_byte, GLuint usage)
 Allocate a new pipe_texture object width0, height0, depth0 are the dimensions of the level 0 image (the highest resolution).
GLboolean st_texture_match_image (const struct pipe_texture *pt, const struct gl_texture_image *image, GLuint face, GLuint level)
 Check if a texture image be pulled into a unified mipmap texture.
GLubyte * st_texture_image_map (struct st_context *st, struct st_texture_image *stImage, GLuint zoffset, GLuint flags)
 Map a teximage in a mipmap texture.
void st_texture_image_unmap (struct st_context *st, struct st_texture_image *stImage)
static void st_surface_data (struct pipe_context *pipe, struct pipe_surface *dst, unsigned dstx, unsigned dsty, const void *src, unsigned src_stride, unsigned srcx, unsigned srcy, unsigned width, unsigned height)
 Upload data to a rectangular sub-region.
void st_texture_image_data (struct pipe_context *pipe, struct pipe_texture *dst, GLuint face, GLuint level, void *src, GLuint src_row_stride, GLuint src_image_stride)
void st_texture_image_copy (struct pipe_context *pipe, struct pipe_texture *dst, GLuint dstLevel, struct pipe_texture *src, GLuint face)
int st_bind_teximage (struct st_framebuffer *stfb, uint surfIndex, int target, int format, int level)
 Redirect rendering into stfb's surface to a texture image.
int st_release_teximage (struct st_framebuffer *stfb, uint surfIndex, int target, int format, int level)
 Undo surface-to-texture binding.


Define Documentation

#define DBG   if(0) printf

Definition at line 46 of file st_texture.c.


Function Documentation

int st_bind_teximage ( struct st_framebuffer stfb,
uint  surfIndex,
int  target,
int  format,
int  level 
)

Redirect rendering into stfb's surface to a texture image.

Definition at line 356 of file st_texture.c.

00360 {
00361    GET_CURRENT_CONTEXT(ctx);
00362    struct st_context *st = ctx->st;
00363    struct pipe_context *pipe = st->pipe;
00364    struct pipe_screen *screen = pipe->screen;
00365    const GLuint unit = ctx->Texture.CurrentUnit;
00366    struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
00367    struct gl_texture_object *texObj;
00368    struct gl_texture_image *texImage;
00369    struct st_texture_image *stImage;
00370    struct st_renderbuffer *strb;
00371    GLint face = 0, slice = 0;
00372 
00373    assert(surfIndex <= ST_SURFACE_DEPTH);
00374 
00375    strb = st_renderbuffer(stfb->Base.Attachment[surfIndex].Renderbuffer);
00376 
00377    if (strb->texture_save || strb->surface_save) {
00378       /* Error! */
00379       return 0;
00380    }
00381 
00382    if (target == ST_TEXTURE_2D) {
00383       texObj = texUnit->Current2D;
00384       texImage = _mesa_get_tex_image(ctx, texObj, GL_TEXTURE_2D, level);
00385       stImage = st_texture_image(texImage);
00386    }
00387    else {
00388       /* unsupported target */
00389       return 0;
00390    }
00391 
00392    st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
00393 
00394    /* save the renderbuffer's surface/texture info */
00395    pipe_texture_reference(&strb->texture_save, strb->texture);
00396    pipe_surface_reference(&strb->surface_save, strb->surface);
00397 
00398    /* plug in new surface/texture info */
00399    pipe_texture_reference(&strb->texture, stImage->pt);
00400    strb->surface = screen->get_tex_surface(screen, strb->texture,
00401                                            face, level, slice,
00402                                            (PIPE_BUFFER_USAGE_GPU_READ |
00403                                             PIPE_BUFFER_USAGE_GPU_WRITE));
00404 
00405    st->dirty.st |= ST_NEW_FRAMEBUFFER;
00406 

int st_release_teximage ( struct st_framebuffer stfb,
uint  surfIndex,
int  target,
int  format,
int  level 
)

Undo surface-to-texture binding.

Definition at line 411 of file st_texture.c.

00415 {
00416    GET_CURRENT_CONTEXT(ctx);
00417    struct st_context *st = ctx->st;
00418    struct st_renderbuffer *strb;
00419 
00420    assert(surfIndex <= ST_SURFACE_DEPTH);
00421 
00422    strb = st_renderbuffer(stfb->Base.Attachment[surfIndex].Renderbuffer);
00423 
00424    if (!strb->texture_save || !strb->surface_save) {
00425       /* Error! */
00426       return 0;
00427    }
00428 
00429    st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
00430 
00431    /* free tex surface, restore original */
00432    pipe_surface_reference(&strb->surface, strb->surface_save);
00433    pipe_texture_reference(&strb->texture, strb->texture_save);
00434 
00435    pipe_surface_reference(&strb->surface_save, NULL);
00436    pipe_texture_reference(&strb->texture_save, NULL);
00437 
00438    st->dirty.st |= ST_NEW_FRAMEBUFFER;
00439 

static void st_surface_data ( struct pipe_context pipe,
struct pipe_surface dst,
unsigned  dstx,
unsigned  dsty,
const void *  src,
unsigned  src_stride,
unsigned  srcx,
unsigned  srcy,
unsigned  width,
unsigned  height 
) [static]

Upload data to a rectangular sub-region.

Lots of choices how to do this:

Currently always memcpy.

Definition at line 233 of file st_texture.c.

00240 {
00241    struct pipe_screen *screen = pipe->screen;
00242    void *map = screen->surface_map(screen, dst, PIPE_BUFFER_USAGE_CPU_WRITE);
00243 
00244    pipe_copy_rect(map,
00245                   &dst->block,
00246                   dst->stride,
00247                   dstx, dsty, 
00248                   width, height, 
00249                   src, src_stride, 
00250                   srcx, srcy);
00251 

struct pipe_texture* st_texture_create ( struct st_context st,
enum pipe_texture_target  target,
enum pipe_format  format,
GLuint  last_level,
GLuint  width0,
GLuint  height0,
GLuint  depth0,
GLuint  compress_byte,
GLuint  usage 
) [read]

Allocate a new pipe_texture object width0, height0, depth0 are the dimensions of the level 0 image (the highest resolution).

last_level indicates how many mipmap levels to allocate storage for. For non-mipmapped textures, this will be zero.

Definition at line 74 of file st_texture.c.

References assert, pipe_texture::block, pipe_texture::compressed, DBG, pipe_texture::depth, pipe_texture::format, pipe_texture::height, pipe_screen::is_format_supported, pipe_texture::last_level, pf_get_block(), st_context::pipe, PIPE_TEXTURE_CUBE, PIPE_TEXTURE_USAGE_SAMPLER, pipe_texture::refcount, pipe_context::screen, pipe_texture::target, pipe_texture::tex_usage, pipe_screen::texture_create, and pipe_texture::width.

00083 {
00084    struct pipe_texture pt, *newtex;
00085    struct pipe_screen *screen = st->pipe->screen;
00086 
00087    assert(target <= PIPE_TEXTURE_CUBE);
00088 
00089    DBG("%s target %s format %s last_level %d\n", __FUNCTION__,
00090        _mesa_lookup_enum_by_nr(target),
00091        _mesa_lookup_enum_by_nr(format), last_level);
00092 
00093    assert(format);
00094    assert(screen->is_format_supported(screen, format, target, 
00095                                       PIPE_TEXTURE_USAGE_SAMPLER, 0));
00096 
00097    memset(&pt, 0, sizeof(pt));
00098    pt.target = target;
00099    pt.format = format;
00100    pt.last_level = last_level;
00101    pt.width[0] = width0;
00102    pt.height[0] = height0;
00103    pt.depth[0] = depth0;
00104    pt.compressed = compress_byte ? 1 : 0;
00105    pf_get_block(format, &pt.block);
00106    pt.tex_usage = usage;
00107 
00108    newtex = screen->texture_create(screen, &pt);
00109 
00110    assert(!newtex || newtex->refcount == 1);
00111 
00112    return newtex;
00113 }

void st_texture_image_copy ( struct pipe_context pipe,
struct pipe_texture dst,
GLuint  dstLevel,
struct pipe_texture src,
GLuint  face 
)

Definition at line 292 of file st_texture.c.

References assert, pipe_texture::depth, FALSE, pipe_screen::get_tex_surface, pipe_surface::height, pipe_texture::height, pipe_texture::last_level, PIPE_BUFFER_USAGE_CPU_READ, PIPE_BUFFER_USAGE_GPU_READ, PIPE_BUFFER_USAGE_GPU_WRITE, pipe_surface_reference(), pipe_context::screen, pipe_context::surface_copy, pipe_screen::surface_map, pipe_screen::surface_unmap, pipe_screen::tex_surface_release, pipe_surface::width, and pipe_texture::width.

00298 {
00299    struct pipe_screen *screen = pipe->screen;
00300    GLuint width = dst->width[dstLevel];
00301    GLuint height = dst->height[dstLevel];
00302    GLuint depth = dst->depth[dstLevel];
00303    struct pipe_surface *src_surface;
00304    struct pipe_surface *dst_surface;
00305    GLuint i;
00306 
00307    for (i = 0; i < depth; i++) {
00308       GLuint srcLevel;
00309 
00310       /* find src texture level of needed size */
00311       for (srcLevel = 0; srcLevel <= src->last_level; srcLevel++) {
00312          if (src->width[srcLevel] == width &&
00313              src->height[srcLevel] == height) {
00314             break;
00315          }
00316       }
00317       assert(src->width[srcLevel] == width);
00318       assert(src->height[srcLevel] == height);
00319 
00320 #if 0
00321       {
00322          src_surface = screen->get_tex_surface(screen, src, face, srcLevel, i,
00323                                                PIPE_BUFFER_USAGE_CPU_READ);
00324          ubyte *map = screen->surface_map(screen, src_surface, PIPE_BUFFER_USAGE_CPU_READ);
00325          map += src_surface->width * src_surface->height * 4 / 2;
00326          printf("%s center pixel: %d %d %d %d (pt %p[%d] -> %p[%d])\n",
00327                 __FUNCTION__,
00328                 map[0], map[1], map[2], map[3],
00329                 src, srcLevel, dst, dstLevel);
00330 
00331          screen->surface_unmap(screen, src_surface);
00332          pipe_surface_reference(&src_surface, NULL);
00333       }
00334 #endif
00335 
00336       dst_surface = screen->get_tex_surface(screen, dst, face, dstLevel, i,
00337                                             PIPE_BUFFER_USAGE_GPU_WRITE);
00338 
00339       src_surface = screen->get_tex_surface(screen, src, face, srcLevel, i,
00340                                             PIPE_BUFFER_USAGE_GPU_READ);
00341 
00342       pipe->surface_copy(pipe,
00343                          FALSE,
00344                          dst_surface,
00345                          0, 0, /* destX, Y */
00346                          src_surface,
00347                          0, 0, /* srcX, Y */
00348                          width, height);
00349 
00350       screen->tex_surface_release(screen, &src_surface);
00351       screen->tex_surface_release(screen, &dst_surface);

void st_texture_image_data ( struct pipe_context pipe,
struct pipe_texture dst,
GLuint  face,
GLuint  level,
void *  src,
GLuint  src_row_stride,
GLuint  src_image_stride 
)

Definition at line 257 of file st_texture.c.

References DBG, pipe_texture::depth, pipe_screen::get_tex_surface, pipe_texture::height, PIPE_BUFFER_USAGE_CPU_WRITE, pipe_context::screen, st_surface_data(), pipe_screen::tex_surface_release, and pipe_texture::width.

00265 {
00266    struct pipe_screen *screen = pipe->screen;
00267    GLuint depth = dst->depth[level];
00268    GLuint i;
00269    const GLubyte *srcUB = src;
00270    struct pipe_surface *dst_surface;
00271 
00272    DBG("%s\n", __FUNCTION__);
00273    for (i = 0; i < depth; i++) {
00274       dst_surface = screen->get_tex_surface(screen, dst, face, level, i,
00275                                             PIPE_BUFFER_USAGE_CPU_WRITE);
00276 
00277       st_surface_data(pipe, dst_surface,
00278                       0, 0,                             /* dstx, dsty */
00279                       srcUB,
00280                       src_row_stride,
00281                       0, 0,                             /* source x, y */
00282                       dst->width[level], dst->height[level]);       /* width, height */
00283 
00284       screen->tex_surface_release(screen, &dst_surface);
00285 
00286       srcUB += src_image_stride;

GLubyte* st_texture_image_map ( struct st_context st,
struct st_texture_image stImage,
GLuint  zoffset,
GLuint  flags 
)

Map a teximage in a mipmap texture.

Parameters:
row_stride returns row stride in bytes
image_stride returns image stride in bytes (for 3D textures).
Returns:
address of mapping

Definition at line 190 of file st_texture.c.

00195 {
00196    struct pipe_screen *screen = st->pipe->screen;
00197    struct pipe_texture *pt = stImage->pt;
00198    DBG("%s \n", __FUNCTION__);
00199 
00200    stImage->surface = screen->get_tex_surface(screen, pt, stImage->face,
00201                                               stImage->level, zoffset, 
00202                                               flags);
00203 
00204    if (stImage->surface)
00205       return screen->surface_map(screen, stImage->surface, flags);
00206    else

void st_texture_image_unmap ( struct st_context st,
struct st_texture_image stImage 
)

Definition at line 210 of file st_texture.c.

References DBG, st_context::pipe, pipe_surface_reference(), pipe_context::screen, st_texture_image::surface, and pipe_screen::surface_unmap.

00214 {
00215    struct pipe_screen *screen = st->pipe->screen;
00216 
00217    DBG("%s\n", __FUNCTION__);
00218 
00219    screen->surface_unmap(screen, stImage->surface);
00220 

GLboolean st_texture_match_image ( const struct pipe_texture pt,
const struct gl_texture_image *  image,
GLuint  face,
GLuint  level 
)

Check if a texture image be pulled into a unified mipmap texture.

This mirrors the completeness test in a lot of ways.

Not sure whether I want to pass gl_texture_image here.

Definition at line 123 of file st_texture.c.

References pipe_texture::compressed, pipe_texture::depth, pipe_texture::format, pipe_texture::height, st_mesa_format_to_pipe_format(), and pipe_texture::width.

00126 {
00127    /* Images with borders are never pulled into mipmap textures. 
00128     */
00129    if (image->Border) 
00130       return GL_FALSE;
00131 
00132    if (st_mesa_format_to_pipe_format(image->TexFormat->MesaFormat) != pt->format ||
00133        image->IsCompressed != pt->compressed)
00134       return GL_FALSE;
00135 
00136    /* Test image dimensions against the base level image adjusted for
00137     * minification.  This will also catch images not present in the
00138     * texture, changed targets, etc.
00139     */
00140    if (image->Width != pt->width[level] ||
00141        image->Height != pt->height[level] ||
00142        image->Depth != pt->depth[level])
00143       return GL_FALSE;
00144 
00145    return GL_TRUE;
00146 }


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