diff options
Diffstat (limited to 'xc/lib/GL/mesa/src/drv/r200/r200_texmem.c')
-rw-r--r-- | xc/lib/GL/mesa/src/drv/r200/r200_texmem.c | 174 |
1 files changed, 119 insertions, 55 deletions
diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_texmem.c b/xc/lib/GL/mesa/src/drv/r200/r200_texmem.c index c1f8dba69..32624ab18 100644 --- a/xc/lib/GL/mesa/src/drv/r200/r200_texmem.c +++ b/xc/lib/GL/mesa/src/drv/r200/r200_texmem.c @@ -36,6 +36,13 @@ SOFTWARE. * */ +#include "glheader.h" +#include "imports.h" +#include "context.h" +#include "colormac.h" +#include "mmath.h" +#include "macros.h" +#include "simple_list.h" #include "radeon_reg.h" /* gets definition for usleep */ #include "r200_context.h" #include "r200_state.h" @@ -43,15 +50,8 @@ SOFTWARE. #include "r200_swtcl.h" #include "r200_tex.h" -#include "context.h" -#include "colormac.h" -#include "mmath.h" -#include "macros.h" -#include "simple_list.h" -#include "enums.h" -#include "mem.h" +#include <unistd.h> /* for usleep() */ -#undef usleep /* Destroy hardware state associated with texture `t'. */ @@ -77,12 +77,16 @@ void r200DestroyTexObj( r200ContextPtr rmesa, r200TexObjPtr t ) rmesa->state.texture.unit[0].texobj = NULL; remove_from_list( &rmesa->hw.tex[0] ); make_empty_list( &rmesa->hw.tex[0] ); + remove_from_list( &rmesa->hw.cube[0] ); + make_empty_list( &rmesa->hw.cube[0] ); } if ( t == rmesa->state.texture.unit[1].texobj ) { rmesa->state.texture.unit[1].texobj = NULL; remove_from_list( &rmesa->hw.tex[1] ); make_empty_list( &rmesa->hw.tex[1] ); + remove_from_list( &rmesa->hw.cube[1] ); + make_empty_list( &rmesa->hw.cube[1] ); } } @@ -95,6 +99,8 @@ void r200DestroyTexObj( r200ContextPtr rmesa, r200TexObjPtr t ) */ void r200SwapOutTexObj( r200ContextPtr rmesa, r200TexObjPtr t ) { + GLuint face; + if ( R200_DEBUG & DEBUG_TEXTURE ) { fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, t, t->tObj ); } @@ -104,7 +110,8 @@ void r200SwapOutTexObj( r200ContextPtr rmesa, r200TexObjPtr t ) t->memBlock = NULL; } - t->dirty_images = ~0; + for (face = 0; face < 6; face++) + t->dirty_images[face] = ~0; move_to_tail( &rmesa->texture.swapped, t ); } @@ -326,26 +333,36 @@ static void r200UploadAGPClientSubImage( r200ContextPtr rmesa, GLint width, GLint height ) { const struct gl_texture_format *texFormat = texImage->TexFormat; - GLuint pitch = t->image[0].width * texFormat->TexelBytes; + GLuint srcPitch, dstPitch; int blit_format; int srcOffset; - + /* + * XXX it appears that we always upload the full image, not a subimage. + * I.e. x==0, y==0, width=texWidth, height=texWidth. If this is ever + * changed, the src pitch will have to change. + */ switch ( texFormat->TexelBytes ) { case 1: blit_format = R200_CP_COLOR_FORMAT_CI8; + srcPitch = t->image[0][0].width * texFormat->TexelBytes; + dstPitch = t->image[0][0].width * texFormat->TexelBytes; break; case 2: blit_format = R200_CP_COLOR_FORMAT_RGB565; + srcPitch = t->image[0][0].width * texFormat->TexelBytes; + dstPitch = t->image[0][0].width * texFormat->TexelBytes; break; case 4: blit_format = R200_CP_COLOR_FORMAT_ARGB8888; + srcPitch = t->image[0][0].width * texFormat->TexelBytes; + dstPitch = t->image[0][0].width * texFormat->TexelBytes; break; default: return; } - t->image[hwlevel].data = texImage->Data; + t->image[0][hwlevel].data = texImage->Data; srcOffset = r200AgpOffsetFromVirtual( rmesa, texImage->Data ); assert( srcOffset != ~0 ); @@ -358,14 +375,14 @@ static void r200UploadAGPClientSubImage( r200ContextPtr rmesa, r200EmitWait( rmesa, RADEON_WAIT_3D ); r200EmitBlit( rmesa, blit_format, - pitch, + srcPitch, srcOffset, - t->image[0].width * texFormat->TexelBytes, /* dst pitch! */ + dstPitch, t->bufAddr, x, y, - t->image[hwlevel].x + x, - t->image[hwlevel].y + y, + t->image[0][hwlevel].x + x, + t->image[0][hwlevel].y + y, width, height ); @@ -379,7 +396,7 @@ static void r200UploadRectSubImage( r200ContextPtr rmesa, GLint width, GLint height ) { const struct gl_texture_format *texFormat = texImage->TexFormat; - int blit_format, blit_pitch, done; + int blit_format, dstPitch, done; switch ( texFormat->TexelBytes ) { case 1: @@ -395,13 +412,13 @@ static void r200UploadRectSubImage( r200ContextPtr rmesa, return; } - t->image[0].data = texImage->Data; + t->image[0][0].data = texImage->Data; /* Currently don't need to cope with small pitches. */ width = texImage->Width; height = texImage->Height; - blit_pitch = t->pp_txpitch + 32; + dstPitch = t->pp_txpitch + 32; if (rmesa->prefer_agp_client_texturing && texImage->IsClientData) { /* In this case, could also use agp texturing. This is @@ -425,11 +442,13 @@ static void r200UploadRectSubImage( r200ContextPtr rmesa, else if (texImage->IsClientData) { /* Data already in agp memory, with usable pitch. */ + GLuint srcPitch; + srcPitch = texImage->RowStride * texFormat->TexelBytes; r200EmitBlit( rmesa, blit_format, - texImage->RowStride * texFormat->TexelBytes, + srcPitch, r200AgpOffsetFromVirtual( rmesa, texImage->Data ), - blit_pitch, t->bufAddr, + dstPitch, t->bufAddr, 0, 0, 0, 0, width, height ); @@ -439,20 +458,24 @@ static void r200UploadRectSubImage( r200ContextPtr rmesa, */ for (done = 0; done < height ; ) { struct r200_dma_region region; - int lines = MIN2( height - done, RADEON_BUFFER_SIZE / blit_pitch ); - int src_pitch = texImage->RowStride * texFormat->TexelBytes; - char *tex = (char *)texImage->Data + done * src_pitch; + int lines = MIN2( height - done, RADEON_BUFFER_SIZE / dstPitch ); + int src_pitch; + char *tex; + + src_pitch = texImage->RowStride * texFormat->TexelBytes; + + tex = (char *)texImage->Data + done * src_pitch; memset(®ion, 0, sizeof(region)); - r200AllocDmaRegion( rmesa, ®ion, lines * blit_pitch, 64 ); + r200AllocDmaRegion( rmesa, ®ion, lines * dstPitch, 64 ); /* Copy texdata to dma: */ if (0) - fprintf(stderr, "%s: src_pitch %d blit_pitch %d\n", - __FUNCTION__, src_pitch, blit_pitch); + fprintf(stderr, "%s: src_pitch %d dst_pitch %d\n", + __FUNCTION__, src_pitch, dstPitch); - if (src_pitch == blit_pitch) { + if (src_pitch == dstPitch) { memcpy( region.address, tex, lines * src_pitch ); } else { @@ -460,7 +483,7 @@ static void r200UploadRectSubImage( r200ContextPtr rmesa, int i; for (i = 0 ; i < lines ; i++) { memcpy( buf, tex, src_pitch ); - buf += blit_pitch; + buf += dstPitch; tex += src_pitch; } } @@ -471,8 +494,8 @@ static void r200UploadRectSubImage( r200ContextPtr rmesa, */ r200EmitBlit( rmesa, blit_format, - blit_pitch, GET_START( ®ion ), - blit_pitch, t->bufAddr, + dstPitch, GET_START( ®ion ), + dstPitch, t->bufAddr, 0, 0, 0, done, width, lines ); @@ -492,9 +515,10 @@ static void r200UploadRectSubImage( r200ContextPtr rmesa, static void r200UploadSubImage( r200ContextPtr rmesa, r200TexObjPtr t, GLint hwlevel, - GLint x, GLint y, GLint width, GLint height ) + GLint x, GLint y, GLint width, GLint height, + GLuint face ) { - struct gl_texture_image *texImage; + struct gl_texture_image *texImage = NULL; const struct gl_texture_format *texFormat; GLint texelsPerDword = 0; GLuint format, pitch, offset; @@ -509,13 +533,35 @@ static void r200UploadSubImage( r200ContextPtr rmesa, level, width, height); } + 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 r200UploadSubimage"); return; } - texImage = t->tObj->Image[level]; + switch (face) { + case 0: + texImage = t->tObj->Image[level]; + break; + case 1: + texImage = t->tObj->NegX[level]; + break; + case 2: + texImage = t->tObj->PosY[level]; + break; + case 3: + texImage = t->tObj->NegY[level]; + break; + case 4: + texImage = t->tObj->PosZ[level]; + break; + case 5: + texImage = t->tObj->NegZ[level]; + break; + } + if ( !texImage ) { if ( R200_DEBUG & DEBUG_TEXTURE ) fprintf( stderr, "%s: texImage %d is NULL!\n", __FUNCTION__, level ); @@ -569,17 +615,21 @@ static void r200UploadSubImage( r200ContextPtr rmesa, imageHeight = texImage->Height; offset = t->bufAddr; - pitch = (t->image[0].width * texFormat->TexelBytes) / 64; + + if (texFormat->TexelBytes == 0) + pitch = (t->image[face][0].width * 1) / 64; + else + pitch = (t->image[face][0].width * texFormat->TexelBytes) / 64; if ( R200_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) { GLint imageX = 0; GLint imageY = 0; - GLint blitX = t->image[hwlevel].x; - GLint blitY = t->image[hwlevel].y; - GLint blitWidth = t->image[hwlevel].width; - GLint blitHeight = t->image[hwlevel].height; + 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", @@ -589,16 +639,31 @@ static void r200UploadSubImage( r200ContextPtr rmesa, (GLuint)offset, (GLuint)pitch, hwlevel, level, format ); } - t->image[hwlevel].data = texImage->Data; + t->image[face][hwlevel].data = texImage->Data; + /* Init the DRM_RADEON_TEXTURE command / drmRadeonTexture 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) + */ tex.offset = offset; - tex.pitch = pitch; - tex.format = format; - tex.width = imageWidth; - tex.height = imageHeight; + tex.pitch = BLIT_WIDTH_BYTES / 64; + tex.format = R200_TXFORMAT_I8; /* any 1-byte texel format */ + if (texImage->TexFormat->TexelBytes) { + tex.width = imageWidth * texImage->TexFormat->TexelBytes; /* in bytes */ + tex.height = imageHeight; + } + else { + tex.width = imageWidth; /* compressed */ + tex.height = imageHeight; + if (tex.height < 4) + tex.height = 4; + } tex.image = &tmp; - memcpy( &tmp, &t->image[hwlevel], sizeof(drmRadeonTexImage) ); + /* copy (x,y,width,height,data) */ + memcpy( &tmp, &t->image[face][hwlevel], sizeof(drmRadeonTexImage) ); LOCK_HARDWARE( rmesa ); do { @@ -620,8 +685,8 @@ static void r200UploadSubImage( r200ContextPtr rmesa, fprintf( stderr, " image width=%d height=%d\n", imageWidth, imageHeight ); fprintf( stderr, " blit width=%d height=%d data=%p\n", - t->image[hwlevel].width, t->image[hwlevel].height, - t->image[hwlevel].data ); + t->image[face][hwlevel].width, t->image[face][hwlevel].height, + t->image[face][hwlevel].data ); exit( 1 ); } } @@ -632,7 +697,7 @@ static void r200UploadSubImage( r200ContextPtr rmesa, * require removing our own and/or other client's texture objects to * make room for these images. */ -int r200UploadTexImages( r200ContextPtr rmesa, r200TexObjPtr t ) +int r200UploadTexImages( r200ContextPtr rmesa, r200TexObjPtr t, GLuint face ) { const int numLevels = t->lastLevel - t->firstLevel + 1; int heap; @@ -713,21 +778,20 @@ int r200UploadTexImages( r200ContextPtr rmesa, r200TexObjPtr t ) UNLOCK_HARDWARE( rmesa ); /* Upload any images that are new */ - if (t->dirty_images) { + if (t->dirty_images[face]) { int hwlevel; for ( hwlevel = 0 ; hwlevel < numLevels ; hwlevel++ ) { - if ( t->dirty_images & (1 << (hwlevel+t->firstLevel)) ) { + if ( t->dirty_images[face] & (1 << (hwlevel+t->firstLevel)) ) { r200UploadSubImage( rmesa, t, hwlevel, - 0, 0, - t->image[hwlevel].width, - t->image[hwlevel].height ); + 0, 0, + t->image[face][hwlevel].width, + t->image[face][hwlevel].height, face ); } } - t->dirty_images = 0; + t->dirty_images[face] = 0; } - if (R200_DEBUG & DEBUG_SYNC) { fprintf(stderr, "\nSyncing\n\n"); r200Finish( rmesa->glCtx ); |