--- a/src/pvr2/texcache.c Thu May 29 10:50:25 2008 +0000 +++ b/src/pvr2/texcache.c Mon Jul 14 07:44:42 2008 +0000 @@ -64,12 +64,12 @@ { int i; for( i=0; i> 12; texcache_entry_index idx = texcache_page_lookup[texture_page]; if( idx == EMPTY_ENTRY ) - return; + return; assert( texcache_free_ptr >= 0 ); do { - texcache_entry_t entry = &texcache_active_list[idx]; - entry->texture_addr = -1; - /* release entry */ - texcache_free_ptr--; - texcache_free_list[texcache_free_ptr] = idx; - idx = entry->next; - entry->next = EMPTY_ENTRY; + texcache_entry_t entry = &texcache_active_list[idx]; + entry->texture_addr = -1; + /* release entry */ + texcache_free_ptr--; + texcache_free_list[texcache_free_ptr] = idx; + idx = entry->next; + entry->next = EMPTY_ENTRY; } while( idx != EMPTY_ENTRY ); texcache_page_lookup[texture_page] = EMPTY_ENTRY; } @@ -203,12 +203,12 @@ { int i; for( i=0; i> 4)]; - in++; + *out++ = pal[*in & 0x0F]; + *out++ = pal[(*in >> 4)]; + in++; } } @@ -243,9 +243,9 @@ { int i; for( i=0; i> 4)]; - in++; + *out++ = (uint16_t)pal[*in & 0x0F]; + *out++ = (uint16_t)pal[(*in >> 4)]; + in++; } } @@ -256,32 +256,32 @@ }; static void vq_get_codebook( struct vq_codebook *codebook, - uint16_t *input ) + uint16_t *input ) { /* Detwiddle the codebook, for the sake of my own sanity if nothing else */ uint16_t *p = (uint16_t *)input; int i; for( i=0; i<256; i++ ) { - codebook->quad[i][0] = *p++; - codebook->quad[i][2] = *p++; - codebook->quad[i][1] = *p++; - codebook->quad[i][3] = *p++; + codebook->quad[i][0] = *p++; + codebook->quad[i][2] = *p++; + codebook->quad[i][1] = *p++; + codebook->quad[i][3] = *p++; } } static void vq_decode( uint16_t *output, unsigned char *input, int width, int height, - struct vq_codebook *codebook ) { + struct vq_codebook *codebook ) { int i,j; - + uint8_t *c = (uint8_t *)input; for( j=0; jquad[code][0]; - output[i + 1 + j*width] = codebook->quad[code][1]; - output[i + (j+1)*width] = codebook->quad[code][2]; - output[i + 1 + (j+1)*width] = codebook->quad[code][3]; - } + for( i=0; iquad[code][0]; + output[i + 1 + j*width] = codebook->quad[code][1]; + output[i + (j+1)*width] = codebook->quad[code][2]; + output[i + 1 + (j+1)*width] = codebook->quad[code][3]; + } } } @@ -310,15 +310,15 @@ int x, y; uint32_t *p = input; for( y=0; y>8)&0xFF ); - float v = (float)( (*p>>16)&0xFF ); - float y1 = (float)( (*p>>24)&0xFF ); - *output++ = yuv_to_rgb32( y0, u, v ); - *output++ = yuv_to_rgb32( y1, u, v ); - p++; - } + for( x=0; x>8)&0xFF ); + float v = (float)( (*p>>16)&0xFF ); + float y1 = (float)( (*p>>24)&0xFF ); + *output++ = yuv_to_rgb32( y0, u, v ); + *output++ = yuv_to_rgb32( y1, u, v ); + p++; + } } } @@ -327,7 +327,7 @@ * bound OpenGL texture. */ static void texcache_load_texture( uint32_t texture_addr, int width, int height, - int mode ) { + int mode ) { int bpp_shift = 1; /* bytes per (output) pixel as a power of 2 */ GLint intFormat = GL_RGBA, format, type; int tex_format = mode & PVR2_TEX_FORMAT_MASK; @@ -340,179 +340,179 @@ switch( tex_format ) { case PVR2_TEX_FORMAT_IDX4: case PVR2_TEX_FORMAT_IDX8: - /* For indexed-colour modes, we need to lookup the palette control - * word to determine the de-indexed texture format. - */ - switch( MMIO_READ( PVR2, RENDER_PALETTE ) & 0x03 ) { - case 0: /* ARGB1555 */ - format = GL_BGRA; - type = GL_UNSIGNED_SHORT_1_5_5_5_REV; - break; - case 1: /* RGB565 */ - intFormat = GL_RGB; - format = GL_RGB; - type = GL_UNSIGNED_SHORT_5_6_5; - break; - case 2: /* ARGB4444 */ - format = GL_BGRA; - type = GL_UNSIGNED_SHORT_4_4_4_4_REV; - break; - case 3: /* ARGB8888 */ - format = GL_BGRA; - type = GL_UNSIGNED_BYTE; - bpp_shift = 2; - break; - default: - return; /* Can't happen, but it makes gcc stop complaining */ - } - break; - - case PVR2_TEX_FORMAT_ARGB1555: - format = GL_BGRA; - type = GL_UNSIGNED_SHORT_1_5_5_5_REV; - break; - case PVR2_TEX_FORMAT_RGB565: - intFormat = GL_RGB; - format = GL_RGB; - type = GL_UNSIGNED_SHORT_5_6_5; - break; - case PVR2_TEX_FORMAT_ARGB4444: - format = GL_BGRA; - type = GL_UNSIGNED_SHORT_4_4_4_4_REV; - break; - case PVR2_TEX_FORMAT_YUV422: - /* YUV422 isn't directly supported by most implementations, so decode - * it to a (reasonably) standard ARGB32. - */ - bpp_shift = 2; - format = GL_BGRA; - type = GL_UNSIGNED_BYTE; - break; - case PVR2_TEX_FORMAT_BUMPMAP: - ERROR( "Bumpmap not supported" ); - return; - default: - ERROR( "Undefined texture format" ); - return; + /* For indexed-colour modes, we need to lookup the palette control + * word to determine the de-indexed texture format. + */ + switch( MMIO_READ( PVR2, RENDER_PALETTE ) & 0x03 ) { + case 0: /* ARGB1555 */ + format = GL_BGRA; + type = GL_UNSIGNED_SHORT_1_5_5_5_REV; + break; + case 1: /* RGB565 */ + intFormat = GL_RGB; + format = GL_RGB; + type = GL_UNSIGNED_SHORT_5_6_5; + break; + case 2: /* ARGB4444 */ + format = GL_BGRA; + type = GL_UNSIGNED_SHORT_4_4_4_4_REV; + break; + case 3: /* ARGB8888 */ + format = GL_BGRA; + type = GL_UNSIGNED_BYTE; + bpp_shift = 2; + break; + default: + return; /* Can't happen, but it makes gcc stop complaining */ + } + break; + + case PVR2_TEX_FORMAT_ARGB1555: + format = GL_BGRA; + type = GL_UNSIGNED_SHORT_1_5_5_5_REV; + break; + case PVR2_TEX_FORMAT_RGB565: + intFormat = GL_RGB; + format = GL_RGB; + type = GL_UNSIGNED_SHORT_5_6_5; + break; + case PVR2_TEX_FORMAT_ARGB4444: + format = GL_BGRA; + type = GL_UNSIGNED_SHORT_4_4_4_4_REV; + break; + case PVR2_TEX_FORMAT_YUV422: + /* YUV422 isn't directly supported by most implementations, so decode + * it to a (reasonably) standard ARGB32. + */ + bpp_shift = 2; + format = GL_BGRA; + type = GL_UNSIGNED_BYTE; + break; + case PVR2_TEX_FORMAT_BUMPMAP: + ERROR( "Bumpmap not supported" ); + return; + default: + ERROR( "Undefined texture format" ); + return; } - + if( PVR2_TEX_IS_STRIDE(mode) && tex_format != PVR2_TEX_FORMAT_IDX4 && - tex_format != PVR2_TEX_FORMAT_IDX8 ) { - /* Stride textures cannot be mip-mapped, compressed, indexed or twiddled */ - uint32_t stride = (MMIO_READ( PVR2, RENDER_TEXSIZE ) & 0x003F) << 5; - unsigned char data[(width*height) << bpp_shift]; - if( tex_format == PVR2_TEX_FORMAT_YUV422 ) { - unsigned char tmp[(width*height)<<1]; - pvr2_vram64_read_stride( tmp, width<<1, texture_addr, stride<<1, height ); - yuv_decode( (uint32_t *)data, (uint32_t *)tmp, width, height ); - } else { - pvr2_vram64_read_stride( data, width<>last_level)*(width>>last_level)); - } - if( width != 1 ) { - src_offset += 3; - } - if( PVR2_TEX_IS_COMPRESSED(mode) ) { - src_offset >>= 2; - } else if( tex_format == PVR2_TEX_FORMAT_IDX4 ) { - src_offset >>= 1; - } else if( tex_format == PVR2_TEX_FORMAT_YUV422 ) { - src_offset <<= 1; - } else if( tex_format != PVR2_TEX_FORMAT_IDX8 ) { - src_offset <<= bpp_shift; - } - texture_addr += src_offset; + uint32_t src_offset = 0; + filter = GL_LINEAR_MIPMAP_LINEAR; + mip_height = height = width; + while( (1<>last_level)*(width>>last_level)); + } + if( width != 1 ) { + src_offset += 3; + } + if( PVR2_TEX_IS_COMPRESSED(mode) ) { + src_offset >>= 2; + } else if( tex_format == PVR2_TEX_FORMAT_IDX4 ) { + src_offset >>= 1; + } else if( tex_format == PVR2_TEX_FORMAT_YUV422 ) { + src_offset <<= 1; + } else if( tex_format != PVR2_TEX_FORMAT_IDX8 ) { + src_offset <<= bpp_shift; + } + texture_addr += src_offset; } - + dest_bytes = (mip_width * mip_height) << bpp_shift; src_bytes = dest_bytes; // Modes will change this (below) for( level=0; level<= last_level; level++ ) { - unsigned char data[dest_bytes]; - /* load data from image, detwiddling/uncompressing as required */ - if( tex_format == PVR2_TEX_FORMAT_IDX8 ) { - src_bytes = (mip_width * mip_height); - int bank = (mode >> 25) &0x03; - uint32_t *palette = ((uint32_t *)mmio_region_PVR2PAL.mem) + (bank<<8); - unsigned char tmp[src_bytes]; - pvr2_vram64_read_twiddled_8( tmp, texture_addr, mip_width, mip_height ); - if( bpp_shift == 2 ) { - decode_pal8_to_32( (uint32_t *)data, tmp, src_bytes, palette ); - } else { - decode_pal8_to_16( (uint16_t *)data, tmp, src_bytes, palette ); - } - } else if( tex_format == PVR2_TEX_FORMAT_IDX4 ) { - src_bytes = (mip_width * mip_height) >> 1; - int bank = (mode >>21 ) & 0x3F; - uint32_t *palette = ((uint32_t *)mmio_region_PVR2PAL.mem) + (bank<<4); - unsigned char tmp[src_bytes]; - pvr2_vram64_read_twiddled_4( tmp, texture_addr, mip_width, mip_height ); - if( bpp_shift == 2 ) { - decode_pal4_to_32( (uint32_t *)data, tmp, src_bytes, palette ); - } else { - decode_pal4_to_16( (uint16_t *)data, tmp, src_bytes, palette ); - } - } else if( tex_format == PVR2_TEX_FORMAT_YUV422 ) { - src_bytes = ((mip_width*mip_height)<<1); - unsigned char tmp[src_bytes]; - if( PVR2_TEX_IS_TWIDDLED(mode) ) { - pvr2_vram64_read_twiddled_16( tmp, texture_addr, mip_width, mip_height ); - } else { - pvr2_vram64_read( tmp, texture_addr, src_bytes ); - } - yuv_decode( (uint32_t *)data, (uint32_t *)tmp, mip_width, mip_height ); - } else if( PVR2_TEX_IS_COMPRESSED(mode) ) { - src_bytes = ((mip_width*mip_height) >> 2); - unsigned char tmp[src_bytes]; - if( PVR2_TEX_IS_TWIDDLED(mode) ) { - pvr2_vram64_read_twiddled_8( tmp, texture_addr, mip_width>>1, mip_height>>1 ); - } else { - pvr2_vram64_read( tmp, texture_addr, src_bytes ); - } - vq_decode( (uint16_t *)data, tmp, mip_width, mip_height, &codebook ); - } else if( PVR2_TEX_IS_TWIDDLED(mode) ) { - pvr2_vram64_read_twiddled_16( data, texture_addr, mip_width, mip_height ); - } else { - pvr2_vram64_read( data, texture_addr, src_bytes ); - } - - /* Pass to GL */ - if( level == last_level && level != 0 ) { /* 1x1 stored within a 2x2 */ - glTexImage2D( GL_TEXTURE_2D, level, intFormat, 1, 1, 0, format, type, - data + (3 << bpp_shift) ); - } else { - glTexImage2D( GL_TEXTURE_2D, level, intFormat, mip_width, mip_height, 0, format, type, - data ); - if( mip_width > 2 ) { - mip_width >>= 1; - mip_height >>= 1; - dest_bytes >>= 2; - src_bytes >>= 2; - } - texture_addr -= src_bytes; - } + unsigned char data[dest_bytes]; + /* load data from image, detwiddling/uncompressing as required */ + if( tex_format == PVR2_TEX_FORMAT_IDX8 ) { + src_bytes = (mip_width * mip_height); + int bank = (mode >> 25) &0x03; + uint32_t *palette = ((uint32_t *)mmio_region_PVR2PAL.mem) + (bank<<8); + unsigned char tmp[src_bytes]; + pvr2_vram64_read_twiddled_8( tmp, texture_addr, mip_width, mip_height ); + if( bpp_shift == 2 ) { + decode_pal8_to_32( (uint32_t *)data, tmp, src_bytes, palette ); + } else { + decode_pal8_to_16( (uint16_t *)data, tmp, src_bytes, palette ); + } + } else if( tex_format == PVR2_TEX_FORMAT_IDX4 ) { + src_bytes = (mip_width * mip_height) >> 1; + int bank = (mode >>21 ) & 0x3F; + uint32_t *palette = ((uint32_t *)mmio_region_PVR2PAL.mem) + (bank<<4); + unsigned char tmp[src_bytes]; + pvr2_vram64_read_twiddled_4( tmp, texture_addr, mip_width, mip_height ); + if( bpp_shift == 2 ) { + decode_pal4_to_32( (uint32_t *)data, tmp, src_bytes, palette ); + } else { + decode_pal4_to_16( (uint16_t *)data, tmp, src_bytes, palette ); + } + } else if( tex_format == PVR2_TEX_FORMAT_YUV422 ) { + src_bytes = ((mip_width*mip_height)<<1); + unsigned char tmp[src_bytes]; + if( PVR2_TEX_IS_TWIDDLED(mode) ) { + pvr2_vram64_read_twiddled_16( tmp, texture_addr, mip_width, mip_height ); + } else { + pvr2_vram64_read( tmp, texture_addr, src_bytes ); + } + yuv_decode( (uint32_t *)data, (uint32_t *)tmp, mip_width, mip_height ); + } else if( PVR2_TEX_IS_COMPRESSED(mode) ) { + src_bytes = ((mip_width*mip_height) >> 2); + unsigned char tmp[src_bytes]; + if( PVR2_TEX_IS_TWIDDLED(mode) ) { + pvr2_vram64_read_twiddled_8( tmp, texture_addr, mip_width>>1, mip_height>>1 ); + } else { + pvr2_vram64_read( tmp, texture_addr, src_bytes ); + } + vq_decode( (uint16_t *)data, tmp, mip_width, mip_height, &codebook ); + } else if( PVR2_TEX_IS_TWIDDLED(mode) ) { + pvr2_vram64_read_twiddled_16( data, texture_addr, mip_width, mip_height ); + } else { + pvr2_vram64_read( data, texture_addr, src_bytes ); + } + + /* Pass to GL */ + if( level == last_level && level != 0 ) { /* 1x1 stored within a 2x2 */ + glTexImage2D( GL_TEXTURE_2D, level, intFormat, 1, 1, 0, format, type, + data + (3 << bpp_shift) ); + } else { + glTexImage2D( GL_TEXTURE_2D, level, intFormat, mip_width, mip_height, 0, format, type, + data ); + if( mip_width > 2 ) { + mip_width >>= 1; + mip_height >>= 1; + dest_bytes >>= 2; + src_bytes >>= 2; + } + texture_addr -= src_bytes; + } } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); @@ -536,25 +536,25 @@ texcache_entry_index next; texcache_entry_index idx = texcache_page_lookup[texture_page]; while( idx != EMPTY_ENTRY ) { - texcache_entry_t entry = &texcache_active_list[idx]; - if( entry->texture_addr == texture_addr && - entry->mode == texture_word && - entry->width == width && - entry->height == height ) { - entry->lru_count = texcache_ref_counter++; - return entry->texture_id; - } + texcache_entry_t entry = &texcache_active_list[idx]; + if( entry->texture_addr == texture_addr && + entry->mode == texture_word && + entry->width == width && + entry->height == height ) { + entry->lru_count = texcache_ref_counter++; + return entry->texture_id; + } idx = entry->next; } - + /* Not found - check the free list */ texcache_entry_index slot = 0; if( texcache_free_ptr < MAX_TEXTURES ) { - slot = texcache_free_list[texcache_free_ptr++]; + slot = texcache_free_list[texcache_free_ptr++]; } else { - slot = texcache_evict_lru(); + slot = texcache_evict_lru(); } /* Construct new entry */ @@ -567,14 +567,14 @@ /* Add entry to the lookup table */ next = texcache_page_lookup[texture_page]; if( next == slot ) { - int i; - fprintf( stderr, "Active list: " ); - for( i=0; i> 12) == i ); - slot_found[slot] = 2; - slot = texcache_active_list[slot].next; - } + int slot = texcache_page_lookup[i]; + while( slot != EMPTY_ENTRY ) { + assert( slot_found[slot] == 0 ); + assert( (texcache_active_list[slot].texture_addr >> 12) == i ); + slot_found[slot] = 2; + slot = texcache_active_list[slot].next; + } } /* Make sure we didn't miss any entries */ for( i=0; i