summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/savage/savagetex.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/savage/savagetex.c')
-rw-r--r--src/mesa/drivers/dri/savage/savagetex.c2123
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
-}