summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri
diff options
context:
space:
mode:
authorNian Wu <nian.wu@intel.com>2007-03-26 17:00:29 +0800
committerNian Wu <nian.wu@intel.com>2007-03-26 17:00:29 +0800
commitee9bc897f8ea361539c5f422fdecc2326271e673 (patch)
tree42396ed93352516dc1da6cb23c5b82679fb5ce47 /src/mesa/drivers/dri
parent1b354bb5e4c4524533a8f2c3293df73a403e011a (diff)
parent42aaa548a1020be5d40b3dce9448d8004b1ef947 (diff)
Merge git://proxy01.pd.intel.com:9419/git/mesa/mesa into crestline
Diffstat (limited to 'src/mesa/drivers/dri')
-rw-r--r--src/mesa/drivers/dri/i965/brw_urb.c2
-rw-r--r--src/mesa/drivers/dri/r300/r300_fragprog.c9
-rw-r--r--src/mesa/drivers/dri/r300/r300_texmem.c361
-rw-r--r--src/mesa/drivers/dri/r300/r300_texstate.c170
4 files changed, 268 insertions, 274 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_urb.c b/src/mesa/drivers/dri/i965/brw_urb.c
index 79ff2b2d4d..64f5904ac6 100644
--- a/src/mesa/drivers/dri/i965/brw_urb.c
+++ b/src/mesa/drivers/dri/i965/brw_urb.c
@@ -131,7 +131,7 @@ static void recalculate_urb_fence( struct brw_context *brw )
brw->urb.constrained = 1;
- if (check_urb_layout(brw)) {
+ if (!check_urb_layout(brw)) {
/* This is impossible, given the maximal sizes of urb
* entries and the values for minimum nr of entries
* provided above.
diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.c b/src/mesa/drivers/dri/r300/r300_fragprog.c
index 68a75ec7f0..e01f56d99d 100644
--- a/src/mesa/drivers/dri/r300/r300_fragprog.c
+++ b/src/mesa/drivers/dri/r300/r300_fragprog.c
@@ -934,6 +934,9 @@ static void emit_tex(struct r300_fragment_program *rp,
int hwsrc, hwdest;
GLuint tempreg = 0;
+ uin = cs->used_in_node;
+ din = cs->dest_in_node;
+
/* Resolve source/dest to hardware registers */
if (opcode != R300_FPITX_OP_KIL) {
if (fpi->TexSrcTarget == TEXTURE_RECT_INDEX) {
@@ -958,6 +961,10 @@ static void emit_tex(struct r300_fragment_program *rp,
emit_arith(rp, PFS_OP_MAD, tempreg, WRITEMASK_XYZW,
coord, factorreg, pfs_zero, 0);
+ /* Ensure correct node indirection */
+ uin = cs->used_in_node;
+ din = cs->dest_in_node;
+
hwsrc = t_hw_src(rp, tempreg, GL_TRUE);
} else {
hwsrc = t_hw_src(rp, coord, GL_TRUE);
@@ -986,8 +993,6 @@ static void emit_tex(struct r300_fragment_program *rp,
hwsrc = t_hw_src(rp, coord, GL_TRUE);
}
- din = cs->dest_in_node;
- uin = cs->used_in_node;
/* Indirection if source has been written in this node, or if the
* dest has been read/written in this node
diff --git a/src/mesa/drivers/dri/r300/r300_texmem.c b/src/mesa/drivers/dri/r300/r300_texmem.c
index f531b54d11..c527677cd0 100644
--- a/src/mesa/drivers/dri/r300/r300_texmem.c
+++ b/src/mesa/drivers/dri/r300/r300_texmem.c
@@ -303,195 +303,190 @@ static void r300UploadRectSubImage(r300ContextPtr rmesa,
* Upload the texture image associated with texture \a t at the specified
* level at the address relative to \a start.
*/
-static void uploadSubImage( r300ContextPtr rmesa, r300TexObjPtr t,
+static void uploadSubImage( r300ContextPtr rmesa, r300TexObjPtr t,
GLint hwlevel,
GLint x, GLint y, GLint width, GLint height,
GLuint face )
{
- struct gl_texture_image *texImage = NULL;
- GLuint offset;
- GLint imageWidth, imageHeight;
- GLint ret;
- drm_radeon_texture_t tex;
- drm_radeon_tex_image_t tmp;
- const int level = hwlevel + t->base.firstLevel;
-
- if ( RADEON_DEBUG & DEBUG_TEXTURE ) {
- fprintf( stderr, "%s( %p, %p ) level/width/height/face = %d/%d/%d/%u\n",
- __FUNCTION__, (void *)t, (void *)t->base.tObj,
- level, width, height, face );
- }
-
- ASSERT(face < 6);
-
- /* Ensure we have a valid texture to upload */
- if ( ( hwlevel < 0 ) || ( hwlevel >= RADEON_MAX_TEXTURE_LEVELS ) ) {
- _mesa_problem(NULL, "bad texture level in %s", __FUNCTION__);
- return;
- }
-
- texImage = t->base.tObj->Image[face][level];
-
- if ( !texImage ) {
- if ( RADEON_DEBUG & DEBUG_TEXTURE )
- fprintf( stderr, "%s: texImage %d is NULL!\n", __FUNCTION__, level );
- return;
- }
- if ( !texImage->Data ) {
- if ( RADEON_DEBUG & DEBUG_TEXTURE )
- fprintf( stderr, "%s: image data is NULL!\n", __FUNCTION__ );
- return;
- }
-
-
- if (t->base.tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
- assert(level == 0);
- assert(hwlevel == 0);
- if ( RADEON_DEBUG & DEBUG_TEXTURE )
- fprintf( stderr, "%s: image data is rectangular\n", __FUNCTION__);
- r300UploadRectSubImage( rmesa, t, texImage, x, y, width, height );
- return;
- }
- else if (texImage->IsClientData) {
- if ( RADEON_DEBUG & DEBUG_TEXTURE )
- fprintf( stderr, "%s: image data is in GART client storage\n",
- __FUNCTION__);
- r300UploadGARTClientSubImage( rmesa, t, texImage, hwlevel,
- x, y, width, height );
- return;
- }
- else if ( RADEON_DEBUG & DEBUG_TEXTURE )
- fprintf( stderr, "%s: image data is in normal memory\n",
- __FUNCTION__);
-
-
- imageWidth = texImage->Width;
- imageHeight = texImage->Height;
-
- offset = t->bufAddr + t->base.totalSize / 6 * face;
-
- if ( RADEON_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) {
- GLint imageX = 0;
- GLint imageY = 0;
- GLint blitX = t->image[face][hwlevel].x;
- GLint blitY = t->image[face][hwlevel].y;
- GLint blitWidth = t->image[face][hwlevel].width;
- GLint blitHeight = t->image[face][hwlevel].height;
- fprintf( stderr, " upload image: %d,%d at %d,%d\n",
- imageWidth, imageHeight, imageX, imageY );
- fprintf( stderr, " upload blit: %d,%d at %d,%d\n",
- blitWidth, blitHeight, blitX, blitY );
- fprintf( stderr, " blit ofs: 0x%07x level: %d/%d\n",
- (GLuint)offset, hwlevel, level );
- }
-
- t->image[face][hwlevel].data = texImage->Data;
-
- /* Init the DRM_RADEON_TEXTURE command / drm_radeon_texture_t struct.
- * NOTE: we're always use a 1KB-wide blit and I8 texture format.
- * We used to use 1, 2 and 4-byte texels and used to use the texture
- * width to dictate the blit width - but that won't work for compressed
- * textures. (Brian)
- * NOTE: can't do that with texture tiling. (sroland)
- */
- tex.offset = offset;
- tex.image = &tmp;
- /* copy (x,y,width,height,data) */
- memcpy( &tmp, &t->image[face][hwlevel], sizeof(tmp) );
-
- if (texImage->TexFormat->TexelBytes > 4) {
- const int log2TexelBytes = (3 + (texImage->TexFormat->TexelBytes >> 4));
- tex.format = RADEON_TXFORMAT_I8; /* any 1-byte texel format */
- tex.pitch = MAX2((texImage->Width * texImage->TexFormat->TexelBytes) / 64, 1);
- tex.height = imageHeight;
- tex.width = imageWidth << log2TexelBytes;
- tex.offset += (tmp.x << log2TexelBytes) & ~1023;
- tmp.x = tmp.x % (1024 >> log2TexelBytes);
- tmp.width = tmp.width << log2TexelBytes;
- }
- else if (texImage->TexFormat->TexelBytes) {
- /* use multi-byte upload scheme */
- tex.height = imageHeight;
- tex.width = imageWidth;
- switch(texImage->TexFormat->TexelBytes) {
- case 1:
- tex.format = RADEON_TXFORMAT_I8;
- break;
- case 2:
- tex.format = RADEON_TXFORMAT_AI88;
- break;
- case 4:
- tex.format = RADEON_TXFORMAT_ARGB8888;
- break;
- }
- tex.pitch = MAX2((texImage->Width * texImage->TexFormat->TexelBytes) / 64, 1);
- tex.offset += tmp.x & ~1023;
- tmp.x = tmp.x % 1024;
-#if 1
- if (t->tile_bits & R300_TXO_MICRO_TILE) {
- /* need something like "tiled coordinates" ? */
- tmp.y = tmp.x / (tex.pitch * 128) * 2;
- tmp.x = tmp.x % (tex.pitch * 128) / 2 / texImage->TexFormat->TexelBytes;
- tex.pitch |= RADEON_DST_TILE_MICRO >> 22;
- }
- else
-#endif
- {
- tmp.x = tmp.x >> (texImage->TexFormat->TexelBytes >> 1);
- }
+ struct gl_texture_image *texImage = NULL;
+ GLuint offset;
+ GLint imageWidth, imageHeight;
+ GLint ret;
+ drm_radeon_texture_t tex;
+ drm_radeon_tex_image_t tmp;
+ const int level = hwlevel + t->base.firstLevel;
+
+ if ( RADEON_DEBUG & DEBUG_TEXTURE ) {
+ fprintf( stderr, "%s( %p, %p ) level/width/height/face = %d/%d/%d/%u\n",
+ __FUNCTION__, (void *)t, (void *)t->base.tObj,
+ level, width, height, face );
+ }
+
+ ASSERT(face < 6);
+
+ /* Ensure we have a valid texture to upload */
+ if ( ( hwlevel < 0 ) || ( hwlevel >= RADEON_MAX_TEXTURE_LEVELS ) ) {
+ _mesa_problem(NULL, "bad texture level in %s", __FUNCTION__);
+ return;
+ }
+
+ texImage = t->base.tObj->Image[face][level];
+
+ if ( !texImage ) {
+ if ( RADEON_DEBUG & DEBUG_TEXTURE )
+ fprintf( stderr, "%s: texImage %d is NULL!\n", __FUNCTION__, level );
+ return;
+ }
+ if ( !texImage->Data ) {
+ if ( RADEON_DEBUG & DEBUG_TEXTURE )
+ fprintf( stderr, "%s: image data is NULL!\n", __FUNCTION__ );
+ return;
+ }
+
+
+ if (t->base.tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
+ assert(level == 0);
+ assert(hwlevel == 0);
+ if ( RADEON_DEBUG & DEBUG_TEXTURE )
+ fprintf( stderr, "%s: image data is rectangular\n", __FUNCTION__);
+ r300UploadRectSubImage( rmesa, t, texImage, x, y, width, height );
+ return;
+ } else if (texImage->IsClientData) {
+ if ( RADEON_DEBUG & DEBUG_TEXTURE )
+ fprintf( stderr, "%s: image data is in GART client storage\n",
+ __FUNCTION__);
+ r300UploadGARTClientSubImage( rmesa, t, texImage, hwlevel,
+ x, y, width, height );
+ return;
+ } else if ( RADEON_DEBUG & DEBUG_TEXTURE )
+ fprintf( stderr, "%s: image data is in normal memory\n",
+ __FUNCTION__);
+
+
+ imageWidth = texImage->Width;
+ imageHeight = texImage->Height;
+
+ offset = t->bufAddr + t->base.totalSize / 6 * face;
+
+ if ( RADEON_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) {
+ GLint imageX = 0;
+ GLint imageY = 0;
+ GLint blitX = t->image[face][hwlevel].x;
+ GLint blitY = t->image[face][hwlevel].y;
+ GLint blitWidth = t->image[face][hwlevel].width;
+ GLint blitHeight = t->image[face][hwlevel].height;
+ fprintf( stderr, " upload image: %d,%d at %d,%d\n",
+ imageWidth, imageHeight, imageX, imageY );
+ fprintf( stderr, " upload blit: %d,%d at %d,%d\n",
+ blitWidth, blitHeight, blitX, blitY );
+ fprintf( stderr, " blit ofs: 0x%07x level: %d/%d\n",
+ (GLuint)offset, hwlevel, level );
+ }
+
+ t->image[face][hwlevel].data = texImage->Data;
+
+ /* Init the DRM_RADEON_TEXTURE command / drm_radeon_texture_t struct.
+ * NOTE: we're always use a 1KB-wide blit and I8 texture format.
+ * We used to use 1, 2 and 4-byte texels and used to use the texture
+ * width to dictate the blit width - but that won't work for compressed
+ * textures. (Brian)
+ * NOTE: can't do that with texture tiling. (sroland)
+ */
+ tex.offset = offset;
+ tex.image = &tmp;
+ /* copy (x,y,width,height,data) */
+ memcpy( &tmp, &t->image[face][hwlevel], sizeof(tmp) );
+
+ if (texImage->TexFormat->TexelBytes > 4) {
+ const int log2TexelBytes = (3 + (texImage->TexFormat->TexelBytes >> 4));
+ tex.format = RADEON_TXFORMAT_I8; /* any 1-byte texel format */
+ tex.pitch = MAX2((texImage->Width * texImage->TexFormat->TexelBytes) / 64, 1);
+ tex.height = imageHeight;
+ tex.width = imageWidth << log2TexelBytes;
+ tex.offset += (tmp.x << log2TexelBytes) & ~1023;
+ tmp.x = tmp.x % (1024 >> log2TexelBytes);
+ tmp.width = tmp.width << log2TexelBytes;
+ } else if (texImage->TexFormat->TexelBytes) {
+ /* use multi-byte upload scheme */
+ tex.height = imageHeight;
+ tex.width = imageWidth;
+ switch(texImage->TexFormat->TexelBytes) {
+ case 1:
+ tex.format = RADEON_TXFORMAT_I8;
+ break;
+ case 2:
+ tex.format = RADEON_TXFORMAT_AI88;
+ break;
+ case 4:
+ tex.format = RADEON_TXFORMAT_ARGB8888;
+ break;
+ }
+ tex.pitch = MAX2((texImage->Width * texImage->TexFormat->TexelBytes) / 64, 1);
+ tex.offset += tmp.x & ~1023;
+ tmp.x = tmp.x % 1024;
+
+ if (t->tile_bits & R300_TXO_MICRO_TILE) {
+ /* need something like "tiled coordinates" ? */
+ tmp.y = tmp.x / (tex.pitch * 128) * 2;
+ tmp.x = tmp.x % (tex.pitch * 128) / 2 / texImage->TexFormat->TexelBytes;
+ tex.pitch |= RADEON_DST_TILE_MICRO >> 22;
+ } else {
+ tmp.x = tmp.x >> (texImage->TexFormat->TexelBytes >> 1);
+ }
#if 1
- if ((t->tile_bits & R300_TXO_MACRO_TILE) &&
- (texImage->Width * texImage->TexFormat->TexelBytes >= 256) &&
- ((!(t->tile_bits & R300_TXO_MICRO_TILE) && (texImage->Height >= 8)) ||
- (texImage->Height >= 16))) {
- /* weird: R200 disables macro tiling if mip width is smaller than 256 bytes,
- OR if height is smaller than 8 automatically, but if micro tiling is active
- the limit is height 16 instead ? */
- tex.pitch |= RADEON_DST_TILE_MACRO >> 22;
- }
+ if ((t->tile_bits & R300_TXO_MACRO_TILE) &&
+ (texImage->Width * texImage->TexFormat->TexelBytes >= 256) &&
+ ((!(t->tile_bits & R300_TXO_MICRO_TILE) && (texImage->Height >= 8)) ||
+ (texImage->Height >= 16))) {
+ /* weird: R200 disables macro tiling if mip width is smaller than 256 bytes,
+ OR if height is smaller than 8 automatically, but if micro tiling is active
+ the limit is height 16 instead ? */
+ tex.pitch |= RADEON_DST_TILE_MACRO >> 22;
+ }
#endif
- }
- else {
- /* In case of for instance 8x8 texture (2x2 dxt blocks), padding after the first two blocks is
- needed (only with dxt1 since 2 dxt3/dxt5 blocks already use 32 Byte). */
- /* set tex.height to 1/4 since 1 "macropixel" (dxt-block) has 4 real pixels. Needed
- so the kernel module reads the right amount of data. */
- tex.format = RADEON_TXFORMAT_I8; /* any 1-byte texel format */
- tex.pitch = (R300_BLIT_WIDTH_BYTES / 64);
- tex.height = (imageHeight + 3) / 4;
- tex.width = (imageWidth + 3) / 4;
- if ((t->format & R300_TX_FORMAT_DXT1) == R300_TX_FORMAT_DXT1)
- {
- tex.width *= 8;
- } else {
- tex.width *= 16;
- }
- }
-
- LOCK_HARDWARE( &rmesa->radeon );
- do {
- ret = drmCommandWriteRead( rmesa->radeon.dri.fd, DRM_RADEON_TEXTURE,
- &tex, sizeof(drm_radeon_texture_t) );
- if (ret) {
- if (RADEON_DEBUG & DEBUG_IOCTL)
- fprintf(stderr, "DRM_RADEON_TEXTURE: again!\n");
- usleep(1);
- }
- } while ( ret == -EAGAIN );
-
- UNLOCK_HARDWARE( &rmesa->radeon );
-
- if ( ret ) {
- fprintf( stderr, "DRM_RADEON_TEXTURE: return = %d\n", ret );
- fprintf( stderr, " offset=0x%08x\n",
- offset );
- fprintf( stderr, " image width=%d height=%d\n",
- imageWidth, imageHeight );
- fprintf( stderr, " blit width=%d height=%d data=%p\n",
- t->image[face][hwlevel].width, t->image[face][hwlevel].height,
- t->image[face][hwlevel].data );
- exit( 1 );
- }
+ } else {
+ /* In case of for instance 8x8 texture (2x2 dxt blocks),
+ padding after the first two blocks is needed (only
+ with dxt1 since 2 dxt3/dxt5 blocks already use 32 Byte). */
+ /* set tex.height to 1/4 since 1 "macropixel" (dxt-block)
+ has 4 real pixels. Needed so the kernel module reads
+ the right amount of data. */
+ tex.format = RADEON_TXFORMAT_I8; /* any 1-byte texel format */
+ tex.pitch = (R300_BLIT_WIDTH_BYTES / 64);
+ tex.height = (imageHeight + 3) / 4;
+ tex.width = (imageWidth + 3) / 4;
+ if ((t->format & R300_TX_FORMAT_DXT1) == R300_TX_FORMAT_DXT1)
+ {
+ tex.width *= 8;
+ } else {
+ tex.width *= 16;
+ }
+ }
+
+ LOCK_HARDWARE( &rmesa->radeon );
+ do {
+ ret = drmCommandWriteRead( rmesa->radeon.dri.fd, DRM_RADEON_TEXTURE,
+ &tex, sizeof(drm_radeon_texture_t) );
+ if (ret) {
+ if (RADEON_DEBUG & DEBUG_IOCTL)
+ fprintf(stderr, "DRM_RADEON_TEXTURE: again!\n");
+ usleep(1);
+ }
+ } while ( ret == -EAGAIN );
+
+ UNLOCK_HARDWARE( &rmesa->radeon );
+
+ if ( ret ) {
+ fprintf( stderr, "DRM_RADEON_TEXTURE: return = %d\n", ret );
+ fprintf( stderr, " offset=0x%08x\n",
+ offset );
+ fprintf( stderr, " image width=%d height=%d\n",
+ imageWidth, imageHeight );
+ fprintf( stderr, " blit width=%d height=%d data=%p\n",
+ t->image[face][hwlevel].width, t->image[face][hwlevel].height,
+ t->image[face][hwlevel].data );
+ exit( 1 );
+ }
}
/**
diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c
index 4bc0ea14f8..14b0c6063b 100644
--- a/src/mesa/drivers/dri/r300/r300_texstate.c
+++ b/src/mesa/drivers/dri/r300/r300_texstate.c
@@ -218,7 +218,7 @@ static void r300SetTexImages(r300ContextPtr rmesa,
if (rmesa->texmicrotile && (tObj->Target != GL_TEXTURE_RECTANGLE_NV) &&
/* texrect might be able to use micro tiling too in theory? */
(baseImage->Height > 1)) {
-
+
/* allow 32 (bytes) x 1 mip (which will use two times the space
the non-tiled version would use) max if base texture is large enough */
if ((numLevels == 1) ||
@@ -228,7 +228,7 @@ static void r300SetTexImages(r300ContextPtr rmesa,
t->tile_bits |= R300_TXO_MICRO_TILE;
}
}
-
+
if (tObj->Target != GL_TEXTURE_RECTANGLE_NV) {
/* we can set macro tiling even for small textures, they will be untiled anyway */
t->tile_bits |= R300_TXO_MACRO_TILE;
@@ -237,91 +237,85 @@ static void r300SetTexImages(r300ContextPtr rmesa,
#endif
for (i = 0; i < numLevels; i++) {
- const struct gl_texture_image *texImage;
- GLuint size;
-
- texImage = tObj->Image[0][i + t->base.firstLevel];
- if (!texImage)
- break;
-
- /* find image size in bytes */
- if (texImage->IsCompressed) {
- if ((t->format & R300_TX_FORMAT_DXT1) == R300_TX_FORMAT_DXT1) {
- // fprintf(stderr,"DXT 1 %d %08X\n", texImage->Width, t->format);
- if ((texImage->Width + 3) < 8) /* width one block */
- size = texImage->CompressedSize * 4;
- else if ((texImage->Width + 3) < 16)
- size = texImage->CompressedSize * 2;
- else size = texImage->CompressedSize;
- }
- else /* DXT3/5, 16 bytes per block */
- {
- WARN_ONCE("DXT 3/5 suffers from multitexturing problems!\n");
- // fprintf(stderr,"DXT 3/5 %d\n", texImage->Width);
- if ((texImage->Width + 3) < 8)
- size = texImage->CompressedSize * 2;
- else size = texImage->CompressedSize;
- }
-
- } else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
- size = ((texImage->Width * texelBytes + 63) & ~63) * texImage->Height;
- blitWidth = 64 / texelBytes;
- } else if (t->tile_bits & R300_TXO_MICRO_TILE) {
- /* tile pattern is 16 bytes x2. mipmaps stay 32 byte aligned,
- though the actual offset may be different (if texture is less than
- 32 bytes width) to the untiled case */
- int w = (texImage->Width * texelBytes * 2 + 31) & ~31;
- size = (w * ((texImage->Height + 1) / 2)) * texImage->Depth;
- blitWidth = MAX2(texImage->Width, 64 / texelBytes);
- } else {
- int w = (texImage->Width * texelBytes + 31) & ~31;
- size = w * texImage->Height * texImage->Depth;
- blitWidth = MAX2(texImage->Width, 64 / texelBytes);
- }
- assert(size > 0);
-
- if(0)
- fprintf(stderr, "w=%d h=%d d=%d tb=%d intFormat=%d\n", texImage->Width, texImage->Height,
- texImage->Depth, texImage->TexFormat->TexelBytes,
- texImage->InternalFormat);
-
- /* Align to 32-byte offset. It is faster to do this unconditionally
- * (no branch penalty).
- */
-
- curOffset = (curOffset + 0x1f) & ~0x1f;
-
- if (texelBytes) {
- t->image[0][i].x = curOffset; /* fix x and y coords up later together with offset */
- t->image[0][i].y = 0;
- t->image[0][i].width = MIN2(size / texelBytes, blitWidth);
- t->image[0][i].height = (size / texelBytes) / t->image[0][i].width;
- } else {
- t->image[0][i].x = curOffset % R300_BLIT_WIDTH_BYTES;
- t->image[0][i].y = curOffset / R300_BLIT_WIDTH_BYTES;
- t->image[0][i].width = MIN2(size, R300_BLIT_WIDTH_BYTES);
- t->image[0][i].height = size / t->image[0][i].width;
- }
-#if 0
- /* for debugging only and only applicable to non-rectangle targets */
- assert(size % t->image[0][i].width == 0);
- assert(t->image[0][i].x == 0
- || (size < R300_BLIT_WIDTH_BYTES
- && t->image[0][i].height == 1));
-#endif
-
- if (0)
- fprintf(stderr,
- "level %d: %dx%d x=%d y=%d w=%d h=%d size=%d at %d\n",
- i, texImage->Width, texImage->Height,
- t->image[0][i].x, t->image[0][i].y,
- t->image[0][i].width, t->image[0][i].height,
- size, curOffset);
-
- curOffset += size;
-
+ const struct gl_texture_image *texImage;
+ GLuint size;
+
+ texImage = tObj->Image[0][i + t->base.firstLevel];
+ if (!texImage)
+ break;
+
+ /* find image size in bytes */
+ if (texImage->IsCompressed) {
+ if ((t->format & R300_TX_FORMAT_DXT1) == R300_TX_FORMAT_DXT1) {
+ // fprintf(stderr,"DXT 1 %d %08X\n", texImage->Width, t->format);
+ if ((texImage->Width + 3) < 8) /* width one block */
+ size = texImage->CompressedSize * 4;
+ else if ((texImage->Width + 3) < 16)
+ size = texImage->CompressedSize * 2;
+ else
+ size = texImage->CompressedSize;
+ } else {
+ /* DXT3/5, 16 bytes per block */
+ WARN_ONCE("DXT 3/5 suffers from multitexturing problems!\n");
+ // fprintf(stderr,"DXT 3/5 %d\n", texImage->Width);
+ if ((texImage->Width + 3) < 8)
+ size = texImage->CompressedSize * 2;
+ else
+ size = texImage->CompressedSize;
+ }
+ } else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
+ size = ((texImage->Width * texelBytes + 63) & ~63) * texImage->Height;
+ blitWidth = 64 / texelBytes;
+ } else if (t->tile_bits & R300_TXO_MICRO_TILE) {
+ /* tile pattern is 16 bytes x2. mipmaps stay 32 byte aligned,
+ though the actual offset may be different (if texture is less than
+ 32 bytes width) to the untiled case */
+ int w = (texImage->Width * texelBytes * 2 + 31) & ~31;
+ size = (w * ((texImage->Height + 1) / 2)) * texImage->Depth;
+ blitWidth = MAX2(texImage->Width, 64 / texelBytes);
+ } else {
+ int w = (texImage->Width * texelBytes + 31) & ~31;
+ size = w * texImage->Height * texImage->Depth;
+ blitWidth = MAX2(texImage->Width, 64 / texelBytes);
+ }
+ assert(size > 0);
+
+ if(0)
+ fprintf(stderr, "w=%d h=%d d=%d tb=%d intFormat=%d\n",
+ texImage->Width, texImage->Height,
+ texImage->Depth, texImage->TexFormat->TexelBytes,
+ texImage->InternalFormat);
+
+ /* Align to 32-byte offset. It is faster to do this unconditionally
+ * (no branch penalty).
+ */
+
+ curOffset = (curOffset + 0x1f) & ~0x1f;
+
+ if (texelBytes) {
+ /* fix x and y coords up later together with offset */
+ t->image[0][i].x = curOffset;
+ t->image[0][i].y = 0;
+ t->image[0][i].width = MIN2(size / texelBytes, blitWidth);
+ t->image[0][i].height = (size / texelBytes) / t->image[0][i].width;
+ } else {
+ t->image[0][i].x = curOffset % R300_BLIT_WIDTH_BYTES;
+ t->image[0][i].y = curOffset / R300_BLIT_WIDTH_BYTES;
+ t->image[0][i].width = MIN2(size, R300_BLIT_WIDTH_BYTES);
+ t->image[0][i].height = size / t->image[0][i].width;
+ }
+
+ if (0)
+ fprintf(stderr,
+ "level %d: %dx%d x=%d y=%d w=%d h=%d size=%d at %d\n",
+ i, texImage->Width, texImage->Height,
+ t->image[0][i].x, t->image[0][i].y,
+ t->image[0][i].width, t->image[0][i].height,
+ size, curOffset);
+
+ curOffset += size;
}
-
+
/* Align the total size of texture memory block.
*/
t->base.totalSize =
@@ -361,7 +355,7 @@ static void r300SetTexImages(r300ContextPtr rmesa,
} else if (tObj->Target == GL_TEXTURE_CUBE_MAP) {
ASSERT(log2Width == log2Height);
t->format |= R300_TX_FORMAT_CUBIC_MAP;
-
+
t->format_x |= R200_TEXCOORD_CUBIC_ENV;
t->pp_cubic_faces = ((log2Width << R200_FACE_WIDTH_1_SHIFT) |
(log2Height << R200_FACE_HEIGHT_1_SHIFT) |
@@ -377,7 +371,7 @@ static void r300SetTexImages(r300ContextPtr rmesa,
ASSERT(log2Width == log2Height);
t->format |= R300_TX_FORMAT_CUBIC_MAP;
}
-
+
t->size = (((tObj->Image[0][t->base.firstLevel]->Width - 1) << R300_TX_WIDTHMASK_SHIFT)
|((tObj->Image[0][t->base.firstLevel]->Height - 1) << R300_TX_HEIGHTMASK_SHIFT))
|((numLevels - 1) << R300_TX_MAX_MIP_LEVEL_SHIFT);