diff options
Diffstat (limited to 'src/mesa/drivers/dri/savage/savagetex.c')
-rw-r--r-- | src/mesa/drivers/dri/savage/savagetex.c | 2123 |
1 files changed, 0 insertions, 2123 deletions
diff --git a/src/mesa/drivers/dri/savage/savagetex.c b/src/mesa/drivers/dri/savage/savagetex.c deleted file mode 100644 index 9486c12c158..00000000000 --- a/src/mesa/drivers/dri/savage/savagetex.c +++ /dev/null @@ -1,2123 +0,0 @@ -/* - * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. - * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sub license, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - - -#include "main/context.h" -#include "main/mm.h" -#include "main/macros.h" -#include "main/texstore.h" -#include "main/texobj.h" -#include "main/colormac.h" -#include "main/simple_list.h" -#include "main/enums.h" - -#include "savagecontext.h" -#include "savagetex.h" -#include "savagetris.h" -#include "savageioctl.h" -#include "savage_bci.h" - -#include "xmlpool.h" - -#define TILE_INDEX_DXT1 0 -#define TILE_INDEX_8 1 -#define TILE_INDEX_16 2 -#define TILE_INDEX_DXTn 3 -#define TILE_INDEX_32 4 - -/* On Savage4 the texure LOD-bias needs an offset of ~ 0.3 to get - * somewhere close to software rendering. - */ -#define SAVAGE4_LOD_OFFSET 10 - -/* Tile info for S3TC formats counts in 4x4 blocks instead of texels. - * In DXT1 each block is encoded in 64 bits. In DXT3 and 5 each block is - * encoded in 128 bits. */ - -/* Size 1, 2 and 4 images are packed into the last subtile. Each image - * is repeated to fill a 4x4 pixel area. The figure below shows the - * layout of those 4x4 pixel areas in the 8x8 subtile. - * - * 4 2 - * x 1 - * - * Yuck! 8-bit texture formats use 4x8 subtiles. See below. - */ -static const savageTileInfo tileInfo_pro[5] = { - {16, 16, 16, 8, 1, 2, {0x18, 0x10}}, /* DXT1 */ - {64, 32, 16, 4, 4, 8, {0x30, 0x20}}, /* 8-bit */ - {64, 16, 8, 2, 8, 8, {0x48, 0x08}}, /* 16-bit */ - {16, 8, 16, 4, 1, 2, {0x30, 0x20}}, /* DXT3, DXT5 */ - {32, 16, 4, 2, 8, 8, {0x90, 0x10}}, /* 32-bit */ -}; - -/* Size 1, 2 and 4 images are packed into the last two subtiles. Each - * image is repeated to fill a 4x4 pixel area. The figures below show - * the layout of those 4x4 pixel areas in the two 4x8 subtiles. - * - * second last subtile: 4 last subtile: 2 - * x 1 - */ -static const savageTileInfo tileInfo_s3d_s4[5] = { - {16, 16, 16, 8, 1, 2, {0x18, 0x10}}, /* DXT1 */ - {64, 32, 16, 4, 4, 8, {0x30, 0x20}}, /* 8-bit */ - {64, 16, 16, 2, 4, 8, {0x60, 0x40}}, /* 16-bit */ - {16, 8, 16, 4, 1, 2, {0x30, 0x20}}, /* DXT3, DXT5 */ - {32, 16, 8, 2, 4, 8, {0xc0, 0x80}}, /* 32-bit */ -}; - -/** \brief Template for subtile uploads. - * \param h height in pixels - * \param w width in bytes - */ -#define SUBTILE_FUNC(w,h) \ -static INLINE GLubyte *savageUploadSubtile_##w##x##h \ -(GLubyte *dest, GLubyte *src, GLuint srcStride) \ -{ \ - GLuint y; \ - for (y = 0; y < h; ++y) { \ - memcpy (dest, src, w); \ - src += srcStride; \ - dest += w; \ - } \ - return dest; \ -} - -SUBTILE_FUNC(2, 8) /* 4 bits per pixel, 4 pixels wide */ -SUBTILE_FUNC(4, 8) -SUBTILE_FUNC(8, 8) -SUBTILE_FUNC(16, 8) -SUBTILE_FUNC(32, 8) /* 4 bytes per pixel, 8 pixels wide */ - -SUBTILE_FUNC(8, 2) /* DXT1 */ -SUBTILE_FUNC(16, 2) /* DXT3 and DXT5 */ - -/** \brief Upload a complete tile from src (srcStride) to dest - * - * \param tileInfo Pointer to tiling information - * \param wInSub Width of source/dest image in subtiles - * \param hInSub Height of source/dest image in subtiles - * \param bpp Bytes per pixel - * \param src Pointer to source data - * \param srcStride Byte stride of rows in the source data - * \param dest Pointer to destination - * - * Writes linearly to the destination memory in order to exploit write - * combining. - * - * For a complete tile wInSub and hInSub are set to the same values as - * in tileInfo. If the source image is smaller than a whole tile in - * one or both dimensions then they are set to the values of the - * source image. This only works as long as the source image is bigger - * than 8x8 pixels. - */ -static void savageUploadTile (const savageTileInfo *tileInfo, - GLuint wInSub, GLuint hInSub, GLuint bpp, - GLubyte *src, GLuint srcStride, GLubyte *dest) { - GLuint subStride = tileInfo->subWidth * bpp; - GLubyte *srcSRow = src, *srcSTile = src; - GLubyte *(*subtileFunc) (GLubyte *, GLubyte *, GLuint); - GLuint sx, sy; - switch (subStride) { - case 2: subtileFunc = savageUploadSubtile_2x8; break; - case 4: subtileFunc = savageUploadSubtile_4x8; break; - case 8: subtileFunc = tileInfo->subHeight == 8 ? - savageUploadSubtile_8x8 : savageUploadSubtile_8x2; break; - case 16: subtileFunc = tileInfo->subHeight == 8 ? - savageUploadSubtile_16x8 : savageUploadSubtile_16x2; break; - case 32: subtileFunc = savageUploadSubtile_32x8; break; - default: assert(0); - } - for (sy = 0; sy < hInSub; ++sy) { - srcSTile = srcSRow; - for (sx = 0; sx < wInSub; ++sx) { - src = srcSTile; - dest = subtileFunc (dest, src, srcStride); - srcSTile += subStride; - } - srcSRow += srcStride * tileInfo->subHeight; - } -} - -/** \brief Upload a image that is smaller than 8 pixels in either dimension. - * - * \param tileInfo Pointer to tiling information - * \param width Width of the image - * \param height Height of the image - * \param bpp Bytes per pixel - * \param src Pointer to source data - * \param dest Pointer to destination - * - * This function handles all the special cases that need to be taken - * care off. The caller may need to call this function multiple times - * with the destination offset in different ways since small texture - * images must be repeated in order to fill a whole tile (or 4x4 for - * the last 3 levels). - * - * FIXME: Repeating inside this function would be more efficient. - */ -static void savageUploadTiny (const savageTileInfo *tileInfo, - GLuint pixWidth, GLuint pixHeight, - GLuint width, GLuint height, GLuint bpp, - GLubyte *src, GLubyte *dest) { - GLuint size = MAX2(pixWidth, pixHeight); - - if (width > tileInfo->subWidth) { /* assert: height <= subtile height */ - GLuint wInSub = width / tileInfo->subWidth; - GLuint srcStride = width * bpp; - GLuint subStride = tileInfo->subWidth * bpp; - GLuint subSkip = (tileInfo->subHeight - height) * subStride; - GLubyte *srcSTile = src; - GLuint sx, y; - for (sx = 0; sx < wInSub; ++sx) { - src = srcSTile; - for (y = 0; y < height; ++y) { - memcpy (dest, src, subStride); - src += srcStride; - dest += subStride; - } - dest += subSkip; - srcSTile += subStride; - } - } else if (size > 4) { /* a tile or less wide, except the last 3 levels */ - GLuint srcStride = width * bpp; - GLuint subStride = tileInfo->subWidth * bpp; - /* if the subtile width is 4 we have to skip every other subtile */ - GLuint subSkip = tileInfo->subWidth <= 4 ? - subStride * tileInfo->subHeight : 0; - GLuint skipRemainder = tileInfo->subHeight - 1; - GLuint y; - for (y = 0; y < height; ++y) { - memcpy (dest, src, srcStride); - src += srcStride; - dest += subStride; - if ((y & skipRemainder) == skipRemainder) - dest += subSkip; - } - } else { /* the last 3 mipmap levels */ - GLuint offset = (size <= 2 ? tileInfo->tinyOffset[size-1] : 0); - GLuint subStride = tileInfo->subWidth * bpp; - GLuint y; - dest += offset; - for (y = 0; y < height; ++y) { - memcpy (dest, src, bpp*width); - src += width * bpp; - dest += subStride; - } - } -} - -/** \brief Upload an image from mesa's internal copy. - */ -static void savageUploadTexLevel( savageTexObjPtr t, int level ) -{ - const struct gl_texture_image *image = t->base.tObj->Image[0][level]; - const savageTileInfo *tileInfo = t->tileInfo; - GLuint pixWidth = image->Width2, pixHeight = image->Height2; - GLuint bpp = t->texelBytes; - GLuint width, height; - - /* FIXME: Need triangle (rather than pixel) fallbacks to simulate - * this using normal textured triangles. - * - * DO THIS IN DRIVER STATE MANAGMENT, not hardware state. - */ - if(image->Border != 0) - fprintf (stderr, "Not supported texture border %d.\n", - (int) image->Border); - - if (t->hwFormat == TFT_S3TC4A4Bit || t->hwFormat == TFT_S3TC4CA4Bit || - t->hwFormat == TFT_S3TC4Bit) { - width = (pixWidth+3) / 4; - height = (pixHeight+3) / 4; - } else { - width = pixWidth; - height = pixHeight; - } - - if (pixWidth >= 8 && pixHeight >= 8) { - GLuint *dirtyPtr = t->image[level].dirtyTiles; - GLuint dirtyMask = 1; - - if (width >= tileInfo->width && height >= tileInfo->height) { - GLuint wInTiles = width / tileInfo->width; - GLuint hInTiles = height / tileInfo->height; - GLubyte *srcTRow = image->Data, *src; - GLubyte *dest = (GLubyte *)(t->bufAddr + t->image[level].offset); - GLuint x, y; - for (y = 0; y < hInTiles; ++y) { - src = srcTRow; - for (x = 0; x < wInTiles; ++x) { - if (*dirtyPtr & dirtyMask) { - savageUploadTile (tileInfo, - tileInfo->wInSub, tileInfo->hInSub, - bpp, src, width * bpp, dest); - } - src += tileInfo->width * bpp; - dest += 2048; /* tile size is always 2k */ - if (dirtyMask == 1<<31) { - dirtyMask = 1; - dirtyPtr++; - } else - dirtyMask <<= 1; - } - srcTRow += width * tileInfo->height * bpp; - } - } else if (width >= tileInfo->width) { - GLuint wInTiles = width / tileInfo->width; - GLubyte *src = image->Data; - GLubyte *dest = (GLubyte *)(t->bufAddr + t->image[level].offset); - GLuint tileStride = tileInfo->width * bpp * height; - savageContextPtr imesa = (savageContextPtr)t->base.heap->driverContext; - GLuint x; - /* Savage3D-based chips seem so use a constant tile stride - * of 2048 for vertically incomplete tiles, but only if - * the color depth is 32bpp. Nobody said this was supposed - * to be logical! - */ - if (bpp == 4 && imesa->savageScreen->chipset < S3_SAVAGE4) - tileStride = 2048; - for (x = 0; x < wInTiles; ++x) { - if (*dirtyPtr & dirtyMask) { - savageUploadTile (tileInfo, - tileInfo->wInSub, - height / tileInfo->subHeight, - bpp, src, width * bpp, dest); - } - src += tileInfo->width * bpp; - dest += tileStride; - if (dirtyMask == 1<<31) { - dirtyMask = 1; - dirtyPtr++; - } else - dirtyMask <<= 1; - } - } else { - savageUploadTile (tileInfo, width / tileInfo->subWidth, - height / tileInfo->subHeight, bpp, - image->Data, width * bpp, - (GLubyte *)(t->bufAddr+t->image[level].offset)); - } - } else { - GLuint minHeight, minWidth, hRepeat, vRepeat, x, y; - if (t->hwFormat == TFT_S3TC4A4Bit || t->hwFormat == TFT_S3TC4CA4Bit || - t->hwFormat == TFT_S3TC4Bit) - minWidth = minHeight = 1; - else - minWidth = minHeight = 4; - if (width > minWidth || height > minHeight) { - minWidth = tileInfo->subWidth; - minHeight = tileInfo->subHeight; - } - hRepeat = width >= minWidth ? 1 : minWidth / width; - vRepeat = height >= minHeight ? 1 : minHeight / height; - for (y = 0; y < vRepeat; ++y) { - GLuint offset = y * tileInfo->subWidth*height * bpp; - for (x = 0; x < hRepeat; ++x) { - savageUploadTiny (tileInfo, pixWidth, pixHeight, - width, height, bpp, image->Data, - (GLubyte *)(t->bufAddr + - t->image[level].offset+offset)); - offset += width * bpp; - } - } - } -} - -/** \brief Compute the destination size of a texture image - */ -static GLuint savageTexImageSize (GLuint width, GLuint height, GLuint bpp) { - /* full subtiles */ - if (width >= 8 && height >= 8) - return width * height * bpp; - /* special case for the last three mipmap levels: the hardware computes - * the offset internally */ - else if (width <= 4 && height <= 4) - return 0; - /* partially filled sub tiles waste memory - * on Savage3D and Savage4 with subtile width 4 every other subtile is - * skipped if width < 8 so we can assume a uniform subtile width of 8 */ - else if (width >= 8) - return width * 8 * bpp; - else if (height >= 8) - return 8 * height * bpp; - else - return 64 * bpp; -} - -/** \brief Compute the destination size of a compressed texture image - */ -static GLuint savageCompressedTexImageSize (GLuint width, GLuint height, - GLuint bpp) { - width = (width+3) / 4; - height = (height+3) / 4; - /* full subtiles */ - if (width >= 2 && height >= 2) - return width * height * bpp; - /* special case for the last three mipmap levels: the hardware computes - * the offset internally */ - else if (width <= 1 && height <= 1) - return 0; - /* partially filled sub tiles waste memory - * on Savage3D and Savage4 with subtile width 4 every other subtile is - * skipped if width < 8 so we can assume a uniform subtile width of 8 */ - else if (width >= 2) - return width * 2 * bpp; - else if (height >= 2) - return 2 * height * bpp; - else - return 4 * bpp; -} - -/** \brief Compute the number of (partial) tiles of a texture image - */ -static GLuint savageTexImageTiles (GLuint width, GLuint height, - const savageTileInfo *tileInfo) -{ - return (width + tileInfo->width - 1) / tileInfo->width * - (height + tileInfo->height - 1) / tileInfo->height; -} - -/** \brief Mark dirty tiles - * - * Some care must be taken because tileInfo may not be set or not - * up-to-date. So we check if tileInfo is initialized and if the number - * of tiles in the bit vector matches the number of tiles computed from - * the current tileInfo. - */ -static void savageMarkDirtyTiles (savageTexObjPtr t, GLuint level, - GLuint totalWidth, GLuint totalHeight, - GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height) -{ - GLuint wInTiles, hInTiles; - GLuint x0, y0, x1, y1; - GLuint x, y; - if (!t->tileInfo) - return; - wInTiles = (totalWidth + t->tileInfo->width - 1) / t->tileInfo->width; - hInTiles = (totalHeight + t->tileInfo->height - 1) / t->tileInfo->height; - if (wInTiles * hInTiles != t->image[level].nTiles) - return; - - x0 = xoffset / t->tileInfo->width; - y0 = yoffset / t->tileInfo->height; - x1 = (xoffset + width - 1) / t->tileInfo->width; - y1 = (yoffset + height - 1) / t->tileInfo->height; - - for (y = y0; y <= y1; ++y) { - GLuint *ptr = t->image[level].dirtyTiles + (y * wInTiles + x0) / 32; - GLuint mask = 1 << (y * wInTiles + x0) % 32; - for (x = x0; x <= x1; ++x) { - *ptr |= mask; - if (mask == (1<<31)) { - ptr++; - mask = 1; - } else { - mask <<= 1; - } - } - } -} - -/** \brief Mark all tiles as dirty - */ -static void savageMarkAllTiles (savageTexObjPtr t, GLuint level) -{ - GLuint words = (t->image[level].nTiles + 31) / 32; - if (words) - memset(t->image[level].dirtyTiles, ~0, words*sizeof(GLuint)); -} - - -static void savageSetTexWrapping(savageTexObjPtr tex, GLenum s, GLenum t) -{ - tex->setup.sWrapMode = s; - tex->setup.tWrapMode = t; -} - -static void savageSetTexFilter(savageTexObjPtr t, GLenum minf, GLenum magf) -{ - t->setup.minFilter = minf; - t->setup.magFilter = magf; -} - - -/* Need a fallback ? - */ -static void savageSetTexBorderColor(savageTexObjPtr t, const GLfloat color[4]) -{ -/* t->Setup[SAVAGE_TEXREG_TEXBORDERCOL] = */ - /*t->setup.borderColor = SAVAGEPACKCOLOR8888(color[0],color[1],color[2],color[3]); */ -} - - - -static savageTexObjPtr -savageAllocTexObj( struct gl_texture_object *texObj ) -{ - savageTexObjPtr t; - - t = (savageTexObjPtr) calloc(1,sizeof(*t)); - texObj->DriverData = t; - if ( t != NULL ) { - GLuint i; - - /* Initialize non-image-dependent parts of the state: - */ - t->base.tObj = texObj; - t->base.dirty_images[0] = 0; - t->dirtySubImages = 0; - t->tileInfo = NULL; - - /* Initialize dirty tiles bit vectors - */ - for (i = 0; i < SAVAGE_TEX_MAXLEVELS; ++i) - t->image[i].nTiles = 0; - - /* FIXME Something here to set initial values for other parts of - * FIXME t->setup? - */ - - make_empty_list( &t->base ); - - savageSetTexWrapping(t,texObj->Sampler.WrapS,texObj->Sampler.WrapT); - savageSetTexFilter(t,texObj->Sampler.MinFilter,texObj->Sampler.MagFilter); - savageSetTexBorderColor(t,texObj->Sampler.BorderColor.f); - } - - return t; -} - -/* Mesa texture formats for alpha-images on Savage3D/IX/MX - * - * Promoting texture images to ARGB888 or ARGB4444 doesn't work - * because we can't tell the hardware to ignore the color components - * and only use the alpha component. So we define our own texture - * formats that promote to ARGB8888 or ARGB4444 and set the color - * components to white. This way we get the correct result. - */ - -#if 0 -/* Using MESA_FORMAT_RGBA8888 to store alpha-only textures should - * work but is space inefficient. - */ - -static GLboolean -_savage_texstore_a1114444(TEXSTORE_PARAMS); - -static GLboolean -_savage_texstore_a1118888(TEXSTORE_PARAMS); - -static struct gl_texture_format _savage_texformat_a1114444 = { - MESA_FORMAT_ARGB4444, /* MesaFormat */ - GL_RGBA, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED_ARB, /* DataType */ - 4, /* RedBits */ - 4, /* GreenBits */ - 4, /* BlueBits */ - 4, /* AlphaBits */ - 0, /* LuminanceBits */ - 0, /* IntensityBits */ - 0, /* IndexBits */ - 0, /* DepthBits */ - 0, /* StencilBits */ - 2, /* TexelBytes */ - _savage_texstore_a1114444, /* StoreTexImageFunc */ - NULL, NULL, NULL, NULL, NULL, NULL /* FetchTexel* filled in by - * savageDDInitTextureFuncs */ -}; -static struct gl_texture_format _savage_texformat_a1118888 = { - MESA_FORMAT_ARGB8888, /* MesaFormat */ - GL_RGBA, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED_ARB, /* DataType */ - 8, /* RedBits */ - 8, /* GreenBits */ - 8, /* BlueBits */ - 8, /* AlphaBits */ - 0, /* LuminanceBits */ - 0, /* IntensityBits */ - 0, /* IndexBits */ - 0, /* DepthBits */ - 0, /* StencilBits */ - 4, /* TexelBytes */ - _savage_texstore_a1118888, /* StoreTexImageFunc */ - NULL, NULL, NULL, NULL, NULL, NULL /* FetchTexel* filled in by - * savageDDInitTextureFuncs */ -}; - - -static GLboolean -_savage_texstore_a1114444(TEXSTORE_PARAMS) -{ - const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, - baseInternalFormat, - baseInternalFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); - const GLchan *src = tempImage; - GLint img, row, col; - - ASSERT(dstFormat == &_savage_texformat_a1114444); - ASSERT(baseInternalFormat == GL_ALPHA); - - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLuint texelBytes = _mesa_get_format_bytes(dstFormat); - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; - for (row = 0; row < srcHeight; row++) { - GLushort *dstUI = (GLushort *) dstRow; - for (col = 0; col < srcWidth; col++) { - dstUI[col] = PACK_COLOR_4444( CHAN_TO_UBYTE(src[0]), - 255, 255, 255 ); - src += 1; - } - dstRow += dstRowStride; - } - } - free((void *) tempImage); - - return GL_TRUE; -} - - -static GLboolean -_savage_texstore_a1118888(TEXSTORE_PARAMS) -{ - const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, - baseInternalFormat, - baseInternalFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); - const GLchan *src = tempImage; - GLint img, row, col; - - ASSERT(dstFormat == &_savage_texformat_a1118888); - ASSERT(baseInternalFormat == GL_ALPHA); - - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLuint texelBytes = _mesa_get_format_bytes(dstFormat); - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; - for (row = 0; row < srcHeight; row++) { - GLuint *dstUI = (GLuint *) dstRow; - for (col = 0; col < srcWidth; col++) { - dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[0]), - 255, 255, 255 ); - src += 1; - } - dstRow += dstRowStride; - } - } - free((void *) tempImage); - - return GL_TRUE; -} -#endif - - -/* Called by the _mesa_store_teximage[123]d() functions. */ -static gl_format -savageChooseTextureFormat( struct gl_context *ctx, GLint internalFormat, - GLenum format, GLenum type ) -{ - savageContextPtr imesa = SAVAGE_CONTEXT(ctx); - const GLboolean do32bpt = - ( imesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32 ); - const GLboolean force16bpt = - ( imesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16 ); - const GLboolean isSavage4 = (imesa->savageScreen->chipset >= S3_SAVAGE4); - (void) format; - - switch ( internalFormat ) { - case 4: - case GL_RGBA: - case GL_COMPRESSED_RGBA: - switch ( type ) { - case GL_UNSIGNED_INT_10_10_10_2: - case GL_UNSIGNED_INT_2_10_10_10_REV: - return do32bpt ? MESA_FORMAT_ARGB8888 : MESA_FORMAT_ARGB1555; - case GL_UNSIGNED_SHORT_4_4_4_4: - case GL_UNSIGNED_SHORT_4_4_4_4_REV: - return MESA_FORMAT_ARGB4444; - case GL_UNSIGNED_SHORT_5_5_5_1: - case GL_UNSIGNED_SHORT_1_5_5_5_REV: - return MESA_FORMAT_ARGB1555; - default: - return do32bpt ? MESA_FORMAT_ARGB8888 : MESA_FORMAT_ARGB4444; - } - - case 3: - case GL_RGB: - case GL_COMPRESSED_RGB: - switch ( type ) { - case GL_UNSIGNED_SHORT_4_4_4_4: - case GL_UNSIGNED_SHORT_4_4_4_4_REV: - return MESA_FORMAT_ARGB4444; - case GL_UNSIGNED_SHORT_5_5_5_1: - case GL_UNSIGNED_SHORT_1_5_5_5_REV: - return MESA_FORMAT_ARGB1555; - case GL_UNSIGNED_SHORT_5_6_5: - case GL_UNSIGNED_SHORT_5_6_5_REV: - return MESA_FORMAT_RGB565; - default: - return do32bpt ? MESA_FORMAT_ARGB8888 : MESA_FORMAT_RGB565; - } - - case GL_RGBA8: - case GL_RGBA12: - case GL_RGBA16: - return !force16bpt ? - MESA_FORMAT_ARGB8888 : MESA_FORMAT_ARGB4444; - - case GL_RGB10_A2: - return !force16bpt ? - MESA_FORMAT_ARGB8888 : MESA_FORMAT_ARGB1555; - - case GL_RGBA4: - case GL_RGBA2: - return MESA_FORMAT_ARGB4444; - - case GL_RGB5_A1: - return MESA_FORMAT_ARGB1555; - - case GL_RGB8: - case GL_RGB10: - case GL_RGB12: - case GL_RGB16: - return !force16bpt ? MESA_FORMAT_ARGB8888 : MESA_FORMAT_RGB565; - - case GL_RGB5: - case GL_RGB4: - case GL_R3_G3_B2: - return MESA_FORMAT_RGB565; - - case GL_ALPHA: - case GL_COMPRESSED_ALPHA: -#if 0 - return isSavage4 ? MESA_FORMAT_a8 : ( - do32bpt ? &_savage_texformat_a1118888 : &_savage_texformat_a1114444); -#else - if (isSavage4) - return MESA_FORMAT_A8; - else if (do32bpt) - return MESA_FORMAT_ARGB8888; - else - return MESA_FORMAT_ARGB4444; -#endif - case GL_ALPHA4: -#if 0 - return isSavage4 ? MESA_FORMAT_a8 : &_savage_texformat_a1114444; -#else - if (isSavage4) - return MESA_FORMAT_A8; - else - return MESA_FORMAT_ARGB4444; -#endif - case GL_ALPHA8: - case GL_ALPHA12: - case GL_ALPHA16: -#if 0 - return isSavage4 ? MESA_FORMAT_a8 : ( - !force16bpt ? &_savage_texformat_a1118888 : &_savage_texformat_a1114444); -#else - if (isSavage4) - return MESA_FORMAT_A8; - else if (force16bpt) - return MESA_FORMAT_ARGB4444; - else - return MESA_FORMAT_ARGB8888; -#endif - case 1: - case GL_LUMINANCE: - case GL_COMPRESSED_LUMINANCE: - /* no alpha, but use argb1555 in 16bit case to get pure grey values */ - return isSavage4 ? MESA_FORMAT_L8 : ( - do32bpt ? MESA_FORMAT_ARGB8888 : MESA_FORMAT_ARGB1555); - case GL_LUMINANCE4: - return isSavage4 ? MESA_FORMAT_L8 : MESA_FORMAT_ARGB1555; - case GL_LUMINANCE8: - case GL_LUMINANCE12: - case GL_LUMINANCE16: - return isSavage4 ? MESA_FORMAT_L8 : ( - !force16bpt ? MESA_FORMAT_ARGB8888 : MESA_FORMAT_ARGB1555); - - case 2: - case GL_LUMINANCE_ALPHA: - case GL_COMPRESSED_LUMINANCE_ALPHA: - /* Savage4 has a al44 texture format. But it's not supported by Mesa. */ - return do32bpt ? MESA_FORMAT_ARGB8888 : MESA_FORMAT_ARGB4444; - case GL_LUMINANCE4_ALPHA4: - case GL_LUMINANCE6_ALPHA2: - return MESA_FORMAT_ARGB4444; - case GL_LUMINANCE8_ALPHA8: - case GL_LUMINANCE12_ALPHA4: - case GL_LUMINANCE12_ALPHA12: - case GL_LUMINANCE16_ALPHA16: - return !force16bpt ? MESA_FORMAT_ARGB8888 : MESA_FORMAT_ARGB4444; -#if 0 - /* TFT_I8 produces garbage on ProSavageDDR and subsequent texture - * disable keeps rendering garbage. Disabled for now. */ - case GL_INTENSITY: - case GL_COMPRESSED_INTENSITY: - return isSavage4 ? MESA_FORMAT_i8 : ( - do32bpt ? MESA_FORMAT_ARGB8888 : MESA_FORMAT_ARGB4444); - case GL_INTENSITY4: - return isSavage4 ? MESA_FORMAT_i8 : MESA_FORMAT_ARGB4444; - case GL_INTENSITY8: - case GL_INTENSITY12: - case GL_INTENSITY16: - return isSavage4 ? MESA_FORMAT_i8 : ( - !force16bpt ? MESA_FORMAT_ARGB8888 : MESA_FORMAT_ARGB4444); -#else - case GL_INTENSITY: - case GL_COMPRESSED_INTENSITY: - return do32bpt ? MESA_FORMAT_ARGB8888 : MESA_FORMAT_ARGB4444; - case GL_INTENSITY4: - return MESA_FORMAT_ARGB4444; - case GL_INTENSITY8: - case GL_INTENSITY12: - case GL_INTENSITY16: - return !force16bpt ? MESA_FORMAT_ARGB8888 : MESA_FORMAT_ARGB4444; -#endif - - case GL_RGB_S3TC: - case GL_RGB4_S3TC: - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - return MESA_FORMAT_RGB_DXT1; - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - return MESA_FORMAT_RGBA_DXT1; - - case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - return MESA_FORMAT_RGBA_DXT3; - - case GL_RGBA_S3TC: - case GL_RGBA4_S3TC: - if (!isSavage4) - /* Not the best choice but Savage3D/MX/IX don't support DXT3 or DXT5. */ - return MESA_FORMAT_RGBA_DXT1; - /* fall through */ - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - return MESA_FORMAT_RGBA_DXT5; - -/* - case GL_COLOR_INDEX: - case GL_COLOR_INDEX1_EXT: - case GL_COLOR_INDEX2_EXT: - case GL_COLOR_INDEX4_EXT: - case GL_COLOR_INDEX8_EXT: - case GL_COLOR_INDEX12_EXT: - case GL_COLOR_INDEX16_EXT: - return &_mesa_texformat_ci8; -*/ - default: - _mesa_problem(ctx, "unexpected texture format in %s", __FUNCTION__); - return MESA_FORMAT_NONE; - } -} - -static void savageSetTexImages( savageContextPtr imesa, - const struct gl_texture_object *tObj ) -{ - savageTexObjPtr t = (savageTexObjPtr) tObj->DriverData; - struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; - GLuint offset, i, textureFormat, tileIndex, size; - GLint firstLevel, lastLevel; - - assert(t); - assert(image); - - switch (image->TexFormat) { - case MESA_FORMAT_ARGB8888: - textureFormat = TFT_ARGB8888; - t->texelBytes = tileIndex = 4; - break; - case MESA_FORMAT_ARGB1555: - textureFormat = TFT_ARGB1555; - t->texelBytes = tileIndex = 2; - break; - case MESA_FORMAT_ARGB4444: - textureFormat = TFT_ARGB4444; - t->texelBytes = tileIndex = 2; - break; - case MESA_FORMAT_RGB565: - textureFormat = TFT_RGB565; - t->texelBytes = tileIndex = 2; - break; - case MESA_FORMAT_L8: - textureFormat = TFT_L8; - t->texelBytes = tileIndex = 1; - break; - case MESA_FORMAT_I8: - textureFormat = TFT_I8; - t->texelBytes = tileIndex = 1; - break; - case MESA_FORMAT_A8: - textureFormat = TFT_A8; - t->texelBytes = tileIndex = 1; - break; - case MESA_FORMAT_RGB_DXT1: - textureFormat = TFT_S3TC4Bit; - tileIndex = TILE_INDEX_DXT1; - t->texelBytes = 8; - break; - case MESA_FORMAT_RGBA_DXT1: - textureFormat = TFT_S3TC4Bit; - tileIndex = TILE_INDEX_DXT1; - t->texelBytes = 8; - break; - case MESA_FORMAT_RGBA_DXT3: - textureFormat = TFT_S3TC4A4Bit; - tileIndex = TILE_INDEX_DXTn; - t->texelBytes = 16; - break; - case MESA_FORMAT_RGBA_DXT5: - textureFormat = TFT_S3TC4CA4Bit; - tileIndex = TILE_INDEX_DXTn; - t->texelBytes = 16; - break; - default: - _mesa_problem(imesa->glCtx, "Bad texture format in %s", __FUNCTION__); - return; - } - t->hwFormat = textureFormat; - - /* Select tiling format depending on the chipset and texture format */ - if (imesa->savageScreen->chipset <= S3_SAVAGE4) - t->tileInfo = &tileInfo_s3d_s4[tileIndex]; - else - t->tileInfo = &tileInfo_pro[tileIndex]; - - /* Compute which mipmap levels we really want to send to the hardware. - */ - driCalculateTextureFirstLastLevel( &t->base ); - firstLevel = t->base.firstLevel; - lastLevel = t->base.lastLevel; - - /* Figure out the size now (and count the levels). Upload won't be - * done until later. If the number of tiles changes, it means that - * this function is called for the first time on this tex object or - * the image or the destination color format changed. So all tiles - * are marked as dirty. - */ - offset = 0; - size = 1; - for ( i = firstLevel ; i <= lastLevel && tObj->Image[0][i] ; i++ ) { - GLuint nTiles; - nTiles = savageTexImageTiles (image->Width2, image->Height2, t->tileInfo); - if (t->image[i].nTiles != nTiles) { - GLuint words = (nTiles + 31) / 32; - if (t->image[i].nTiles != 0) { - free(t->image[i].dirtyTiles); - } - t->image[i].dirtyTiles = malloc(words*sizeof(GLuint)); - memset(t->image[i].dirtyTiles, ~0, words*sizeof(GLuint)); - } - t->image[i].nTiles = nTiles; - - t->image[i].offset = offset; - - image = tObj->Image[0][i]; - if (t->texelBytes >= 8) - size = savageCompressedTexImageSize (image->Width2, image->Height2, - t->texelBytes); - else - size = savageTexImageSize (image->Width2, image->Height2, - t->texelBytes); - offset += size; - } - - t->base.lastLevel = i-1; - t->base.totalSize = offset; - /* the last three mipmap levels don't add to the offset. They are packed - * into 64 pixels. */ - if (size == 0) - t->base.totalSize += (t->texelBytes >= 8 ? 4 : 64) * t->texelBytes; - /* 2k-aligned (really needed?) */ - t->base.totalSize = (t->base.totalSize + 2047UL) & ~2047UL; -} - -void savageDestroyTexObj(savageContextPtr imesa, savageTexObjPtr t) -{ - GLuint i; - - /* Free dirty tiles bit vectors */ - for (i = 0; i < SAVAGE_TEX_MAXLEVELS; ++i) { - if (t->image[i].nTiles) - free (t->image[i].dirtyTiles); - } - - /* See if it was the driver's current object. - */ - if ( imesa != NULL ) - { - for ( i = 0 ; i < imesa->glCtx->Const.MaxTextureUnits ; i++ ) - { - if ( &t->base == imesa->CurrentTexObj[ i ] ) { - assert( t->base.bound & (1 << i) ); - imesa->CurrentTexObj[ i ] = NULL; - } - } - } -} - -/* Upload a texture's images to one of the texture heaps. May have to - * eject our own and/or other client's texture objects to make room - * for the upload. - */ -static void savageUploadTexImages( savageContextPtr imesa, savageTexObjPtr t ) -{ - const GLint numLevels = t->base.lastLevel - t->base.firstLevel + 1; - GLuint i; - - assert(t); - - LOCK_HARDWARE(imesa); - - /* Do we need to eject LRU texture objects? - */ - if (!t->base.memBlock) { - GLint heap; - GLuint ofs; - - heap = driAllocateTexture(imesa->textureHeaps, imesa->lastTexHeap, - (driTextureObject *)t); - if (heap == -1) { - UNLOCK_HARDWARE(imesa); - return; - } - - assert(t->base.memBlock); - ofs = t->base.memBlock->ofs; - t->setup.physAddr = imesa->savageScreen->textureOffset[heap] + ofs; - t->bufAddr = (GLubyte *)imesa->savageScreen->texVirtual[heap] + ofs; - imesa->dirty |= SAVAGE_UPLOAD_GLOBAL; /* FIXME: really needed? */ - } - - /* Let the world know we've used this memory recently. - */ - driUpdateTextureLRU( &t->base ); - UNLOCK_HARDWARE(imesa); - - if (t->base.dirty_images[0] || t->dirtySubImages) { - if (SAVAGE_DEBUG & DEBUG_VERBOSE_TEX) - fprintf(stderr, "Texture upload: |"); - - /* Heap timestamps are only reliable with Savage DRM 2.3.x or - * later. Earlier versions had only 16 bit time stamps which - * would wrap too frequently. */ - if (imesa->savageScreen->driScrnPriv->drm_version.minor >= 3) { - unsigned int heap = t->base.heap->heapId; - LOCK_HARDWARE(imesa); - savageWaitEvent (imesa, imesa->textureHeaps[heap]->timestamp); - } else { - savageFlushVertices (imesa); - LOCK_HARDWARE(imesa); - savageFlushCmdBufLocked (imesa, GL_FALSE); - WAIT_IDLE_EMPTY_LOCKED(imesa); - } - - for (i = 0 ; i < numLevels ; i++) { - const GLint j = t->base.firstLevel + i; /* the texObj's level */ - if (t->base.dirty_images[0] & (1 << j)) { - savageMarkAllTiles(t, j); - if (SAVAGE_DEBUG & DEBUG_VERBOSE_TEX) - fprintf (stderr, "*"); - } else if (SAVAGE_DEBUG & DEBUG_VERBOSE_TEX) { - if (t->dirtySubImages & (1 << j)) - fprintf (stderr, "."); - else - fprintf (stderr, " "); - } - if ((t->base.dirty_images[0] | t->dirtySubImages) & (1 << j)) - savageUploadTexLevel( t, j ); - } - - UNLOCK_HARDWARE(imesa); - t->base.dirty_images[0] = 0; - t->dirtySubImages = 0; - - if (SAVAGE_DEBUG & DEBUG_VERBOSE_TEX) - fprintf(stderr, "|\n"); - } -} - - -static void -savage4_set_wrap_mode( savageContextPtr imesa, unsigned unit, - GLenum s_mode, GLenum t_mode ) -{ - switch( s_mode ) { - case GL_REPEAT: - imesa->regs.s4.texCtrl[ unit ].ni.uMode = TAM_Wrap; - break; - case GL_CLAMP: - case GL_CLAMP_TO_EDGE: - imesa->regs.s4.texCtrl[ unit ].ni.uMode = TAM_Clamp; - break; - case GL_MIRRORED_REPEAT: - imesa->regs.s4.texCtrl[ unit ].ni.uMode = TAM_Mirror; - break; - } - - switch( t_mode ) { - case GL_REPEAT: - imesa->regs.s4.texCtrl[ unit ].ni.vMode = TAM_Wrap; - break; - case GL_CLAMP: - case GL_CLAMP_TO_EDGE: - imesa->regs.s4.texCtrl[ unit ].ni.vMode = TAM_Clamp; - break; - case GL_MIRRORED_REPEAT: - imesa->regs.s4.texCtrl[ unit ].ni.vMode = TAM_Mirror; - break; - } -} - - -/** - * Sets the hardware bits for the specified GL texture filter modes. - * - * \todo - * Does the Savage4 have the ability to select the magnification filter? - */ -static void -savage4_set_filter_mode( savageContextPtr imesa, unsigned unit, - GLenum minFilter, GLenum magFilter ) -{ - (void) magFilter; - - switch (minFilter) { - case GL_NEAREST: - imesa->regs.s4.texCtrl[ unit ].ni.filterMode = TFM_Point; - imesa->regs.s4.texCtrl[ unit ].ni.mipmapEnable = GL_FALSE; - break; - - case GL_LINEAR: - imesa->regs.s4.texCtrl[ unit ].ni.filterMode = TFM_Bilin; - imesa->regs.s4.texCtrl[ unit ].ni.mipmapEnable = GL_FALSE; - break; - - case GL_NEAREST_MIPMAP_NEAREST: - imesa->regs.s4.texCtrl[ unit ].ni.filterMode = TFM_Point; - imesa->regs.s4.texCtrl[ unit ].ni.mipmapEnable = GL_TRUE; - break; - - case GL_LINEAR_MIPMAP_NEAREST: - imesa->regs.s4.texCtrl[ unit ].ni.filterMode = TFM_Bilin; - imesa->regs.s4.texCtrl[ unit ].ni.mipmapEnable = GL_TRUE; - break; - - case GL_NEAREST_MIPMAP_LINEAR: - case GL_LINEAR_MIPMAP_LINEAR: - imesa->regs.s4.texCtrl[ unit ].ni.filterMode = TFM_Trilin; - imesa->regs.s4.texCtrl[ unit ].ni.mipmapEnable = GL_TRUE; - break; - } -} - - -static void savageUpdateTex0State_s4( struct gl_context *ctx ) -{ - savageContextPtr imesa = SAVAGE_CONTEXT(ctx); - struct gl_texture_object *tObj; - struct gl_texture_image *image; - savageTexObjPtr t; - GLuint format; - - /* disable */ - imesa->regs.s4.texDescr.ni.tex0En = GL_FALSE; - imesa->regs.s4.texBlendCtrl[0].ui = TBC_NoTexMap; - imesa->regs.s4.texCtrl[0].ui = 0x20f040; - if (ctx->Texture.Unit[0]._ReallyEnabled == 0) - return; - - tObj = ctx->Texture.Unit[0]._Current; - if ((ctx->Texture.Unit[0]._ReallyEnabled & ~(TEXTURE_1D_BIT|TEXTURE_2D_BIT)) - || tObj->Image[0][tObj->BaseLevel]->Border > 0) { - /* 3D texturing enabled, or texture border - fallback */ - FALLBACK (ctx, SAVAGE_FALLBACK_TEXTURE, GL_TRUE); - return; - } - - /* Do 2D texture setup */ - - t = tObj->DriverData; - if (!t) { - t = savageAllocTexObj( tObj ); - if (!t) - return; - } - - imesa->CurrentTexObj[0] = &t->base; - t->base.bound |= 1; - - if (t->base.dirty_images[0] || t->dirtySubImages) { - savageSetTexImages(imesa, tObj); - savageUploadTexImages(imesa, t); - } - - driUpdateTextureLRU( &t->base ); - - format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat; - - switch (ctx->Texture.Unit[0].EnvMode) { - case GL_REPLACE: - imesa->regs.s4.texCtrl[0].ni.clrArg1Invert = GL_FALSE; - switch(format) - { - case GL_LUMINANCE: - case GL_RGB: - imesa->regs.s4.texBlendCtrl[0].ui = TBC_Decal; - break; - - case GL_LUMINANCE_ALPHA: - case GL_RGBA: - case GL_INTENSITY: - imesa->regs.s4.texBlendCtrl[0].ui = TBC_Copy; - break; - - case GL_ALPHA: - imesa->regs.s4.texBlendCtrl[0].ui = TBC_CopyAlpha; - break; - } - __HWEnvCombineSingleUnitScale(imesa, 0, 0, - &imesa->regs.s4.texBlendCtrl[0]); - break; - - case GL_DECAL: - imesa->regs.s4.texCtrl[0].ni.clrArg1Invert = GL_FALSE; - switch (format) - { - case GL_RGB: - case GL_LUMINANCE: - imesa->regs.s4.texBlendCtrl[0].ui = TBC_Decal; - break; - - case GL_RGBA: - case GL_INTENSITY: - case GL_LUMINANCE_ALPHA: - imesa->regs.s4.texBlendCtrl[0].ui = TBC_DecalAlpha; - break; - - /* - GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_INTENSITY - are undefined with GL_DECAL - */ - - case GL_ALPHA: - imesa->regs.s4.texBlendCtrl[0].ui = TBC_CopyAlpha; - break; - } - __HWEnvCombineSingleUnitScale(imesa, 0, 0, - &imesa->regs.s4.texBlendCtrl[0]); - break; - - case GL_MODULATE: - imesa->regs.s4.texCtrl[0].ni.clrArg1Invert = GL_FALSE; - imesa->regs.s4.texBlendCtrl[0].ui = TBC_ModulAlpha; - __HWEnvCombineSingleUnitScale(imesa, 0, 0, - &imesa->regs.s4.texBlendCtrl[0]); - break; - - case GL_BLEND: - imesa->regs.s4.texBlendColor.ui = imesa->texEnvColor; - - switch (format) - { - case GL_ALPHA: - imesa->regs.s4.texBlendCtrl[0].ui = TBC_ModulAlpha; - imesa->regs.s4.texCtrl[0].ni.clrArg1Invert = GL_FALSE; - break; - - case GL_LUMINANCE: - case GL_RGB: - imesa->regs.s4.texBlendCtrl[0].ui = TBC_Blend0; - imesa->regs.s4.texDescr.ni.tex1En = GL_TRUE; - imesa->regs.s4.texDescr.ni.texBLoopEn = GL_TRUE; - imesa->regs.s4.texDescr.ni.tex1Width = - imesa->regs.s4.texDescr.ni.tex0Width; - imesa->regs.s4.texDescr.ni.tex1Height = - imesa->regs.s4.texDescr.ni.tex0Height; - imesa->regs.s4.texDescr.ni.tex1Fmt = - imesa->regs.s4.texDescr.ni.tex0Fmt; - - imesa->regs.s4.texAddr[1].ui = imesa->regs.s4.texAddr[0].ui; - imesa->regs.s4.texBlendCtrl[1].ui = TBC_Blend1; - - imesa->regs.s4.texCtrl[0].ni.clrArg1Invert = GL_TRUE; - imesa->bTexEn1 = GL_TRUE; - break; - - case GL_LUMINANCE_ALPHA: - case GL_RGBA: - imesa->regs.s4.texBlendCtrl[0].ui = TBC_BlendAlpha0; - imesa->regs.s4.texDescr.ni.tex1En = GL_TRUE; - imesa->regs.s4.texDescr.ni.texBLoopEn = GL_TRUE; - imesa->regs.s4.texDescr.ni.tex1Width = - imesa->regs.s4.texDescr.ni.tex0Width; - imesa->regs.s4.texDescr.ni.tex1Height = - imesa->regs.s4.texDescr.ni.tex0Height; - imesa->regs.s4.texDescr.ni.tex1Fmt = - imesa->regs.s4.texDescr.ni.tex0Fmt; - - imesa->regs.s4.texAddr[1].ui = imesa->regs.s4.texAddr[0].ui; - imesa->regs.s4.texBlendCtrl[1].ui = TBC_BlendAlpha1; - - imesa->regs.s4.texCtrl[0].ni.clrArg1Invert = GL_TRUE; - imesa->bTexEn1 = GL_TRUE; - break; - - case GL_INTENSITY: - imesa->regs.s4.texBlendCtrl[0].ui = TBC_BlendInt0; - imesa->regs.s4.texDescr.ni.tex1En = GL_TRUE; - imesa->regs.s4.texDescr.ni.texBLoopEn = GL_TRUE; - imesa->regs.s4.texDescr.ni.tex1Width = - imesa->regs.s4.texDescr.ni.tex0Width; - imesa->regs.s4.texDescr.ni.tex1Height = - imesa->regs.s4.texDescr.ni.tex0Height; - imesa->regs.s4.texDescr.ni.tex1Fmt = - imesa->regs.s4.texDescr.ni.tex0Fmt; - - imesa->regs.s4.texAddr[1].ui = imesa->regs.s4.texAddr[0].ui; - imesa->regs.s4.texBlendCtrl[1].ui = TBC_BlendInt1; - - imesa->regs.s4.texCtrl[0].ni.clrArg1Invert = GL_TRUE; - imesa->regs.s4.texCtrl[0].ni.alphaArg1Invert = GL_TRUE; - imesa->bTexEn1 = GL_TRUE; - break; - } - __HWEnvCombineSingleUnitScale(imesa, 0, 0, - &imesa->regs.s4.texBlendCtrl[0]); - break; - - case GL_ADD: - imesa->regs.s4.texCtrl[0].ni.clrArg1Invert = GL_FALSE; - switch (format) - { - case GL_ALPHA: - imesa->regs.s4.texBlendCtrl[0].ui = TBC_ModulAlpha; - break; - - case GL_LUMINANCE: - case GL_RGB: - imesa->regs.s4.texBlendCtrl[0].ui = TBC_Add; - break; - - case GL_LUMINANCE_ALPHA: - case GL_RGBA: - imesa->regs.s4.texBlendCtrl[0].ui = TBC_Add; - break; - - case GL_INTENSITY: - imesa->regs.s4.texBlendCtrl[0].ui = TBC_AddAlpha; - break; - } - __HWEnvCombineSingleUnitScale(imesa, 0, 0, - &imesa->regs.s4.texBlendCtrl[0]); - break; - -#if GL_ARB_texture_env_combine - case GL_COMBINE_ARB: - __HWParseTexEnvCombine(imesa, 0, &imesa->regs.s4.texCtrl[0], - &imesa->regs.s4.texBlendCtrl[0]); - break; -#endif - - default: - fprintf(stderr, "unknown tex env mode"); - exit(1); - break; - } - - savage4_set_wrap_mode( imesa, 0, t->setup.sWrapMode, t->setup.tWrapMode ); - savage4_set_filter_mode( imesa, 0, t->setup.minFilter, t->setup.magFilter ); - - if((ctx->Texture.Unit[0].LodBias !=0.0F) || - (imesa->regs.s4.texCtrl[0].ni.dBias != 0)) - { - int bias = (int)(ctx->Texture.Unit[0].LodBias * 32.0) + - SAVAGE4_LOD_OFFSET; - if (bias < -256) - bias = -256; - else if (bias > 255) - bias = 255; - imesa->regs.s4.texCtrl[0].ni.dBias = bias & 0x1ff; - } - - image = tObj->Image[0][tObj->BaseLevel]; - imesa->regs.s4.texDescr.ni.tex0En = GL_TRUE; - imesa->regs.s4.texDescr.ni.tex0Width = image->WidthLog2; - imesa->regs.s4.texDescr.ni.tex0Height = image->HeightLog2; - imesa->regs.s4.texDescr.ni.tex0Fmt = t->hwFormat; - imesa->regs.s4.texCtrl[0].ni.dMax = t->base.lastLevel - t->base.firstLevel; - - if (imesa->regs.s4.texDescr.ni.tex1En) - imesa->regs.s4.texDescr.ni.texBLoopEn = GL_TRUE; - - imesa->regs.s4.texAddr[0].ui = (uint32_t) t->setup.physAddr | 0x2; - if(t->base.heap->heapId == SAVAGE_AGP_HEAP) - imesa->regs.s4.texAddr[0].ui |= 0x1; - - return; -} -static void savageUpdateTex1State_s4( struct gl_context *ctx ) -{ - savageContextPtr imesa = SAVAGE_CONTEXT(ctx); - struct gl_texture_object *tObj; - struct gl_texture_image *image; - savageTexObjPtr t; - GLuint format; - - /* disable */ - if(imesa->bTexEn1) - { - imesa->bTexEn1 = GL_FALSE; - return; - } - - imesa->regs.s4.texDescr.ni.tex1En = GL_FALSE; - imesa->regs.s4.texBlendCtrl[1].ui = TBC_NoTexMap1; - imesa->regs.s4.texCtrl[1].ui = 0x20f040; - imesa->regs.s4.texDescr.ni.texBLoopEn = GL_FALSE; - if (ctx->Texture.Unit[1]._ReallyEnabled == 0) - return; - - tObj = ctx->Texture.Unit[1]._Current; - - if ((ctx->Texture.Unit[1]._ReallyEnabled & ~(TEXTURE_1D_BIT|TEXTURE_2D_BIT)) - || tObj->Image[0][tObj->BaseLevel]->Border > 0) { - /* 3D texturing enabled, or texture border - fallback */ - FALLBACK (ctx, SAVAGE_FALLBACK_TEXTURE, GL_TRUE); - return; - } - - /* Do 2D texture setup */ - - t = tObj->DriverData; - if (!t) { - t = savageAllocTexObj( tObj ); - if (!t) - return; - } - - imesa->CurrentTexObj[1] = &t->base; - - t->base.bound |= 2; - - if (t->base.dirty_images[0] || t->dirtySubImages) { - savageSetTexImages(imesa, tObj); - savageUploadTexImages(imesa, t); - } - - driUpdateTextureLRU( &t->base ); - - format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat; - - switch (ctx->Texture.Unit[1].EnvMode) { - case GL_REPLACE: - imesa->regs.s4.texCtrl[1].ni.clrArg1Invert = GL_FALSE; - switch (format) - { - case GL_LUMINANCE: - case GL_RGB: - imesa->regs.s4.texBlendCtrl[1].ui = TBC_Decal; - break; - - case GL_LUMINANCE_ALPHA: - case GL_INTENSITY: - case GL_RGBA: - imesa->regs.s4.texBlendCtrl[1].ui = TBC_Copy; - break; - - case GL_ALPHA: - imesa->regs.s4.texBlendCtrl[1].ui = TBC_CopyAlpha1; - break; - } - __HWEnvCombineSingleUnitScale(imesa, 0, 1, &imesa->regs.s4.texBlendCtrl); - break; - case GL_MODULATE: - imesa->regs.s4.texCtrl[1].ni.clrArg1Invert = GL_FALSE; - imesa->regs.s4.texBlendCtrl[1].ui = TBC_ModulAlpha1; - __HWEnvCombineSingleUnitScale(imesa, 0, 1, &imesa->regs.s4.texBlendCtrl); - break; - - case GL_ADD: - imesa->regs.s4.texCtrl[1].ni.clrArg1Invert = GL_FALSE; - switch (format) - { - case GL_ALPHA: - imesa->regs.s4.texBlendCtrl[1].ui = TBC_ModulAlpha1; - break; - - case GL_LUMINANCE: - case GL_RGB: - imesa->regs.s4.texBlendCtrl[1].ui = TBC_Add1; - break; - - case GL_LUMINANCE_ALPHA: - case GL_RGBA: - imesa->regs.s4.texBlendCtrl[1].ui = TBC_Add1; - break; - - case GL_INTENSITY: - imesa->regs.s4.texBlendCtrl[1].ui = TBC_AddAlpha1; - break; - } - __HWEnvCombineSingleUnitScale(imesa, 0, 1, &imesa->regs.s4.texBlendCtrl); - break; - -#if GL_ARB_texture_env_combine - case GL_COMBINE_ARB: - __HWParseTexEnvCombine(imesa, 1, &texCtrl, &imesa->regs.s4.texBlendCtrl); - break; -#endif - - case GL_DECAL: - imesa->regs.s4.texCtrl[1].ni.clrArg1Invert = GL_FALSE; - - switch (format) - { - case GL_LUMINANCE: - case GL_RGB: - imesa->regs.s4.texBlendCtrl[1].ui = TBC_Decal1; - break; - case GL_LUMINANCE_ALPHA: - case GL_INTENSITY: - case GL_RGBA: - imesa->regs.s4.texBlendCtrl[1].ui = TBC_DecalAlpha1; - break; - - /* - // GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_INTENSITY - // are undefined with GL_DECAL - */ - case GL_ALPHA: - imesa->regs.s4.texBlendCtrl[1].ui = TBC_CopyAlpha1; - break; - } - __HWEnvCombineSingleUnitScale(imesa, 0, 1, &imesa->regs.s4.texBlendCtrl); - break; - - case GL_BLEND: - if (format == GL_LUMINANCE) - { - /* - // This is a hack for GLQuake, invert. - */ - imesa->regs.s4.texCtrl[1].ni.clrArg1Invert = GL_TRUE; - imesa->regs.s4.texBlendCtrl[1].ui = 0; - } - __HWEnvCombineSingleUnitScale(imesa, 0, 1, &imesa->regs.s4.texBlendCtrl); - break; - - default: - fprintf(stderr, "unknown tex 1 env mode\n"); - exit(1); - break; - } - - savage4_set_wrap_mode( imesa, 1, t->setup.sWrapMode, t->setup.tWrapMode ); - savage4_set_filter_mode( imesa, 1, t->setup.minFilter, t->setup.magFilter ); - - if((ctx->Texture.Unit[1].LodBias !=0.0F) || - (imesa->regs.s4.texCtrl[1].ni.dBias != 0)) - { - int bias = (int)(ctx->Texture.Unit[1].LodBias * 32.0) + - SAVAGE4_LOD_OFFSET; - if (bias < -256) - bias = -256; - else if (bias > 255) - bias = 255; - imesa->regs.s4.texCtrl[1].ni.dBias = bias & 0x1ff; - } - - image = tObj->Image[0][tObj->BaseLevel]; - imesa->regs.s4.texDescr.ni.tex1En = GL_TRUE; - imesa->regs.s4.texDescr.ni.tex1Width = image->WidthLog2; - imesa->regs.s4.texDescr.ni.tex1Height = image->HeightLog2; - imesa->regs.s4.texDescr.ni.tex1Fmt = t->hwFormat; - imesa->regs.s4.texCtrl[1].ni.dMax = t->base.lastLevel - t->base.firstLevel; - imesa->regs.s4.texDescr.ni.texBLoopEn = GL_TRUE; - - imesa->regs.s4.texAddr[1].ui = (uint32_t) t->setup.physAddr | 2; - if(t->base.heap->heapId == SAVAGE_AGP_HEAP) - imesa->regs.s4.texAddr[1].ui |= 0x1; -} -static void savageUpdateTexState_s3d( struct gl_context *ctx ) -{ - savageContextPtr imesa = SAVAGE_CONTEXT(ctx); - struct gl_texture_object *tObj; - struct gl_texture_image *image; - savageTexObjPtr t; - GLuint format; - - /* disable */ - imesa->regs.s3d.texCtrl.ui = 0; - imesa->regs.s3d.texCtrl.ni.texEn = GL_FALSE; - imesa->regs.s3d.texCtrl.ni.dBias = 0x08; - imesa->regs.s3d.texCtrl.ni.texXprEn = GL_TRUE; - if (ctx->Texture.Unit[0]._ReallyEnabled == 0) - return; - - tObj = ctx->Texture.Unit[0]._Current; - if ((ctx->Texture.Unit[0]._ReallyEnabled & ~(TEXTURE_1D_BIT|TEXTURE_2D_BIT)) - || tObj->Image[0][tObj->BaseLevel]->Border > 0) { - /* 3D texturing enabled, or texture border - fallback */ - FALLBACK (ctx, SAVAGE_FALLBACK_TEXTURE, GL_TRUE); - return; - } - - /* Do 2D texture setup */ - t = tObj->DriverData; - if (!t) { - t = savageAllocTexObj( tObj ); - if (!t) - return; - } - - imesa->CurrentTexObj[0] = &t->base; - t->base.bound |= 1; - - if (t->base.dirty_images[0] || t->dirtySubImages) { - savageSetTexImages(imesa, tObj); - savageUploadTexImages(imesa, t); - } - - driUpdateTextureLRU( &t->base ); - - format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat; - - /* FIXME: copied from utah-glx, probably needs some tuning */ - switch (ctx->Texture.Unit[0].EnvMode) { - case GL_DECAL: - imesa->regs.s3d.drawCtrl.ni.texBlendCtrl = SAVAGETBC_DECALALPHA_S3D; - break; - case GL_REPLACE: - switch (format) { - case GL_ALPHA: /* FIXME */ - imesa->regs.s3d.drawCtrl.ni.texBlendCtrl = 1; - break; - case GL_LUMINANCE_ALPHA: - case GL_RGBA: - imesa->regs.s3d.drawCtrl.ni.texBlendCtrl = 4; - break; - case GL_RGB: - case GL_LUMINANCE: - imesa->regs.s3d.drawCtrl.ni.texBlendCtrl = SAVAGETBC_DECAL_S3D; - break; - case GL_INTENSITY: - imesa->regs.s3d.drawCtrl.ni.texBlendCtrl = SAVAGETBC_COPY_S3D; - } - break; - case GL_BLEND: /* hardware can't do GL_BLEND */ - FALLBACK (ctx, SAVAGE_FALLBACK_TEXTURE, GL_TRUE); - return; - case GL_MODULATE: - imesa->regs.s3d.drawCtrl.ni.texBlendCtrl = SAVAGETBC_MODULATEALPHA_S3D; - break; - default: - fprintf(stderr, "unknown tex env mode\n"); - /*exit(1);*/ - break; - } - - /* The Savage3D can't handle different wrapping modes in s and t. - * If they are not the same, fall back to software. */ - if (t->setup.sWrapMode != t->setup.tWrapMode) { - FALLBACK (ctx, SAVAGE_FALLBACK_TEXTURE, GL_TRUE); - return; - } - imesa->regs.s3d.texCtrl.ni.uWrapEn = 0; - imesa->regs.s3d.texCtrl.ni.vWrapEn = 0; - imesa->regs.s3d.texCtrl.ni.wrapMode = - (t->setup.sWrapMode == GL_REPEAT) ? TAM_Wrap : TAM_Clamp; - - switch (t->setup.minFilter) { - case GL_NEAREST: - imesa->regs.s3d.texCtrl.ni.filterMode = TFM_Point; - imesa->regs.s3d.texCtrl.ni.mipmapDisable = GL_TRUE; - break; - - case GL_LINEAR: - imesa->regs.s3d.texCtrl.ni.filterMode = TFM_Bilin; - imesa->regs.s3d.texCtrl.ni.mipmapDisable = GL_TRUE; - break; - - case GL_NEAREST_MIPMAP_NEAREST: - imesa->regs.s3d.texCtrl.ni.filterMode = TFM_Point; - imesa->regs.s3d.texCtrl.ni.mipmapDisable = GL_FALSE; - break; - - case GL_LINEAR_MIPMAP_NEAREST: - imesa->regs.s3d.texCtrl.ni.filterMode = TFM_Bilin; - imesa->regs.s3d.texCtrl.ni.mipmapDisable = GL_FALSE; - break; - - case GL_NEAREST_MIPMAP_LINEAR: - case GL_LINEAR_MIPMAP_LINEAR: - imesa->regs.s3d.texCtrl.ni.filterMode = TFM_Trilin; - imesa->regs.s3d.texCtrl.ni.mipmapDisable = GL_FALSE; - break; - } - - /* There is no way to specify a maximum mipmap level. We may have to - disable mipmapping completely. */ - /* - if (t->max_level < t->image[0].image->WidthLog2 || - t->max_level < t->image[0].image->HeightLog2) { - texCtrl.ni.mipmapEnable = GL_TRUE; - if (texCtrl.ni.filterMode == TFM_Trilin) - texCtrl.ni.filterMode = TFM_Bilin; - texCtrl.ni.filterMode = TFM_Point; - } - */ - - if((ctx->Texture.Unit[0].LodBias !=0.0F) || - (imesa->regs.s3d.texCtrl.ni.dBias != 0)) - { - int bias = (int)(ctx->Texture.Unit[0].LodBias * 16.0); - if (bias < -256) - bias = -256; - else if (bias > 255) - bias = 255; - imesa->regs.s3d.texCtrl.ni.dBias = bias & 0x1ff; - } - - image = tObj->Image[0][tObj->BaseLevel]; - imesa->regs.s3d.texCtrl.ni.texEn = GL_TRUE; - imesa->regs.s3d.texDescr.ni.texWidth = image->WidthLog2; - imesa->regs.s3d.texDescr.ni.texHeight = image->HeightLog2; - assert (t->hwFormat <= 7); - imesa->regs.s3d.texDescr.ni.texFmt = t->hwFormat; - - imesa->regs.s3d.texAddr.ui = (uint32_t) t->setup.physAddr | 2; - if(t->base.heap->heapId == SAVAGE_AGP_HEAP) - imesa->regs.s3d.texAddr.ui |= 0x1; -} - - -static void savageTimestampTextures( savageContextPtr imesa ) -{ - /* Timestamp current texture objects for texture heap aging. - * Only useful with long-lived 32-bit event tags available - * with Savage DRM 2.3.x or later. */ - if ((imesa->CurrentTexObj[0] || imesa->CurrentTexObj[1]) && - imesa->savageScreen->driScrnPriv->drm_version.minor >= 3) { - unsigned int e; - FLUSH_BATCH(imesa); - e = savageEmitEvent(imesa, SAVAGE_WAIT_3D); - if (imesa->CurrentTexObj[0]) - imesa->CurrentTexObj[0]->timestamp = e; - if (imesa->CurrentTexObj[1]) - imesa->CurrentTexObj[1]->timestamp = e; - } -} - - -static void savageUpdateTextureState_s4( struct gl_context *ctx ) -{ - savageContextPtr imesa = SAVAGE_CONTEXT(ctx); - - /* When a texture is about to change or be disabled, timestamp the - * old texture(s). We'll have to wait for this time stamp before - * uploading anything to the same texture heap. - */ - if ((imesa->CurrentTexObj[0] && ctx->Texture.Unit[0]._ReallyEnabled && - ctx->Texture.Unit[0]._Current->DriverData != imesa->CurrentTexObj[0]) || - (imesa->CurrentTexObj[1] && ctx->Texture.Unit[1]._ReallyEnabled && - ctx->Texture.Unit[1]._Current->DriverData != imesa->CurrentTexObj[1]) || - (imesa->CurrentTexObj[0] && !ctx->Texture.Unit[0]._ReallyEnabled) || - (imesa->CurrentTexObj[1] && !ctx->Texture.Unit[1]._ReallyEnabled)) - savageTimestampTextures(imesa); - - if (imesa->CurrentTexObj[0]) imesa->CurrentTexObj[0]->bound &= ~1; - if (imesa->CurrentTexObj[1]) imesa->CurrentTexObj[1]->bound &= ~2; - imesa->CurrentTexObj[0] = 0; - imesa->CurrentTexObj[1] = 0; - savageUpdateTex0State_s4( ctx ); - savageUpdateTex1State_s4( ctx ); - imesa->dirty |= (SAVAGE_UPLOAD_TEX0 | - SAVAGE_UPLOAD_TEX1); -} -static void savageUpdateTextureState_s3d( struct gl_context *ctx ) -{ - savageContextPtr imesa = SAVAGE_CONTEXT(ctx); - - /* When a texture is about to change or be disabled, timestamp the - * old texture(s). We'll have to wait for this time stamp before - * uploading anything to the same texture heap. - */ - if ((imesa->CurrentTexObj[0] && ctx->Texture.Unit[0]._ReallyEnabled && - ctx->Texture.Unit[0]._Current->DriverData != imesa->CurrentTexObj[0]) || - (imesa->CurrentTexObj[0] && !ctx->Texture.Unit[0]._ReallyEnabled)) - savageTimestampTextures(imesa); - - if (imesa->CurrentTexObj[0]) imesa->CurrentTexObj[0]->bound &= ~1; - imesa->CurrentTexObj[0] = 0; - savageUpdateTexState_s3d( ctx ); - imesa->dirty |= (SAVAGE_UPLOAD_TEX0); -} -void savageUpdateTextureState( struct gl_context *ctx) -{ - savageContextPtr imesa = SAVAGE_CONTEXT( ctx ); - FALLBACK (ctx, SAVAGE_FALLBACK_TEXTURE, GL_FALSE); - FALLBACK(ctx, SAVAGE_FALLBACK_PROJ_TEXTURE, GL_FALSE); - if (imesa->savageScreen->chipset >= S3_SAVAGE4) - savageUpdateTextureState_s4 (ctx); - else - savageUpdateTextureState_s3d (ctx); -} - - - -/***************************************** - * DRIVER functions - *****************************************/ - -static void savageTexEnv( struct gl_context *ctx, GLenum target, - GLenum pname, const GLfloat *param ) -{ - savageContextPtr imesa = SAVAGE_CONTEXT( ctx ); - - if (pname == GL_TEXTURE_ENV_MODE) { - - imesa->new_state |= SAVAGE_NEW_TEXTURE; - - } else if (pname == GL_TEXTURE_ENV_COLOR) { - - struct gl_texture_unit *texUnit = - &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - const GLfloat *fc = texUnit->EnvColor; - GLuint r, g, b, a; - CLAMPED_FLOAT_TO_UBYTE(r, fc[0]); - CLAMPED_FLOAT_TO_UBYTE(g, fc[1]); - CLAMPED_FLOAT_TO_UBYTE(b, fc[2]); - CLAMPED_FLOAT_TO_UBYTE(a, fc[3]); - - imesa->texEnvColor = ((a << 24) | (r << 16) | - (g << 8) | (b << 0)); - - - } -} - -/* Update the heap's time stamp, so the new image is not uploaded - * while the old one is still in use. If the texture that is going to - * be changed is currently bound, we need to timestamp the texture - * first. */ -static void savageTexImageChanged (savageTexObjPtr t) { - if (t->base.heap) { - if (t->base.bound) - savageTimestampTextures( - (savageContextPtr)t->base.heap->driverContext); - if (t->base.timestamp > t->base.heap->timestamp) - t->base.heap->timestamp = t->base.timestamp; - } -} - -static void savageTexImage1D( struct gl_context *ctx, GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint border, - GLenum format, GLenum type, const GLvoid *pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage ) -{ - savageTexObjPtr t = (savageTexObjPtr) texObj->DriverData; - if (t) { - savageTexImageChanged (t); - } else { - t = savageAllocTexObj(texObj); - if (!t) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); - return; - } - } - _mesa_store_teximage1d( ctx, target, level, internalFormat, - width, border, format, type, - pixels, packing, texObj, texImage ); - t->base.dirty_images[0] |= (1 << level); - SAVAGE_CONTEXT(ctx)->new_state |= SAVAGE_NEW_TEXTURE; -} - -static void savageTexSubImage1D( struct gl_context *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 ) -{ - savageTexObjPtr t = (savageTexObjPtr) texObj->DriverData; - assert( t ); /* this _should_ be true */ - if (t) { - savageTexImageChanged (t); - savageMarkDirtyTiles(t, level, texImage->Width2, 1, - xoffset, 0, width, 1); - } else { - t = savageAllocTexObj(texObj); - if (!t) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D"); - return; - } - t->base.dirty_images[0] |= (1 << level); - } - _mesa_store_texsubimage1d(ctx, target, level, xoffset, width, - format, type, pixels, packing, texObj, - texImage); - t->dirtySubImages |= (1 << level); - SAVAGE_CONTEXT(ctx)->new_state |= SAVAGE_NEW_TEXTURE; -} - -static void savageTexImage2D( struct gl_context *ctx, GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint height, GLint border, - GLenum format, GLenum type, const GLvoid *pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage ) -{ - savageTexObjPtr t = (savageTexObjPtr) texObj->DriverData; - if (t) { - savageTexImageChanged (t); - } else { - t = savageAllocTexObj(texObj); - if (!t) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); - return; - } - } - _mesa_store_teximage2d( ctx, target, level, internalFormat, - width, height, border, format, type, - pixels, packing, texObj, texImage ); - t->base.dirty_images[0] |= (1 << level); - SAVAGE_CONTEXT(ctx)->new_state |= SAVAGE_NEW_TEXTURE; -} - -static void savageTexSubImage2D( struct gl_context *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 ) -{ - savageTexObjPtr t = (savageTexObjPtr) texObj->DriverData; - assert( t ); /* this _should_ be true */ - if (t) { - savageTexImageChanged (t); - savageMarkDirtyTiles(t, level, texImage->Width2, texImage->Height2, - xoffset, yoffset, width, height); - } else { - t = savageAllocTexObj(texObj); - if (!t) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D"); - return; - } - t->base.dirty_images[0] |= (1 << level); - } - _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width, - height, format, type, pixels, packing, texObj, - texImage); - t->dirtySubImages |= (1 << level); - SAVAGE_CONTEXT(ctx)->new_state |= SAVAGE_NEW_TEXTURE; -} - -static void -savageCompressedTexImage2D( struct gl_context *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 ) -{ - savageTexObjPtr t = (savageTexObjPtr) texObj->DriverData; - if (t) { - savageTexImageChanged (t); - } else { - t = savageAllocTexObj(texObj); - if (!t) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D"); - return; - } - } - _mesa_store_compressed_teximage2d( ctx, target, level, internalFormat, - width, height, border, imageSize, - data, texObj, texImage ); - t->base.dirty_images[0] |= (1 << level); - SAVAGE_CONTEXT(ctx)->new_state |= SAVAGE_NEW_TEXTURE; -} - -static void -savageCompressedTexSubImage2D( struct gl_context *ctx, - GLenum target, - GLint level, - GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, - GLenum format, GLsizei imageSize, - const GLvoid *data, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage ) -{ - savageTexObjPtr t = (savageTexObjPtr) texObj->DriverData; - assert( t ); /* this _should_ be true */ - if (t) { - savageTexImageChanged (t); - savageMarkDirtyTiles(t, level, texImage->Width2, texImage->Height2, - xoffset, yoffset, width, height); - } else { - t = savageAllocTexObj(texObj); - if (!t) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D"); - return; - } - t->base.dirty_images[0] |= (1 << level); - } - _mesa_store_compressed_texsubimage2d(ctx, target, level, xoffset, yoffset, - width, height, format, imageSize, - data, texObj, texImage); - t->dirtySubImages |= (1 << level); - SAVAGE_CONTEXT(ctx)->new_state |= SAVAGE_NEW_TEXTURE; -} - -static void savageTexParameter( struct gl_context *ctx, GLenum target, - struct gl_texture_object *tObj, - GLenum pname, const GLfloat *params ) -{ - savageTexObjPtr t = (savageTexObjPtr) tObj->DriverData; - savageContextPtr imesa = SAVAGE_CONTEXT( ctx ); - - if (!t || (target != GL_TEXTURE_1D && target != GL_TEXTURE_2D)) - return; - - switch (pname) { - case GL_TEXTURE_MIN_FILTER: - case GL_TEXTURE_MAG_FILTER: - savageSetTexFilter(t,tObj->Sampler.MinFilter,tObj->Sampler.MagFilter); - break; - - case GL_TEXTURE_WRAP_S: - case GL_TEXTURE_WRAP_T: - savageSetTexWrapping(t,tObj->Sampler.WrapS,tObj->Sampler.WrapT); - break; - - case GL_TEXTURE_BORDER_COLOR: - savageSetTexBorderColor(t,tObj->Sampler.BorderColor.f); - break; - - default: - return; - } - - imesa->new_state |= SAVAGE_NEW_TEXTURE; -} - -static void savageBindTexture( struct gl_context *ctx, GLenum target, - struct gl_texture_object *tObj ) -{ - savageContextPtr imesa = SAVAGE_CONTEXT( ctx ); - - assert( (target != GL_TEXTURE_1D && target != GL_TEXTURE_2D) || - (tObj->DriverData != NULL) ); - - imesa->new_state |= SAVAGE_NEW_TEXTURE; -} - -static void savageDeleteTexture( struct gl_context *ctx, struct gl_texture_object *tObj ) -{ - driTextureObject *t = (driTextureObject *)tObj->DriverData; - savageContextPtr imesa = SAVAGE_CONTEXT( ctx ); - - if (t) { - if (t->bound) - savageTimestampTextures(imesa); - - driDestroyTextureObject(t); - } - /* Free mipmap images and the texture object itself */ - _mesa_delete_texture_object(ctx, tObj); -} - - -static struct gl_texture_object * -savageNewTextureObject( struct gl_context *ctx, GLuint name, GLenum target ) -{ - struct gl_texture_object *obj; - obj = _mesa_new_texture_object(ctx, name, target); - savageAllocTexObj( obj ); - - return obj; -} - -void savageDDInitTextureFuncs( struct dd_function_table *functions ) -{ - functions->TexEnv = savageTexEnv; - functions->ChooseTextureFormat = savageChooseTextureFormat; - functions->TexImage1D = savageTexImage1D; - functions->TexSubImage1D = savageTexSubImage1D; - functions->TexImage2D = savageTexImage2D; - functions->TexSubImage2D = savageTexSubImage2D; - functions->CompressedTexImage2D = savageCompressedTexImage2D; - functions->CompressedTexSubImage2D = savageCompressedTexSubImage2D; - functions->BindTexture = savageBindTexture; - functions->NewTextureObject = savageNewTextureObject; - functions->DeleteTexture = savageDeleteTexture; - functions->IsTextureResident = driIsTextureResident; - functions->TexParameter = savageTexParameter; - - /* Texel fetching with our custom texture formats works just like - * the standard argb formats. */ -#if 0 - _savage_texformat_a1114444.FetchTexel1D = _mesa_texformat_argb4444.FetchTexel1D; - _savage_texformat_a1114444.FetchTexel2D = _mesa_texformat_argb4444.FetchTexel2D; - _savage_texformat_a1114444.FetchTexel3D = _mesa_texformat_argb4444.FetchTexel3D; - _savage_texformat_a1114444.FetchTexel1Df= _mesa_texformat_argb4444.FetchTexel1Df; - _savage_texformat_a1114444.FetchTexel2Df= _mesa_texformat_argb4444.FetchTexel2Df; - _savage_texformat_a1114444.FetchTexel3Df= _mesa_texformat_argb4444.FetchTexel3Df; - - _savage_texformat_a1118888.FetchTexel1D = _mesa_texformat_argb8888.FetchTexel1D; - _savage_texformat_a1118888.FetchTexel2D = _mesa_texformat_argb8888.FetchTexel2D; - _savage_texformat_a1118888.FetchTexel3D = _mesa_texformat_argb8888.FetchTexel3D; - _savage_texformat_a1118888.FetchTexel1Df= _mesa_texformat_argb8888.FetchTexel1Df; - _savage_texformat_a1118888.FetchTexel2Df= _mesa_texformat_argb8888.FetchTexel2Df; - _savage_texformat_a1118888.FetchTexel3Df= _mesa_texformat_argb8888.FetchTexel3Df; -#endif -} |