Search
lxdream.org :: lxdream :: r224:289ddaeeebb3
lxdream 0.9.1
released Jun 29
Download Now
changeset224:289ddaeeebb3
parent223:f6c28fa9076b
child225:e5cea6125580
authornkeynes
dateTue Sep 12 13:33:18 2006 +0000 (14 years ago)
Bug #0002 Implement VQ compression
Implemented based on KOS code.
src/pvr2/texcache.c
1.1 --- a/src/pvr2/texcache.c Tue Sep 12 12:16:36 2006 +0000
1.2 +++ b/src/pvr2/texcache.c Tue Sep 12 13:33:18 2006 +0000
1.3 @@ -1,5 +1,5 @@
1.4 /**
1.5 - * $Id: texcache.c,v 1.7 2006-08-02 06:24:08 nkeynes Exp $
1.6 + * $Id: texcache.c,v 1.8 2006-09-12 13:33:18 nkeynes Exp $
1.7 *
1.8 * Texture cache. Responsible for maintaining a working set of OpenGL
1.9 * textures.
1.10 @@ -221,6 +221,59 @@
1.11 }
1.12 }
1.13
1.14 +#define VQ_CODEBOOK_SIZE 2048 /* 256 entries * 4 pixels per quad * 2 byte pixels */
1.15 +
1.16 +struct vq_codebook {
1.17 + uint16_t quad[256][4];
1.18 +};
1.19 +
1.20 +static void detwiddle_vq_to_16(int x1, int y1, int size, int totsize,
1.21 + uint8_t **in, uint16_t *out, struct vq_codebook *codebook ) {
1.22 + if( size == 2 ) {
1.23 + uint8_t code = **in;
1.24 + (*in)++;
1.25 + out[y1 * totsize + x1] = codebook->quad[code][0];
1.26 + out[y1 * totsize + x1 + 1] = codebook->quad[code][1];
1.27 + out[(y1+1) * totsize + x1] = codebook->quad[code][2];
1.28 + out[(y1+1) * totsize + x1 + 1] = codebook->quad[code][3];
1.29 + } else {
1.30 + int ns = size>>1;
1.31 + detwiddle_vq_to_16(x1, y1, ns, totsize, in, out, codebook);
1.32 + detwiddle_vq_to_16(x1, y1+ns, ns, totsize, in, out, codebook);
1.33 + detwiddle_vq_to_16(x1+ns, y1, ns, totsize, in, out, codebook);
1.34 + detwiddle_vq_to_16(x1+ns, y1+ns, ns, totsize, in, out, codebook);
1.35 + }
1.36 +}
1.37 +
1.38 +static void vq_decode( int width, int height, char *input, uint16_t *output,
1.39 + int twiddled ) {
1.40 + struct vq_codebook codebook;
1.41 + int i,j;
1.42 +
1.43 + /* Detwiddle the codebook, for the sake of my own sanity if nothing else */
1.44 + uint16_t *p = (uint16_t *)input;
1.45 + for( i=0; i<256; i++ ) {
1.46 + codebook.quad[i][0] = *p++;
1.47 + codebook.quad[i][2] = *p++;
1.48 + codebook.quad[i][1] = *p++;
1.49 + codebook.quad[i][3] = *p++;
1.50 + }
1.51 +
1.52 + uint8_t *c = (uint8_t *)p;
1.53 + if( twiddled ) {
1.54 + detwiddle_vq_to_16( 0, 0, width, width, &c, output, &codebook );
1.55 + } else {
1.56 + for( j=0; j<height; j+=2 ) {
1.57 + for( i=0; i<width; i+=2 ) {
1.58 + uint8_t code = *c;
1.59 + output[i + j*width] = codebook.quad[code][0];
1.60 + output[i + 1 + j*width] = codebook.quad[code][1];
1.61 + output[i + (j+1)*width] = codebook.quad[code][2];
1.62 + output[i + 1 + (j+1)*width] = codebook.quad[code][3];
1.63 + }
1.64 + }
1.65 + }
1.66 +}
1.67
1.68 /**
1.69 * Load texture data from the given address and parameters into the currently
1.70 @@ -326,17 +379,19 @@
1.71 char data[bytes];
1.72 /* load data from image, detwiddling/uncompressing as required */
1.73 if( PVR2_TEX_IS_COMPRESSED(mode) ) {
1.74 - ERROR( "VQ Compression not supported" );
1.75 + int inputlength = VQ_CODEBOOK_SIZE +
1.76 + ((width*height) >> 2); /* + mip maps */
1.77 + char tmp[bytes];
1.78 + pvr2_vram64_read( tmp, texture_addr, inputlength );
1.79 + vq_decode( width, height, tmp, (uint16_t *)&data, PVR2_TEX_IS_TWIDDLED(mode) );
1.80 + } else if( PVR2_TEX_IS_TWIDDLED(mode) ) {
1.81 + char tmp[bytes];
1.82 + uint16_t *p = (uint16_t *)tmp;
1.83 + pvr2_vram64_read( tmp, texture_addr, bytes );
1.84 + /* Untwiddle */
1.85 + detwiddle_16_to_16( 0, 0, width, width, &p, (uint16_t *)&data );
1.86 } else {
1.87 - if( PVR2_TEX_IS_TWIDDLED(mode) ) {
1.88 - char tmp[bytes];
1.89 - uint16_t *p = (uint16_t *)tmp;
1.90 - pvr2_vram64_read( tmp, texture_addr, bytes );
1.91 - /* Untwiddle */
1.92 - detwiddle_16_to_16( 0, 0, width, width, &p, (uint16_t *)&data );
1.93 - } else {
1.94 - pvr2_vram64_read( data, texture_addr, bytes );
1.95 - }
1.96 + pvr2_vram64_read( data, texture_addr, bytes );
1.97 }
1.98
1.99 /* Pass to GL */
.