From 1d4c85c0097fe65fd9e3c22023503df92f707486 Mon Sep 17 00:00:00 2001 From: Peter Zubaj Date: Sat, 23 Jun 2007 08:42:32 +0200 Subject: [PATCH] Fixed upload of rectangle textures. --- src/mesa/drivers/dri/r300/r300_texmem.c | 10 ++- src/mesa/drivers/dri/r300/r300_texstate.c | 139 +++++++++++++++++------------ 2 files changed, 90 insertions(+), 59 deletions(-) diff --git a/src/mesa/drivers/dri/r300/r300_texmem.c b/src/mesa/drivers/dri/r300/r300_texmem.c index 4e224d3..7853f77 100644 --- a/src/mesa/drivers/dri/r300/r300_texmem.c +++ b/src/mesa/drivers/dri/r300/r300_texmem.c @@ -81,6 +81,7 @@ void r300DestroyTexObj(r300ContextPtr rmesa, r300TexObjPtr t) * Texture image conversions */ +/* this is not used */ static void r300UploadGARTClientSubImage(r300ContextPtr rmesa, r300TexObjPtr t, struct gl_texture_image *texImage, @@ -153,6 +154,8 @@ static void r300UploadGARTClientSubImage(r300ContextPtr rmesa, r300EmitWait(rmesa, R300_WAIT_2D); } +#if 0 +/* not used for now */ static void r300UploadRectSubImage(r300ContextPtr rmesa, r300TexObjPtr t, struct gl_texture_image *texImage, @@ -279,6 +282,8 @@ static void r300UploadRectSubImage(r300ContextPtr rmesa, } } +#endif + /** * Upload the texture image associated with texture \a t at the specified * level at the address relative to \a start. @@ -326,7 +331,8 @@ static void r300UploadSubImage(r300ContextPtr rmesa, r300TexObjPtr t, return; } - if (t->base.tObj->Target == GL_TEXTURE_RECTANGLE_NV) { + /* use normal blit for rect textures */ +/* if (t->base.tObj->Target == GL_TEXTURE_RECTANGLE_NV) { assert(level == 0); assert(hwlevel == 0); if (RADEON_DEBUG & DEBUG_TEXTURE) @@ -334,7 +340,7 @@ static void r300UploadSubImage(r300ContextPtr rmesa, r300TexObjPtr t, __FUNCTION__); r300UploadRectSubImage(rmesa, t, texImage, x, y, width, height); return; - } else if (texImage->IsClientData) { + } else*/ if (texImage->IsClientData) { if (RADEON_DEBUG & DEBUG_TEXTURE) fprintf(stderr, "%s: image data is in GART client storage\n", diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c index 8337b53..d753053 100644 --- a/src/mesa/drivers/dri/r300/r300_texstate.c +++ b/src/mesa/drivers/dri/r300/r300_texstate.c @@ -188,22 +188,54 @@ static void r300SetTexImages(r300ContextPtr rmesa, /* we can set macro tiling even for small textures, they will be untiled anyway */ t->tile_bits |= R300_TXO_MACRO_TILE; } + + /* setup coef - they are const */ + height_coef = 1; + /* dxt textures have height/4 */ + if (tObj->Image[0][t->base.firstLevel]->IsCompressed) + height_coef = 4; + + /* if texture has more then 4 bytes per pixel, blit width is multiplied */ + width_coef = 1; + if (tObj->Image[0][t->base.firstLevel]->IsCompressed) { + t->transfer_size = 2; + /* DXT 3/5 have two times width */ + if ((t->format & R300_TX_FORMAT_DXT1) == R300_TX_FORMAT_DXT1) + width_coef = 1; + else + width_coef = 2; + } else if (texelBytes >= 4) { + /* textures with more then 4 bytes on texel */ + t->transfer_size = 4; + width_coef = texelBytes / 4; + } else if (texelBytes >= 2) + t->transfer_size = 2; + else + t->transfer_size = 1; for (i = 0; i < numLevels; i++) { const struct gl_texture_image *texImage; GLuint size; + GLuint blitWidth; texImage = tObj->Image[0][i + t->base.firstLevel]; if (!texImage) break; + + blitWidth = texImage->Width; /* find image size in bytes */ if (texImage->IsCompressed) { size = texImage->CompressedSize; + /* minimum size for compressed textures is 32 */ + size = ((size + 31) & ~31); } else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) { + /* for rect textures we need pad texture + blit stil uses original width, only pitch is padded to 16 */ + blitWidth = (((texImage->Width) + 15) & ~15); size = - ((texImage->Width * texelBytes + - 63) & ~63) * texImage->Height; + ((blitWidth * texelBytes + + 15) & ~15) * texImage->Height; } 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 @@ -231,86 +263,82 @@ static void r300SetTexImages(r300ContextPtr rmesa, curOffset = (curOffset + 0x1f) & ~0x1f; - height_coef = 1; - if (texImage->IsCompressed) - height_coef = 4; - - width_coef = 1; - if (texImage->IsCompressed) { - t->transfer_size = 2; - /* DXT 3/5 have two times width */ - if ((t->format & R300_TX_FORMAT_DXT1) == R300_TX_FORMAT_DXT1) - width_coef = 1; - else - width_coef = 2; - } else if (texelBytes >= 4) { - /* textures with more then 4 bytes on texel */ - t->transfer_size = 4; - width_coef = texelBytes / 4; - } else if (texelBytes >= 2) - t->transfer_size = 2; - else - t->transfer_size = 1; t->image[0][i].clip_x = 0; t->image[0][i].clip_y = 0; /* set tiling register for blit from base texture tiling */ t->image[0][i].src_dst_tile = t->tile_bits >> 2; + + /* for not compressed textures with height <= 8 disable micro tiling + and for height < 2 macro tiling too - this is only guess */ + if (!texImage->IsCompressed && texImage->Height <= 8) { + t->image[0][i].src_dst_tile &= ~(R300_TXO_MICRO_TILE >> 2); + if (texImage->Height < 2) + t->image[0][i].src_dst_tile &= ~(R300_TXO_MACRO_TILE >> 2); + } /* for small sizes turn off macro tiling */ if (texImage->IsCompressed && (texImage->Width <= 32)) { t->image[0][i].src_dst_tile &= ~(R300_TXO_MACRO_TILE >> 2); } else { - if (t->transfer_size < 2 ) { - if (texImage->Width <= 32) - t->image[0][i].src_dst_tile &= ~(R300_TXO_MACRO_TILE >> 2); - } else if (texImage->Width <= 16) - t->image[0][i].src_dst_tile &= ~(R300_TXO_MACRO_TILE >> 2); + if (t->transfer_size < 2 ) { + if (texImage->Width <= 32) + t->image[0][i].src_dst_tile &= ~(R300_TXO_MACRO_TILE >> 2); + } else if (texImage->Width <= 16) + t->image[0][i].src_dst_tile &= ~(R300_TXO_MACRO_TILE >> 2); } - /* correct start tiling on first level */ + /* correct start tiling on first level used for hw registers */ if ((i == 0) && (t->image[0][i].src_dst_tile != (t->tile_bits >> 2))) - t->tile_bits = t->image[0][i].src_dst_tile << 2; + t->tile_bits = t->image[0][i].src_dst_tile << 2; t->image[0][i].x = 0; t->image[0][i].y = 0; - + + /* set minimal width */ if (texImage->IsCompressed) { - if ((t->format & R300_TX_FORMAT_DXT1) != R300_TX_FORMAT_DXT1) - t->image[0][i].width = MAX2(width_coef * texImage->Width, 16); /* guess */ - else - t->image[0][i].width = MAX2(width_coef * texImage->Width, 4); + if ((t->format & R300_TX_FORMAT_DXT1) != R300_TX_FORMAT_DXT1) + t->image[0][i].width = MAX2(width_coef * texImage->Width, 8); /* guess */ + else + t->image[0][i].width = MAX2(width_coef * texImage->Width, 4); } else - t->image[0][i].width = width_coef * texImage->Width; + t->image[0][i].width = width_coef * texImage->Width; t->image[0][i].height = texImage->Height / height_coef; if (t->image[0][i].height <= 0) - t->image[0][i].height = 1; + t->image[0][i].height = 1; t->image[0][i].dst_offset = curOffset; - t->image[0][i].dst_pitch = MAX2(t->image[0][i].width * t->transfer_size, 16); - + /* set blit pitch - used for pitch texture register too */ + if (tObj->Target != GL_TEXTURE_RECTANGLE_NV) + t->image[0][i].dst_pitch = MAX2(t->image[0][i].width * t->transfer_size, 16); + else + t->image[0][i].dst_pitch = MAX2(blitWidth * width_coef * t->transfer_size, 16); + + /* blit clipping */ if (texImage->IsCompressed) { - if ((t->format & R300_TX_FORMAT_DXT1) != R300_TX_FORMAT_DXT1) - t->image[0][i].clip_width = MAX2(width_coef * texImage->Width, 16); - else - t->image[0][i].clip_width = MAX2(width_coef * texImage->Width, 8); + if ((t->format & R300_TX_FORMAT_DXT1) != R300_TX_FORMAT_DXT1) + t->image[0][i].clip_width = MAX2(width_coef * texImage->Width, 16); + else + t->image[0][i].clip_width = MAX2(width_coef * texImage->Width, 8); } else - t->image[0][i].clip_width = width_coef * texImage->Width; + t->image[0][i].clip_width = width_coef * texImage->Width; t->image[0][i].clip_height = texImage->Height / height_coef; if (t->image[0][i].clip_height <= 0) - t->image[0][i].clip_height = 1; + t->image[0][i].clip_height = 1; if (RADEON_DEBUG & DEBUG_TEXTURE) fprintf(stderr, - "level %d: %dx%d x=%d y=%d w=%d h=%d size=%d at %d\n", + "level %d: %dx%d x=%d y=%d w=%d h=%d size=%d at %d\ncx=%d cy=%d cw=%d ch=%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); + size, curOffset, + t->image[0][i].clip_x, t->image[0][i].clip_y, + t->image[0][i].clip_width, t->image[0][i].clip_height); curOffset += size; } @@ -360,18 +388,15 @@ static void r300SetTexImages(r300ContextPtr rmesa, * blitter. NPOT only! */ /* I dont know what is minimal pitch for 2d blitter, and this is probably wrong */ - if (baseImage->IsCompressed) { - t->pitch = - (tObj->Image[0][t->base.firstLevel]->Width + 15) & ~(15); - } else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) { - unsigned int align = tObj->Image[0][t->base.firstLevel]->Width - 1; - t->pitch = ((tObj->Image[0][t->base.firstLevel]->Width * - texelBytes) + 15) & ~(15); - t->size |= R300_TX_SIZE_TXPITCH_EN; + /* get pitch from first level */ + if (baseImage->IsCompressed) + t->pitch = (tObj->Image[0][t->base.firstLevel]->Width + 15) & ~(15); + else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) { + t->pitch = t->image[0][t->base.firstLevel].dst_pitch; + /* for rectangular textures set pitch control */ + t->size |= R300_TX_SIZE_TXPITCH_EN; if (!t->image_override) - t->pitch_reg = - (((tObj->Image[0][t->base.firstLevel]->Width) + - align) & ~align) - 1; + t->pitch_reg = t->pitch / (t->transfer_size * width_coef) - 1; } else { t->pitch = ((tObj->Image[0][t->base.firstLevel]->Width * -- 1.5.2.1