X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fdri%2Fradeon%2Fradeon_texture.c;h=d2b190e42e0ec2e46e50aefd1cbedc2a4525266d;hb=ba03a0b5ba73bc8e79d0ffa6d1da623544716f74;hp=c093d1283d1ecbd4ad7cb45ca21b22720e9f3a6f;hpb=8f88cf3938f0156d4df6fcc5fde2711d40b85d03;p=mesa.git diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.c b/src/mesa/drivers/dri/radeon/radeon_texture.c index c093d1283d1..d2b190e42e0 100644 --- a/src/mesa/drivers/dri/radeon/radeon_texture.c +++ b/src/mesa/drivers/dri/radeon/radeon_texture.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2009 Maciej Cencora. * Copyright (C) 2008 Nicolai Haehnle. * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. * @@ -32,12 +33,13 @@ #include "main/imports.h" #include "main/context.h" #include "main/convolve.h" +#include "main/enums.h" #include "main/mipmap.h" #include "main/texcompress.h" #include "main/texstore.h" #include "main/teximage.h" #include "main/texobj.h" -#include "main/texgetimage.h" +#include "drivers/common/meta.h" #include "xmlpool.h" /* for symbolic values of enum-type options */ @@ -46,12 +48,19 @@ #include "radeon_mipmap_tree.h" -static void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride, +void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride, GLuint numrows, GLuint rowsize) { assert(rowsize <= dststride); assert(rowsize <= srcstride); + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s dst %p, stride %u, src %p, stride %u, " + "numrows %u, rowsize %u.\n", + __func__, dst, dststride, + src, srcstride, + numrows, rowsize); + if (rowsize == srcstride && rowsize == dststride) { memcpy(dst, src, numrows*rowsize); } else { @@ -101,13 +110,17 @@ static void teximage_set_map_data(radeon_texture_image *image) { radeon_mipmap_level *lvl; - if (!image->mt) + if (!image->mt) { + radeon_warning("%s(%p) Trying to set map data without miptree.\n", + __func__, image); + return; + } lvl = &image->mt->levels[image->mtlevel]; image->base.Data = image->mt->bo->ptr + lvl->faces[image->mtface].offset; - image->base.RowStride = lvl->rowstride / image->mt->bpp; + image->base.RowStride = lvl->rowstride / _mesa_get_format_bytes(image->base.TexFormat); } @@ -116,6 +129,10 @@ static void teximage_set_map_data(radeon_texture_image *image) */ void radeon_teximage_map(radeon_texture_image *image, GLboolean write_enable) { + radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, + "%s(img %p), write_enable %s.\n", + __func__, image, + write_enable ? "true": "false"); if (image->mt) { assert(!image->base.Data); @@ -127,6 +144,9 @@ void radeon_teximage_map(radeon_texture_image *image, GLboolean write_enable) void radeon_teximage_unmap(radeon_texture_image *image) { + radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, + "%s(img %p)\n", + __func__, image); if (image->mt) { assert(image->base.Data); @@ -161,19 +181,35 @@ void radeonMapTexture(GLcontext *ctx, struct gl_texture_object *texObj) radeonTexObj* t = radeon_tex_obj(texObj); int face, level; - if (!radeon_validate_texture_miptree(ctx, texObj)) - return; + radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, + "%s(%p, tex %p)\n", + __func__, ctx, texObj); + + if (!radeon_validate_texture_miptree(ctx, texObj)) { + radeon_error("%s(%p, tex %p) Failed to validate miptree for " + "sw fallback.\n", + __func__, ctx, texObj); + return; + } + + if (t->image_override && t->bo) { + radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, + "%s(%p, tex %p) Work around for missing miptree in r100.\n", + __func__, ctx, texObj); - /* for r100 3D sw fallbacks don't have mt */ - if (t->image_override && t->bo) map_override(ctx, t); + } - if (!t->mt) + /* for r100 3D sw fallbacks don't have mt */ + if (!t->mt) { + radeon_warning("%s(%p, tex %p) No miptree in texture.\n", + __func__, ctx, texObj); return; + } radeon_bo_map(t->mt->bo, GL_FALSE); for(face = 0; face < t->mt->faces; ++face) { - for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) + for(level = t->minLod; level <= t->maxLod; ++level) teximage_set_map_data(get_radeon_texture_image(texObj->Image[face][level])); } } @@ -183,6 +219,10 @@ void radeonUnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj) radeonTexObj* t = radeon_tex_obj(texObj); int face, level; + radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, + "%s(%p, tex %p)\n", + __func__, ctx, texObj); + if (t->image_override && t->bo) unmap_override(ctx, t); /* for r100 3D sw fallbacks don't have mt */ @@ -190,27 +230,12 @@ void radeonUnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj) return; for(face = 0; face < t->mt->faces; ++face) { - for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) + for(level = t->minLod; level <= t->maxLod; ++level) texObj->Image[face][level]->Data = 0; } radeon_bo_unmap(t->mt->bo); } -GLuint radeon_face_for_target(GLenum target) -{ - switch (target) { - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; - default: - return 0; - } -} - /** * Wraps Mesa's implementation to ensure that the base level image is mapped. * @@ -224,6 +249,10 @@ static void radeon_generate_mipmap(GLcontext *ctx, GLenum target, GLuint nr_faces = (t->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; int i, face; + radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, + "%s(%p, tex %p) Target type %s.\n", + __func__, ctx, texObj, + _mesa_lookup_enum_by_nr(target)); _mesa_generate_mipmap(ctx, target, texObj); @@ -247,12 +276,32 @@ static void radeon_generate_mipmap(GLcontext *ctx, GLenum target, void radeonGenerateMipmap(GLcontext* ctx, GLenum target, struct gl_texture_object *texObj) { - GLuint face = radeon_face_for_target(target); + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + struct radeon_bo *bo; + GLuint face = _mesa_tex_target_to_face(target); radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[face][texObj->BaseLevel]); + bo = !baseimage->mt ? baseimage->bo : baseimage->mt->bo; + + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s(%p, target %s, tex %p)\n", + __func__, ctx, _mesa_lookup_enum_by_nr(target), + texObj); + + if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) { + radeon_print(RADEON_TEXTURE, RADEON_NORMAL, + "%s(%p, tex %p) Trying to generate mipmap for texture " + "in processing by GPU.\n", + __func__, ctx, texObj); + radeon_firevertices(rmesa); + } - radeon_teximage_map(baseimage, GL_FALSE); - radeon_generate_mipmap(ctx, target, texObj); - radeon_teximage_unmap(baseimage); + if (_mesa_meta_check_generate_mipmap_fallback(ctx, target, texObj)) { + radeon_teximage_map(baseimage, GL_FALSE); + radeon_generate_mipmap(ctx, target, texObj); + radeon_teximage_unmap(baseimage); + } else { + _mesa_meta_GenerateMipmap(ctx, target, texObj); + } } @@ -311,12 +360,14 @@ gl_format radeonChooseTextureFormat(GLcontext * ctx, (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16); (void)format; -#if 0 - fprintf(stderr, "InternalFormat=%s(%d) type=%s format=%s\n", + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s InternalFormat=%s(%d) type=%s format=%s\n", + __func__, _mesa_lookup_enum_by_nr(internalFormat), internalFormat, _mesa_lookup_enum_by_nr(type), _mesa_lookup_enum_by_nr(format)); - fprintf(stderr, "do32bpt=%d force16bpt=%d\n", do32bpt, force16bpt); -#endif + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s do32bpt=%d force16bpt=%d\n", + __func__, do32bpt, force16bpt); switch (internalFormat) { case 4: @@ -471,6 +522,19 @@ gl_format radeonChooseTextureFormat(GLcontext * ctx, case GL_RGBA32F_ARB: return MESA_FORMAT_RGBA_FLOAT32; +#ifdef RADEON_R300 + case GL_DEPTH_COMPONENT: + case GL_DEPTH_COMPONENT16: + return MESA_FORMAT_Z16; + case GL_DEPTH_COMPONENT24: + case GL_DEPTH_COMPONENT32: + case GL_DEPTH_STENCIL_EXT: + case GL_DEPTH24_STENCIL8_EXT: + if (rmesa->radeonScreen->chip_family >= CHIP_FAMILY_RV515) + return MESA_FORMAT_S8_Z24; + else + return MESA_FORMAT_Z16; +#else case GL_DEPTH_COMPONENT: case GL_DEPTH_COMPONENT16: case GL_DEPTH_COMPONENT24: @@ -478,6 +542,7 @@ gl_format radeonChooseTextureFormat(GLcontext * ctx, case GL_DEPTH_STENCIL_EXT: case GL_DEPTH24_STENCIL8_EXT: return MESA_FORMAT_S8_Z24; +#endif /* EXT_texture_sRGB */ case GL_SRGB: @@ -498,6 +563,15 @@ gl_format radeonChooseTextureFormat(GLcontext * ctx, case GL_COMPRESSED_SLUMINANCE_ALPHA: return MESA_FORMAT_SLA8; + case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + return MESA_FORMAT_SRGB_DXT1; + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + return MESA_FORMAT_SRGBA_DXT1; + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + return MESA_FORMAT_SRGBA_DXT3; + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + return MESA_FORMAT_SRGBA_DXT5; + default: _mesa_problem(ctx, "unexpected internalFormat 0x%x in %s", @@ -508,6 +582,66 @@ gl_format radeonChooseTextureFormat(GLcontext * ctx, return MESA_FORMAT_NONE; /* never get here */ } +/** Check if given image is valid within current texture object. + */ +static int image_matches_texture_obj(struct gl_texture_object *texObj, + struct gl_texture_image *texImage, + unsigned level) +{ + const struct gl_texture_image *baseImage = texObj->Image[0][texObj->BaseLevel]; + + if (!baseImage) + return 0; + + if (level < texObj->BaseLevel || level > texObj->MaxLevel) + return 0; + + const unsigned levelDiff = level - texObj->BaseLevel; + const unsigned refWidth = MAX2(baseImage->Width >> levelDiff, 1); + const unsigned refHeight = MAX2(baseImage->Height >> levelDiff, 1); + const unsigned refDepth = MAX2(baseImage->Depth >> levelDiff, 1); + + return (texImage->Width == refWidth && + texImage->Height == refHeight && + texImage->Depth == refDepth); +} + +static void teximage_assign_miptree(radeonContextPtr rmesa, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, + unsigned face, + unsigned level) +{ + radeonTexObj *t = radeon_tex_obj(texObj); + radeon_texture_image* image = get_radeon_texture_image(texImage); + + /* Since miptree holds only images for levels + * don't allocate the miptree if the teximage won't fit. + */ + if (!image_matches_texture_obj(texObj, texImage, level)) + return; + + /* Try using current miptree, or create new if there isn't any */ + if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage, face, level)) { + radeon_miptree_unreference(&t->mt); + radeon_try_alloc_miptree(rmesa, t); + radeon_print(RADEON_TEXTURE, RADEON_NORMAL, + "%s: texObj %p, texImage %p, face %d, level %d, " + "texObj miptree doesn't match, allocated new miptree %p\n", + __FUNCTION__, texObj, texImage, face, level, t->mt); + } + + /* Miptree alocation may have failed, + * when there was no image for baselevel specified */ + if (t->mt) { + image->mtface = face; + image->mtlevel = level; + radeon_miptree_reference(t->mt, &image->mt); + } else + radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, + "%s Failed to allocate miptree.\n", __func__); +} + static GLuint * allocate_image_offsets(GLcontext *ctx, unsigned alignedWidth, unsigned height, @@ -516,7 +650,7 @@ static GLuint * allocate_image_offsets(GLcontext *ctx, int i; GLuint *offsets; - offsets = _mesa_malloc(depth * sizeof(GLuint)) ; + offsets = malloc(depth * sizeof(GLuint)) ; if (!offsets) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTex[Sub]Image"); return NULL; @@ -543,22 +677,33 @@ static void radeon_store_teximage(GLcontext* ctx, int dims, struct gl_texture_image *texImage, int compressed) { + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + radeonTexObj *t = radeon_tex_obj(texObj); radeon_texture_image* image = get_radeon_texture_image(texImage); - GLint dstRowStride; + GLuint dstRowStride; GLuint *dstImageOffsets; + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s(%p, tex %p, image %p) compressed %d\n", + __func__, ctx, texObj, texImage, compressed); + if (image->mt) { - radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel]; - dstRowStride = lvl->rowstride; + dstRowStride = image->mt->levels[image->mtlevel].rowstride; + } else if (t->bo) { + /* TFP case */ + dstRowStride = get_texture_image_row_stride(rmesa, texImage->TexFormat, width, 0); } else { - dstRowStride = texImage->RowStride * _mesa_get_format_bytes(texImage->TexFormat); + dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width); } + assert(dstRowStride); + if (dims == 3) { unsigned alignedWidth = dstRowStride/_mesa_get_format_bytes(texImage->TexFormat); - dstImageOffsets = allocate_image_offsets(ctx, alignedWidth, height, depth); + dstImageOffsets = allocate_image_offsets(ctx, alignedWidth, texImage->Height, texImage->Depth); if (!dstImageOffsets) { + radeon_warning("%s Failed to allocate dstImaeOffset.\n", __func__); return; } } else { @@ -568,8 +713,11 @@ static void radeon_store_teximage(GLcontext* ctx, int dims, radeon_teximage_map(image, GL_TRUE); if (compressed) { - uint32_t srcRowStride, bytesPerRow, rows; + uint32_t srcRowStride, bytesPerRow, rows, block_width, block_height; GLubyte *img_start; + + _mesa_get_format_block_size(texImage->TexFormat, &block_width, &block_height); + if (!image->mt) { dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width); img_start = _mesa_compressed_image_address(xoffset, yoffset, 0, @@ -577,15 +725,16 @@ static void radeon_store_teximage(GLcontext* ctx, int dims, texImage->Width, texImage->Data); } else { - uint32_t blocks_x = dstRowStride / (image->mt->bpp * 4); - img_start = texImage->Data + image->mt->bpp * 4 * (blocks_x * (yoffset / 4) + xoffset / 4); + uint32_t offset; + offset = dstRowStride / _mesa_get_format_bytes(texImage->TexFormat) * yoffset / block_height + xoffset / block_width; + offset *= _mesa_get_format_bytes(texImage->TexFormat); + img_start = texImage->Data + offset; } srcRowStride = _mesa_format_row_stride(texImage->TexFormat, width); bytesPerRow = srcRowStride; - rows = (height + 3) / 4; - - copy_rows(img_start, dstRowStride, pixels, srcRowStride, rows, bytesPerRow); + rows = (height + block_height - 1) / block_height; + copy_rows(img_start, dstRowStride, pixels, srcRowStride, rows, bytesPerRow); } else { if (!_mesa_texstore(ctx, dims, texImage->_BaseFormat, @@ -600,7 +749,7 @@ static void radeon_store_teximage(GLcontext* ctx, int dims, } if (dims == 3) { - _mesa_free(dstImageOffsets); + free(dstImageOffsets); } radeon_teximage_unmap(image); @@ -624,20 +773,26 @@ static void radeon_teximage( radeonContextPtr rmesa = RADEON_CONTEXT(ctx); radeonTexObj* t = radeon_tex_obj(texObj); radeon_texture_image* image = get_radeon_texture_image(texImage); - GLuint dstRowStride; GLint postConvWidth = width; GLint postConvHeight = height; - GLuint texelBytes; - GLuint face = radeon_face_for_target(target); + GLuint face = _mesa_tex_target_to_face(target); + radeon_print(RADEON_TEXTURE, RADEON_NORMAL, + "%s %dd: texObj %p, texImage %p, face %d, level %d\n", + __func__, dims, texObj, texImage, face, level); { struct radeon_bo *bo; bo = !image->mt ? image->bo : image->mt->bo; if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) { + radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, + "%s Calling teximage for texture that is " + "queued for GPU processing.\n", + __func__); radeon_firevertices(rmesa); } } + t->validated = GL_FALSE; if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { @@ -645,51 +800,34 @@ static void radeon_teximage( &postConvHeight); } - if (_mesa_is_format_compressed(texImage->TexFormat)) { - texelBytes = 0; - } else { - texelBytes = _mesa_get_format_bytes(texImage->TexFormat); + if (!_mesa_is_format_compressed(texImage->TexFormat)) { + GLuint texelBytes = _mesa_get_format_bytes(texImage->TexFormat); /* Minimum pitch of 32 bytes */ if (postConvWidth * texelBytes < 32) { - postConvWidth = 32 / texelBytes; - texImage->RowStride = postConvWidth; + postConvWidth = 32 / texelBytes; + texImage->RowStride = postConvWidth; } - if (!image->mt) { + if (!image->mt) { assert(texImage->RowStride == postConvWidth); } } - /* Allocate memory for image */ - radeonFreeTexImageData(ctx, texImage); /* Mesa core only clears texImage->Data but not image->mt */ - - if (t->mt && - t->mt->firstLevel == level && - t->mt->lastLevel == level && - t->mt->target != GL_TEXTURE_CUBE_MAP_ARB && - !radeon_miptree_matches_image(t->mt, texImage, face, level)) { - radeon_miptree_unreference(&t->mt); - } + /* Mesa core only clears texImage->Data but not image->mt */ + radeonFreeTexImageData(ctx, texImage); - if (!t->mt) - radeon_try_alloc_miptree(rmesa, t, image, face, level); - if (t->mt && radeon_miptree_matches_image(t->mt, texImage, face, level)) { - radeon_mipmap_level *lvl; - image->mtlevel = level - t->mt->firstLevel; - image->mtface = face; - radeon_miptree_reference(t->mt, &image->mt); - lvl = &image->mt->levels[image->mtlevel]; - dstRowStride = lvl->rowstride; - } else { - int size; - if (_mesa_is_format_compressed(texImage->TexFormat)) { - size = _mesa_format_image_size(texImage->TexFormat, - texImage->Width, - texImage->Height, - texImage->Depth); - } else { - size = texImage->Width * texImage->Height * texImage->Depth * _mesa_get_format_bytes(texImage->TexFormat); + if (!t->bo) { + teximage_assign_miptree(rmesa, texObj, texImage, face, level); + if (!image->mt) { + int size = _mesa_format_image_size(texImage->TexFormat, + texImage->Width, + texImage->Height, + texImage->Depth); + texImage->Data = _mesa_alloc_texmemory(size); + radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, + "%s %dd: texObj %p, texImage %p, " + " no miptree assigned, using local memory %p\n", + __func__, dims, texObj, texImage, texImage->Data); } - texImage->Data = _mesa_alloc_texmemory(size); } /* Upload texture image; note that the spec allows pixels to be NULL */ @@ -782,21 +920,30 @@ static void radeon_texsubimage(GLcontext* ctx, int dims, GLenum target, int leve radeonTexObj* t = radeon_tex_obj(texObj); radeon_texture_image* image = get_radeon_texture_image(texImage); + radeon_print(RADEON_TEXTURE, RADEON_NORMAL, + "%s %dd: texObj %p, texImage %p, face %d, level %d\n", + __func__, dims, texObj, texImage, + _mesa_tex_target_to_face(target), level); { struct radeon_bo *bo; bo = !image->mt ? image->bo : image->mt->bo; if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) { + radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, + "%s Calling texsubimage for texture that is " + "queued for GPU processing.\n", + __func__); radeon_firevertices(rmesa); } } + t->validated = GL_FALSE; if (compressed) { pixels = _mesa_validate_pbo_compressed_teximage( - ctx, imageSize, pixels, packing, "glCompressedTexImage"); + ctx, imageSize, pixels, packing, "glCompressedTexSubImage"); } else { pixels = _mesa_validate_pbo_teximage(ctx, dims, - width, height, depth, format, type, pixels, packing, "glTexSubImage1D"); + width, height, depth, format, type, pixels, packing, "glTexSubImage"); } if (pixels) { @@ -865,191 +1012,18 @@ void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level, format, type, pixels, packing, texObj, texImage, 0); } - - -/** - * Ensure that the given image is stored in the given miptree from now on. - */ -static void migrate_image_to_miptree(radeon_mipmap_tree *mt, radeon_texture_image *image, int face, int level) +unsigned radeonIsFormatRenderable(gl_format mesa_format) { - radeon_mipmap_level *dstlvl = &mt->levels[level - mt->firstLevel]; - unsigned char *dest; - - assert(image->mt != mt); - assert(dstlvl->width == image->base.Width); - assert(dstlvl->height == image->base.Height); - assert(dstlvl->depth == image->base.Depth); - - - radeon_bo_map(mt->bo, GL_TRUE); - dest = mt->bo->ptr + dstlvl->faces[face].offset; - - if (image->mt) { - /* Format etc. should match, so we really just need a memcpy(). - * In fact, that memcpy() could be done by the hardware in many - * cases, provided that we have a proper memory manager. - */ - radeon_mipmap_level *srclvl = &image->mt->levels[image->mtlevel-image->mt->firstLevel]; - - assert(srclvl->size == dstlvl->size); - assert(srclvl->rowstride == dstlvl->rowstride); - - radeon_bo_map(image->mt->bo, GL_FALSE); - - memcpy(dest, - image->mt->bo->ptr + srclvl->faces[face].offset, - dstlvl->size); - radeon_bo_unmap(image->mt->bo); - - radeon_miptree_unreference(&image->mt); - } else { - uint32_t srcrowstride; - uint32_t height; - /* need to confirm this value is correct */ - if (mt->compressed) { - height = (image->base.Height + 3) / 4; - srcrowstride = _mesa_format_row_stride(image->base.TexFormat, image->base.Width); - } else { - height = image->base.Height * image->base.Depth; - srcrowstride = image->base.Width * _mesa_get_format_bytes(image->base.TexFormat); - } - -// if (mt->tilebits) -// WARN_ONCE("%s: tiling not supported yet", __FUNCTION__); - - copy_rows(dest, dstlvl->rowstride, image->base.Data, srcrowstride, - height, srcrowstride); - - _mesa_free_texmemory(image->base.Data); - image->base.Data = 0; - } - - radeon_bo_unmap(mt->bo); - - image->mtface = face; - image->mtlevel = level; - radeon_miptree_reference(mt, &image->mt); -} - -int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *texObj) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeonTexObj *t = radeon_tex_obj(texObj); - radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[0][texObj->BaseLevel]); - int face, level; - - if (t->validated || t->image_override) - return GL_TRUE; - - if (RADEON_DEBUG & RADEON_TEXTURE) - fprintf(stderr, "%s: Validating texture %p now\n", __FUNCTION__, texObj); + if (mesa_format == _dri_texformat_argb8888 || mesa_format == _dri_texformat_rgb565 || + mesa_format == _dri_texformat_argb1555 || mesa_format == _dri_texformat_argb4444) + return 1; - if (baseimage->base.Border > 0) - return GL_FALSE; - - /* Ensure a matching miptree exists. - * - * Differing mipmap trees can result when the app uses TexImage to - * change texture dimensions. - * - * Prefer to use base image's miptree if it - * exists, since that most likely contains more valid data (remember - * that the base level is usually significantly larger than the rest - * of the miptree, so cubemaps are the only possible exception). - */ - if (baseimage->mt && - baseimage->mt != t->mt && - radeon_miptree_matches_texture(baseimage->mt, &t->base)) { - radeon_miptree_unreference(&t->mt); - radeon_miptree_reference(baseimage->mt, &t->mt); - } else if (t->mt && !radeon_miptree_matches_texture(t->mt, &t->base)) { - radeon_miptree_unreference(&t->mt); - } - - if (!t->mt) { - if (RADEON_DEBUG & RADEON_TEXTURE) - fprintf(stderr, " Allocate new miptree\n"); - radeon_try_alloc_miptree(rmesa, t, baseimage, 0, texObj->BaseLevel); - if (!t->mt) { - _mesa_problem(ctx, "radeon_validate_texture failed to alloc miptree"); - return GL_FALSE; - } - } - - /* Ensure all images are stored in the single main miptree */ - for(face = 0; face < t->mt->faces; ++face) { - for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) { - radeon_texture_image *image = get_radeon_texture_image(texObj->Image[face][level]); - if (RADEON_DEBUG & RADEON_TEXTURE) - fprintf(stderr, " face %i, level %i... %p vs %p ", face, level, t->mt, image->mt); - if (t->mt == image->mt || (!image->mt && !image->base.Data)) { - if (RADEON_DEBUG & RADEON_TEXTURE) - fprintf(stderr, "OK\n"); - - continue; - } - - if (RADEON_DEBUG & RADEON_TEXTURE) - fprintf(stderr, "migrating\n"); - migrate_image_to_miptree(t->mt, image, face, level); - } - } - - return GL_TRUE; -} - - -/** - * Need to map texture image into memory before copying image data, - * then unmap it. - */ -static void -radeon_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) -{ - radeon_texture_image *image = get_radeon_texture_image(texImage); - - if (image->mt) { - /* Map the texture image read-only */ - radeon_teximage_map(image, GL_FALSE); - } else { - /* Image hasn't been uploaded to a miptree yet */ - assert(image->base.Data); - } - - if (compressed) { - /* FIXME: this can't work for small textures (mips) which - use different hw stride */ - _mesa_get_compressed_teximage(ctx, target, level, pixels, - texObj, texImage); - } else { - _mesa_get_teximage(ctx, target, level, format, type, pixels, - texObj, texImage); - } - - if (image->mt) { - radeon_teximage_unmap(image); + switch (mesa_format) + { + case MESA_FORMAT_Z16: + case MESA_FORMAT_S8_Z24: + return 1; + default: + return 0; } } - -void -radeonGetTexImage(GLcontext * ctx, GLenum target, GLint level, - GLenum format, GLenum type, GLvoid * pixels, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) -{ - radeon_get_tex_image(ctx, target, level, format, type, pixels, - texObj, texImage, 0); -} - -void -radeonGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level, - GLvoid *pixels, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) -{ - radeon_get_tex_image(ctx, target, level, 0, 0, pixels, - texObj, texImage, 1); -}