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 __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 ???
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.
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.
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.
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 }