diff options
-rw-r--r-- | progs/tests/fbotest2.c | 4 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_urb.c | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r300/r300_fragprog.c | 9 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r300/r300_texmem.c | 361 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r300/r300_texstate.c | 170 | ||||
-rw-r--r-- | src/mesa/drivers/x11/xm_buffer.c | 12 | ||||
-rw-r--r-- | src/mesa/main/api_loopback.c | 2 | ||||
-rw-r--r-- | src/mesa/main/fbobject.c | 22 | ||||
-rw-r--r-- | src/mesa/main/framebuffer.c | 52 | ||||
-rw-r--r-- | src/mesa/main/rbadaptors.c | 2 | ||||
-rw-r--r-- | src/mesa/main/renderbuffer.c | 56 | ||||
-rw-r--r-- | src/mesa/main/renderbuffer.h | 3 |
12 files changed, 327 insertions, 368 deletions
diff --git a/progs/tests/fbotest2.c b/progs/tests/fbotest2.c index c3117b0f767..18f28972b6e 100644 --- a/progs/tests/fbotest2.c +++ b/progs/tests/fbotest2.c @@ -13,6 +13,7 @@ #include <math.h> #include <GL/glut.h> +static int Win = 0; static int Width = 400, Height = 400; static GLuint MyFB, ColorRb, DepthRb; static GLboolean Animate = GL_TRUE; @@ -110,6 +111,7 @@ CleanUp(void) assert(!glIsFramebufferEXT(MyFB)); assert(!glIsRenderbufferEXT(ColorRb)); assert(!glIsRenderbufferEXT(DepthRb)); + glutDestroyWindow(Win); exit(0); } @@ -187,7 +189,7 @@ main( int argc, char *argv[] ) glutInitWindowPosition( 0, 0 ); glutInitWindowSize(Width, Height); glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE ); - glutCreateWindow(argv[0]); + Win = glutCreateWindow(argv[0]); glutReshapeFunc( Reshape ); glutKeyboardFunc( Key ); glutDisplayFunc( Display ); diff --git a/src/mesa/drivers/dri/i965/brw_urb.c b/src/mesa/drivers/dri/i965/brw_urb.c index 79ff2b2d4db..64f5904ac68 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 68a75ec7f00..e01f56d99df 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 f531b54d115..c527677cd0c 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 4bc0ea14f81..14b0c6063b7 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); diff --git a/src/mesa/drivers/x11/xm_buffer.c b/src/mesa/drivers/x11/xm_buffer.c index c1fa23328f0..bb8fe31ce88 100644 --- a/src/mesa/drivers/x11/xm_buffer.c +++ b/src/mesa/drivers/x11/xm_buffer.c @@ -422,18 +422,6 @@ xmesa_delete_framebuffer(struct gl_framebuffer *fb) XMesaDestroyImage( b->rowimage ); } - /* Note that XMesaBuffer renderbuffers normally have a refcount of 2 - * (creation + binding) so we need to explicitly delete/unbind them here. - */ - if (b->frontxrb) { - _mesa_unreference_renderbuffer((struct gl_renderbuffer **) &b->frontxrb); - ASSERT(b->frontxrb == NULL); - } - if (b->backxrb) { - _mesa_unreference_renderbuffer((struct gl_renderbuffer **) &b->backxrb); - ASSERT(b->backxrb == NULL); - } - _mesa_free_framebuffer_data(fb); _mesa_free(fb); } diff --git a/src/mesa/main/api_loopback.c b/src/mesa/main/api_loopback.c index 717ef1fc8f0..efe5a77d581 100644 --- a/src/mesa/main/api_loopback.c +++ b/src/mesa/main/api_loopback.c @@ -146,7 +146,7 @@ static void GLAPIENTRY loopback_Color3iv_f( const GLint *v ) { COLORF( INT_TO_FLOAT(v[0]), INT_TO_FLOAT(v[1]), - INT_TO_FLOAT(v[2]), INT_TO_FLOAT(v[3]) ); + INT_TO_FLOAT(v[2]), 1.0 ); } static void GLAPIENTRY diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c index f7e870b49cd..fefa14e5036 100644 --- a/src/mesa/main/fbobject.c +++ b/src/mesa/main/fbobject.c @@ -559,7 +559,7 @@ _mesa_IsRenderbufferEXT(GLuint renderbuffer) void GLAPIENTRY _mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer) { - struct gl_renderbuffer *newRb, *oldRb; + struct gl_renderbuffer *newRb; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); @@ -593,21 +593,16 @@ _mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer) } ASSERT(newRb->AllocStorage); _mesa_HashInsert(ctx->Shared->RenderBuffers, renderbuffer, newRb); + newRb->RefCount = 1; /* referenced by hash table */ } - newRb->RefCount++; } else { newRb = NULL; } - oldRb = ctx->CurrentRenderbuffer; - if (oldRb) { - _mesa_unreference_renderbuffer(&oldRb); - } - ASSERT(newRb != &DummyRenderbuffer); - ctx->CurrentRenderbuffer = newRb; + _mesa_reference_renderbuffer(&ctx->CurrentRenderbuffer, newRb); } @@ -632,14 +627,15 @@ _mesa_DeleteRenderbuffersEXT(GLsizei n, const GLuint *renderbuffers) _mesa_BindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); } - /* remove from hash table immediately, to free the ID */ + /* Remove from hash table immediately, to free the ID. + * But the object will not be freed until it's no longer + * referenced anywhere else. + */ _mesa_HashRemove(ctx->Shared->RenderBuffers, renderbuffers[i]); if (rb != &DummyRenderbuffer) { - /* But the object will not be freed until it's no longer - * bound in any context. - */ - _mesa_unreference_renderbuffer(&rb); + /* no longer referenced by hash table */ + _mesa_reference_renderbuffer(&rb, NULL); } } } diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c index cd4f594aa29..1fd31a53211 100644 --- a/src/mesa/main/framebuffer.c +++ b/src/mesa/main/framebuffer.c @@ -70,42 +70,6 @@ compute_depth_max(struct gl_framebuffer *fb) /** - * Set the framebuffer's _DepthBuffer field, taking care of - * reference counts, etc. - */ -static void -set_depth_renderbuffer(struct gl_framebuffer *fb, - struct gl_renderbuffer *rb) -{ - if (fb->_DepthBuffer) { - _mesa_unreference_renderbuffer(&fb->_DepthBuffer); - } - fb->_DepthBuffer = rb; - if (rb) { - rb->RefCount++; - } -} - - -/** - * Set the framebuffer's _StencilBuffer field, taking care of - * reference counts, etc. - */ -static void -set_stencil_renderbuffer(struct gl_framebuffer *fb, - struct gl_renderbuffer *rb) -{ - if (fb->_StencilBuffer) { - _mesa_unreference_renderbuffer(&fb->_StencilBuffer); - } - fb->_StencilBuffer = rb; - if (rb) { - rb->RefCount++; - } -} - - -/** * Create and initialize a gl_framebuffer object. * This is intended for creating _window_system_ framebuffers, not generic * framebuffer objects ala GL_EXT_framebuffer_object. @@ -223,7 +187,7 @@ _mesa_free_framebuffer_data(struct gl_framebuffer *fb) for (i = 0; i < BUFFER_COUNT; i++) { struct gl_renderbuffer_attachment *att = &fb->Attachment[i]; if (att->Renderbuffer) { - _mesa_unreference_renderbuffer(&att->Renderbuffer); + _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); } if (att->Texture) { /* render to texture */ @@ -239,9 +203,9 @@ _mesa_free_framebuffer_data(struct gl_framebuffer *fb) att->Texture = NULL; } - /* unbind depth/stencil to decr ref counts */ - set_depth_renderbuffer(fb, NULL); - set_stencil_renderbuffer(fb, NULL); + /* unbind _Depth/_StencilBuffer to decr ref counts */ + _mesa_reference_renderbuffer(&fb->_DepthBuffer, NULL); + _mesa_reference_renderbuffer(&fb->_StencilBuffer, NULL); } @@ -569,13 +533,13 @@ _mesa_update_depth_buffer(GLcontext *ctx, /* need to update wrapper */ struct gl_renderbuffer *wrapper = _mesa_new_z24_renderbuffer_wrapper(ctx, depthRb); - set_depth_renderbuffer(fb, wrapper); + _mesa_reference_renderbuffer(&fb->_DepthBuffer, wrapper); ASSERT(fb->_DepthBuffer->Wrapped == depthRb); } } else { /* depthRb may be null */ - set_depth_renderbuffer(fb, depthRb); + _mesa_reference_renderbuffer(&fb->_DepthBuffer, depthRb); } } @@ -610,13 +574,13 @@ _mesa_update_stencil_buffer(GLcontext *ctx, /* need to update wrapper */ struct gl_renderbuffer *wrapper = _mesa_new_s8_renderbuffer_wrapper(ctx, stencilRb); - set_stencil_renderbuffer(fb, wrapper); + _mesa_reference_renderbuffer(&fb->_StencilBuffer, wrapper); ASSERT(fb->_StencilBuffer->Wrapped == stencilRb); } } else { /* stencilRb may be null */ - set_stencil_renderbuffer(fb, stencilRb); + _mesa_reference_renderbuffer(&fb->_StencilBuffer, stencilRb); } } diff --git a/src/mesa/main/rbadaptors.c b/src/mesa/main/rbadaptors.c index 60f4948becf..c1ac0606c86 100644 --- a/src/mesa/main/rbadaptors.c +++ b/src/mesa/main/rbadaptors.c @@ -45,7 +45,7 @@ Delete_wrapper(struct gl_renderbuffer *rb) /* Decrement reference count on the buffer we're wrapping and delete * it if refcount hits zero. */ - _mesa_unreference_renderbuffer(&rb->Wrapped); + _mesa_reference_renderbuffer(&rb->Wrapped, NULL); /* delete myself */ _mesa_delete_renderbuffer(rb); diff --git a/src/mesa/main/renderbuffer.c b/src/mesa/main/renderbuffer.c index ded0063c739..49706b52516 100644 --- a/src/mesa/main/renderbuffer.c +++ b/src/mesa/main/renderbuffer.c @@ -1473,7 +1473,7 @@ _mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name) rb->ClassID = 0; rb->Name = name; - rb->RefCount = 1; + rb->RefCount = 0; rb->Delete = _mesa_delete_renderbuffer; /* The rest of these should be set later by the caller of this function or @@ -2105,9 +2105,7 @@ _mesa_add_renderbuffer(struct gl_framebuffer *fb, fb->Attachment[bufferName].Type = GL_RENDERBUFFER_EXT; fb->Attachment[bufferName].Complete = GL_TRUE; - fb->Attachment[bufferName].Renderbuffer = rb; - - rb->RefCount++; + _mesa_reference_renderbuffer(&fb->Attachment[bufferName].Renderbuffer, rb); } @@ -2125,38 +2123,55 @@ _mesa_remove_renderbuffer(struct gl_framebuffer *fb, GLuint bufferName) if (!rb) return; - _mesa_unreference_renderbuffer(&rb); + _mesa_reference_renderbuffer(&rb, NULL); fb->Attachment[bufferName].Renderbuffer = NULL; } /** - * Decrement a renderbuffer object's reference count and delete it when - * the refcount hits zero. - * Note: we pass the address of a pointer. + * Set *ptr to point to rb. If *ptr points to another renderbuffer, + * dereference that buffer first. The new renderbuffer's refcount will + * be incremented. The old renderbuffer's refcount will be decremented. */ void -_mesa_unreference_renderbuffer(struct gl_renderbuffer **rb) +_mesa_reference_renderbuffer(struct gl_renderbuffer **ptr, + struct gl_renderbuffer *rb) { - assert(rb); - if (*rb) { + assert(ptr); + if (*ptr == rb) { + /* no change */ + return; + } + + if (*ptr) { + /* Unreference the old renderbuffer */ GLboolean deleteFlag = GL_FALSE; + struct gl_renderbuffer *oldRb = *ptr; - _glthread_LOCK_MUTEX((*rb)->Mutex); - ASSERT((*rb)->RefCount > 0); - (*rb)->RefCount--; - deleteFlag = ((*rb)->RefCount == 0); - _glthread_UNLOCK_MUTEX((*rb)->Mutex); + _glthread_LOCK_MUTEX(oldRb->Mutex); + ASSERT(oldRb->RefCount > 0); + oldRb->RefCount--; + /*printf("RB DECR %p to %d\n", (void*) oldRb, oldRb->RefCount);*/ + deleteFlag = (oldRb->RefCount == 0); + _glthread_UNLOCK_MUTEX(oldRb->Mutex); if (deleteFlag) - (*rb)->Delete(*rb); + oldRb->Delete(oldRb); - *rb = NULL; + *ptr = NULL; } -} - + assert(!*ptr); + if (rb) { + /* reference new renderbuffer */ + _glthread_LOCK_MUTEX(rb->Mutex); + rb->RefCount++; + /*printf("RB REF %p to %d\n", (void*)rb, rb->RefCount);*/ + _glthread_UNLOCK_MUTEX(rb->Mutex); + *ptr = rb; + } +} /** @@ -2180,4 +2195,3 @@ _mesa_new_depthstencil_renderbuffer(GLcontext *ctx, GLuint name) return dsrb; } - diff --git a/src/mesa/main/renderbuffer.h b/src/mesa/main/renderbuffer.h index e5f1147b4a6..c9bf8885487 100644 --- a/src/mesa/main/renderbuffer.h +++ b/src/mesa/main/renderbuffer.h @@ -102,7 +102,8 @@ extern void _mesa_remove_renderbuffer(struct gl_framebuffer *fb, GLuint bufferName); extern void -_mesa_unreference_renderbuffer(struct gl_renderbuffer **rb); +_mesa_reference_renderbuffer(struct gl_renderbuffer **ptr, + struct gl_renderbuffer *rb); extern struct gl_renderbuffer * _mesa_new_depthstencil_renderbuffer(GLcontext *ctx, GLuint name); |