summaryrefslogtreecommitdiff
path: root/xc/lib/GL/mesa/src/drv/r200/r200_texmem.c
diff options
context:
space:
mode:
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.c174
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(&region, 0, sizeof(region));
- r200AllocDmaRegion( rmesa, &region, lines * blit_pitch, 64 );
+ r200AllocDmaRegion( rmesa, &region, 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( &region ),
- blit_pitch, t->bufAddr,
+ dstPitch, GET_START( &region ),
+ 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 );