X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fdri%2Fradeon%2Fradeon_texmem.c;h=20f25dd34b4bab0b186947fe84fcdc35fa030dc5;hb=29c471aafc6a3fef23d553e31a555d1782854a77;hp=61f187762cdeac016fe9b09ee3f5c3f33c23b247;hpb=ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0;p=mesa.git diff --git a/src/mesa/drivers/dri/radeon/radeon_texmem.c b/src/mesa/drivers/dri/radeon/radeon_texmem.c index 61f187762cd..20f25dd34b4 100644 --- a/src/mesa/drivers/dri/radeon/radeon_texmem.c +++ b/src/mesa/drivers/dri/radeon/radeon_texmem.c @@ -41,12 +41,13 @@ SOFTWARE. #include "imports.h" #include "context.h" #include "macros.h" -#include "simple_list.h" #include "radeon_context.h" #include "radeon_ioctl.h" #include "radeon_tex.h" +#include /* for usleep() */ + /** * Destroy any device-dependent state associated with the texture. This may @@ -56,7 +57,7 @@ void radeonDestroyTexObj( radeonContextPtr rmesa, radeonTexObjPtr t ) { if ( RADEON_DEBUG & DEBUG_TEXTURE ) { - fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, t, t->base.tObj ); + fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, (void *)t, (void *)t->base.tObj ); } if ( rmesa != NULL ) { @@ -66,8 +67,6 @@ radeonDestroyTexObj( radeonContextPtr rmesa, radeonTexObjPtr t ) for ( i = 0 ; i < rmesa->glCtx->Const.MaxTextureUnits ; i++ ) { if ( t == rmesa->state.texture.unit[i].texobj ) { rmesa->state.texture.unit[i].texobj = NULL; - remove_from_list( &rmesa->hw.tex[i] ); - make_empty_list( &rmesa->hw.tex[i] ); } } } @@ -153,12 +152,12 @@ static void radeonUploadRectSubImage( radeonContextPtr rmesa, /* Blit to framebuffer */ - radeonEmitBlit( rmesa, - blit_format, - dstPitch, GET_START( ®ion ), - dstPitch, t->bufAddr, - 0, 0, - 0, done, + radeonEmitBlit( rmesa, + blit_format, + dstPitch, GET_START( ®ion ), + dstPitch, t->bufAddr, + 0, 0, + 0, done, width, lines ); radeonEmitWait( rmesa, RADEON_WAIT_2D ); @@ -189,7 +188,7 @@ static void uploadSubImage( radeonContextPtr rmesa, radeonTexObjPtr t, if ( RADEON_DEBUG & DEBUG_TEXTURE ) { fprintf( stderr, "%s( %p, %p ) level/width/height/face = %d/%d/%d/%u\n", - __FUNCTION__, t, t->base.tObj, level, width, height, face ); + __FUNCTION__, (void *)t, (void *)t->base.tObj, level, width, height, face ); } ASSERT(face < 6); @@ -226,7 +225,7 @@ static void uploadSubImage( radeonContextPtr rmesa, radeonTexObjPtr t, imageWidth = texImage->Width; imageHeight = texImage->Height; - offset = t->bufAddr; + offset = t->bufAddr + t->base.totalSize * face / 6; if ( RADEON_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) { GLint imageX = 0; @@ -250,30 +249,61 @@ static void uploadSubImage( radeonContextPtr rmesa, radeonTexObjPtr t, * 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.pitch = BLIT_WIDTH_BYTES / 64; - tex.format = RADEON_TXFORMAT_I8; /* any 1-byte texel format */ + tex.image = &tmp; + /* copy (x,y,width,height,data) */ + memcpy( &tmp, &t->image[face][hwlevel], sizeof(drm_radeon_tex_image_t) ); + if (texImage->TexFormat->TexelBytes) { - tex.width = imageWidth * texImage->TexFormat->TexelBytes; /* in bytes */ + /* use multi-byte upload scheme */ tex.height = imageHeight; + tex.width = imageWidth; + tex.format = t->pp_txformat & RADEON_TXFORMAT_FORMAT_MASK; + tex.pitch = MAX2((texImage->Width * texImage->TexFormat->TexelBytes) / 64, 1); + tex.offset += tmp.x & ~1023; + tmp.x = tmp.x % 1024; + if (t->tile_bits & RADEON_TXO_MICRO_TILE_X2) { + /* 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 ((t->tile_bits & RADEON_TXO_MACRO_TILE) && + (texImage->Width * texImage->TexFormat->TexelBytes >= 256)) { + /* radeon switches off macro tiling for small textures/mipmaps it seems */ + tex.pitch |= RADEON_DST_TILE_MACRO >> 22; + } } else { - tex.width = imageWidth; /* compressed */ - tex.height = imageHeight; - if (tex.height < 4) - tex.height = 4; + /* 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 = (BLIT_WIDTH_BYTES / 64); + tex.height = (imageHeight + 3) / 4; + tex.width = (imageWidth + 3) / 4; + switch (t->pp_txformat & RADEON_TXFORMAT_FORMAT_MASK) { + case RADEON_TXFORMAT_DXT1: + tex.width *= 8; + break; + case RADEON_TXFORMAT_DXT23: + case RADEON_TXFORMAT_DXT45: + tex.width *= 16; + break; + } } - tex.image = &tmp; - - /* copy (x,y,width,height,data) */ - memcpy( &tmp, &t->image[face][hwlevel], sizeof(drm_radeon_tex_image_t) ); LOCK_HARDWARE( rmesa ); do { ret = drmCommandWriteRead( rmesa->dri.fd, DRM_RADEON_TEXTURE, &tex, sizeof(drm_radeon_texture_t) ); - } while ( ret && errno == EAGAIN ); + } while ( ret == -EAGAIN ); UNLOCK_HARDWARE( rmesa ); @@ -302,16 +332,23 @@ static void uploadSubImage( radeonContextPtr rmesa, radeonTexObjPtr t, int radeonUploadTexImages( radeonContextPtr rmesa, radeonTexObjPtr t, GLuint face ) { - const int numLevels = t->base.lastLevel - t->base.firstLevel + 1; + int numLevels; + + if ( !t || t->base.totalSize == 0 ) + return 0; if ( RADEON_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) { fprintf( stderr, "%s( %p, %p ) sz=%d lvls=%d-%d\n", __FUNCTION__, - rmesa->glCtx, t->base.tObj, t->base.totalSize, + (void *)rmesa->glCtx, (void *)t->base.tObj, t->base.totalSize, t->base.firstLevel, t->base.lastLevel ); } - if ( !t || t->base.totalSize == 0 ) - return 0; + numLevels = t->base.lastLevel - t->base.firstLevel + 1; + + if (RADEON_DEBUG & DEBUG_SYNC) { + fprintf(stderr, "%s: Syncing\n", __FUNCTION__ ); + radeonFinish( rmesa->glCtx ); + } LOCK_HARDWARE( rmesa ); @@ -330,6 +367,10 @@ int radeonUploadTexImages( radeonContextPtr rmesa, radeonTexObjPtr t, GLuint fac + t->base.memBlock->ofs; t->pp_txoffset = t->bufAddr; + if (!(t->base.tObj->Image[0][0]->IsClientData)) { + /* hope it's safe to add that here... */ + t->pp_txoffset |= t->tile_bits; + } /* Mark this texobj as dirty on all units: */ @@ -355,5 +396,10 @@ int radeonUploadTexImages( radeonContextPtr rmesa, radeonTexObjPtr t, GLuint fac t->base.dirty_images[face] = 0; } + if (RADEON_DEBUG & DEBUG_SYNC) { + fprintf(stderr, "%s: Syncing\n", __FUNCTION__ ); + radeonFinish( rmesa->glCtx ); + } + return 0; }