forums.ps2dev.org Forum Index forums.ps2dev.org
Homebrew PS2, PSP & PS3 Development Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Swizzling DXT1

 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development
View previous topic :: View next topic  
Author Message
ACh



Joined: 03 Jun 2007
Posts: 3

PostPosted: Sat Aug 04, 2007 12:02 am    Post subject: Swizzling DXT1 Reply with quote

I wasn't able to find any mention in the forum of getting this working; apologies if this is already known.

It looks like it is in fact possible to use DXT1 compressed textures in swizzled mode. When reading from swizzled DXT1, the GE reads 32 bytes of data (presumably since 4bpp in DXT1 expands to 16bpp uncompressed, giving the 128-byte swizzle block). The 4x4 pixel blocks are rearranged in the same manner as for uncompressed 16-bit textures, 8 pixels across by 8 down; so if you have a 32x8 texture (00, 01 etc. represent 4x4 pixel blocks):

Code:
00 01 02 03 04 05 06 07
10 11 12 13 14 15 16 17


the data would be swizzled as:

Code:
00 01 10 11 02 03 12 13 04 05 14 15 06 07 16 17


The trick, however, is that while the GE only reads 32 bytes, it advances its internal pointer 128 bytes (just as for uncompressed reads), so you have to leave 96 bytes of space between each 32-byte swizzled block--and you lose all the space you gained from compression.

If you're clever, you can interleave two textures within the same memory block (only two, since the GE requires 64-byte texture alignment):

Code:
00 01 02 03 04 05 06 07 | AA AB AC AD AE AF AG AH
10 11 12 13 14 15 16 17 | BA BB BC BD BE BF BG BH
20 21 22 23 24 25 26 27 | CA CB CC CD CE CF CG CH
30 31 32 33 34 35 36 37 | DA DB DC DD DE DF DG DH
--- becomes ---
00 01 10 11 .. .. .. .. AA AB BA BB .. .. .. .. 02 03 12 13 .. .. .. .. AC AD BC BD .. .. .. ..
04 05 14 15 .. .. .. .. AE AF BE BF .. .. .. .. 06 07 16 17 .. .. .. .. AG AH BG BH .. .. .. ..
20 21 30 31 .. .. .. .. CA CB DA DB .. .. .. .. 22 23 32 33 .. .. .. .. CC CD DC DD .. .. .. ..
24 25 34 35 .. .. .. .. CE CF DE DF .. .. .. .. 26 27 36 37 .. .. .. .. CG CH DG DH .. .. .. ..


Or, if the texture is no more than 32 pixels high, you can even interleave its own rows in the empty space, and set the texture stride to 4 pixels:

Code:
00 01 02 03 04 05 06 07
10 11 12 13 14 15 16 17
20 21 22 23 24 25 26 27
30 31 32 33 34 35 36 37
40 41 42 43 44 45 46 47
50 51 52 53 54 55 56 57
60 61 62 63 64 65 66 67
70 71 72 73 74 75 76 77
--- becomes ---
00 01 10 11 20 21 30 31 40 41 50 51 60 61 70 71
02 03 12 13 22 23 32 33 42 43 52 53 62 63 72 73
04 05 14 15 24 25 34 35 44 45 54 55 64 65 74 75
06 07 16 17 26 27 36 37 46 47 56 57 66 67 76 77


However, swizzling only seems to give a marginal speedup; in my tests, swizzled DXT1 was about 10% faster than unswizzled, and 40-50% slower than swizzled 16-bit (5551) textures. So there's probably not much use for it; if you need the memory, go with unswizzled DXT1, and if you want speed, go with uncompressed textures.

FWIW, here's the code I use to swizzle:

Code:

void swizzle_texture(const void * const src, void * const dest,
                     const int width, const int height, const int format)
{
    // ...
    if (format == GU_PSM_DXT1) {
        // Note: the following assumes width%8 == 0
        const int wblocks = width/8;
        const int hblocks = (height+7)/8;
        const uint8_t *sbase = (const uint8_t *)src;
        uint32_t *dptr = (uint32_t *)dest;
        int yblock;
        for (yblock = 0; yblock < hblocks; yblock++, sbase += 2*(width*2)) {
            const uint32_t *sptr0 = (const uint32_t *) sbase;
            const uint32_t *sptr1 = (const uint32_t *)(sbase + width*2);
            int xblock;
            for (xblock = 0; xblock < wblocks;
                 xblock++, sptr0 += 4, sptr1 += 4, dptr += 32
            ) {
                dptr[0] = sptr0[1];  // Swap words for the PSP
                dptr[1] = sptr0[0];
                dptr[2] = sptr0[3];
                dptr[3] = sptr0[2];
                dptr[4] = sptr1[1];
                dptr[5] = sptr1[0];
                dptr[6] = sptr1[3];
                dptr[7] = sptr1[2];
            }
            if (height <= 32) {
                dptr -= (32*wblocks) - 8;  // Interleave rows
            }
        }
    }  // if (format == GU_PSM_DXT1)
}
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development All times are GMT + 10 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group