Texture compression size comparison study

If you have any questions on programming, this is the place to ask them, whether you're a newbie or an experienced programmer. Discussion on programming in general is also welcome. We will help you with programming homework, but we will not do your work for you! Any porting requests must be made in Developmental Ideas.
User avatar
bogglez
Moderator
Moderator
Posts: 576
Joined: Sun Apr 20, 2014 9:45 am
Has liked: 0
Been liked: 0

Texture compression size comparison study

Post by bogglez » Sat Nov 01, 2014 9:24 am

Hey everyone,

I just tried to find out how much of an advantage VQ compressed textures give over uncompressed textures in VRAM and on disc. Just sharing my findings here, in case anybody else wondered.

What I did:
1. Downloaded a mesh from Dead or Alive 4 of the character Kokoro.
2. Converted the DDS textures to TGA and PNG. PNGs were optimized with optipng. The TGA corresponds to the size of an uncompressed texture in VRAM.
3. Converted to twiddled, mip-mapped, VQ-compressed KMGs with color format ARGB1555, ARGB4444 or RGB565, depending on how much transparency was required. I don't know whether the DDS files contain mipmaps.
4. I also added the size of gzipped KMGs to see how much disc space can be saved here (faster load times and more stuff on disc).

Issue at step 3: the non-RGB565 textures have non-square sizes such as 256x128, so I couldn't compare the size. Does VQ/Twiddling really limit to square textures and not just power of two in each dimension?

Anyway, results I got so far:

Code: Select all

for i in *.kmg; do N=$(basename $i .kmg); file $N.png; du -sh $N.tga $N.png $N.dds $N.kmg $N.kmg.gz;echo ""; done
cloth3.png: PNG image data, 256 x 256, 8-bit/color RGB, non-interlaced
196K	cloth3.tga
48K	cloth3.png
36K	cloth3.dds
24K	cloth3.kmg
20K	cloth3.kmg.gz

eye.png: PNG image data, 512 x 512, 8-bit/color RGB, non-interlaced
772K	eye.tga
144K	eye.png
132K	eye.dds
88K	eye.kmg
48K	eye.kmg.gz

face.png: PNG image data, 1024 x 1024, 8-bit/color RGB, non-interlaced
3.1M	face.tga
304K	face.png
516K	face.dds
344K	face.kmg
108K	face.kmg.gz

gradient.png: PNG image data, 512 x 512, 8-bit/color RGB, non-interlaced
772K	gradient.tga
152K	gradient.png
du: cannot access ‘gradient.dds’: No such file or directory
88K	gradient.kmg
68K	gradient.kmg.gz

hands.png: PNG image data, 256 x 256, 8-bit/color RGB, non-interlaced
196K	hands.tga
24K	hands.png
36K	hands.dds
24K	hands.kmg
16K	hands.kmg.gz

jewel.png: PNG image data, 128 x 128, 8-bit/color RGB, non-interlaced
52K	jewel.tga
12K	jewel.png
12K	jewel.dds
8.0K	jewel.kmg
8.0K	jewel.kmg.gz

lips.png: PNG image data, 128 x 128, 8-bit/color RGB, non-interlaced
52K	lips.tga
16K	lips.png
12K	lips.dds
8.0K	lips.kmg
8.0K	lips.kmg.gz

sash.png: PNG image data, 512 x 512, 8-bit/color RGB, non-interlaced
772K	sash.tga
216K	sash.png
132K	sash.dds
88K	sash.kmg
56K	sash.kmg.gz
Attachments
libgl15_2014-11-01_kokoro.png
Wiki & tutorials: http://dcemulation.org/?title=Development
Wiki feedback: viewtopic.php?f=29&t=103940
My libgl playground (not for production): https://bitbucket.org/bogglez/libgl15
My lxdream fork (with small fixes): https://bitbucket.org/bogglez/lxdream
Tvspelsfreak
Team Screamcast
Team Screamcast
Posts: 144
Joined: Tue Dec 23, 2003 6:04 pm
Location: Umeå, Sweden
Has liked: 0
Been liked: 0
Contact:

Re: Texture compression size comparison study

Post by Tvspelsfreak » Sat Nov 01, 2014 8:49 pm

Hey,

The VQ compression ratio is fixed at 1/8th of the uncompressed size, plus a 2kB overhead for the codebook.
Any texture format supported by the PVR2DC can also utilize VQ compression.

So in the end, the compressed sizes are:
(num_pixels / 4 + 2048) for 16BPP images (RGB565, ARGB1555, ARGB4444, YUV422 and normal maps)
(num_pixels / 8 + 2048) for 8-bit paletted images
(num_pixels / 16 + 2048) for 4-bit paletted images
...where num_pixels is the total number of pixels in the texture, including mipmaps.

It's not worth compressing really small textures due to the fixed 2kB overhead unless you pack several of them together.
Meanwhile, the max compression ratio is ~31x on a 1024x1024 4-bit paletted texture with mipmaps.

Check out my sig for more info.
https://github.com/tvspelsfreak/texconv - Converts images into any texture format supported on the DC.
User avatar
bogglez
Moderator
Moderator
Posts: 576
Joined: Sun Apr 20, 2014 9:45 am
Has liked: 0
Been liked: 0

Re: Texture compression size comparison study

Post by bogglez » Sun Nov 02, 2014 6:38 am

Tvspelsfreak wrote:Hey,

The VQ compression ratio is fixed at 1/8th of the uncompressed size, plus a 2kB overhead for the codebook.
Any texture format supported by the PVR2DC can also utilize VQ compression.

So in the end, the compressed sizes are:
(num_pixels / 4 + 2048) for 16BPP images (RGB565, ARGB1555, ARGB4444, YUV422 and normal maps)
(num_pixels / 8 + 2048) for 8-bit paletted images
(num_pixels / 16 + 2048) for 4-bit paletted images
...where num_pixels is the total number of pixels in the texture, including mipmaps.

It's not worth compressing really small textures due to the fixed 2kB overhead unless you pack several of them together.
Meanwhile, the max compression ratio is ~31x on a 1024x1024 4-bit paletted texture with mipmaps.

Check out my sig for more info.
Thanks for the info!
I wasn't so sure about RGBA because that's basically Voronoi on 4 dimensions and less 4D vectors can be stored in the fixed codebook size compared to 3D vectors. But I guess that just means more quality degradation.

Why can VQ compression not be used with non-square images though?
Are there any quality differences between your tool and the one in KOS?
Wiki & tutorials: http://dcemulation.org/?title=Development
Wiki feedback: viewtopic.php?f=29&t=103940
My libgl playground (not for production): https://bitbucket.org/bogglez/libgl15
My lxdream fork (with small fixes): https://bitbucket.org/bogglez/lxdream
Tvspelsfreak
Team Screamcast
Team Screamcast
Posts: 144
Joined: Tue Dec 23, 2003 6:04 pm
Location: Umeå, Sweden
Has liked: 0
Been liked: 0
Contact:

Re: Texture compression size comparison study

Post by Tvspelsfreak » Sun Nov 02, 2014 11:16 am

bogglez wrote:Why can VQ compression not be used with non-square images though?
I don't think I've ever tried doing VQ compression on rectangular images. All sources say they need to be square. But then again, they also say paletted textures can't be compressed. I might try out that later.
bogglez wrote:Are there any quality differences between your tool and the one in KOS?
It's been a while since I've looked at the codebase, so don't quote me on this. But IIRC, vqenc is missing a "place" after the final codebook split, which is needed in order to calculate the new code vector (avg of all vectors using that code) after a split.
vqenc doesn't do much about unused codes either.
I also do a pre-pass for 16BPP images where I check if the source images contain <=256 unique quads. If they do, you're guaranteed "lossless" compression (it'll still be downgraded to 16BPP).

Let me know if you find any issues though. I'm always up for improving the tool.
https://github.com/tvspelsfreak/texconv - Converts images into any texture format supported on the DC.
User avatar
bogglez
Moderator
Moderator
Posts: 576
Joined: Sun Apr 20, 2014 9:45 am
Has liked: 0
Been liked: 0

Re: Texture compression size comparison study

Post by bogglez » Sun Nov 02, 2014 11:25 am

Tvspelsfreak wrote:
bogglez wrote:Why can VQ compression not be used with non-square images though?
I don't think I've ever tried doing VQ compression on rectangular images. All sources say they need to be square. But then again, they also say paletted textures can't be compressed. I might try out that later.
I'm not sure about twiddling, but VQ could in theory work with rectangles as well, so I'd be glad if you found something out about that.
Many game assets have rectangular texture sizes. I'd need to build texture atlases and change the UV maps of this mesh for example.. And we really don't want to waste any texture memory on the DC, so having to quadruple the size of the texture because it didn't fit into a square and rectangles aren't allowed hurts..
Tvspelsfreak wrote:
bogglez wrote:Are there any quality differences between your tool and the one in KOS?
It's been a while since I've looked at the codebase, so don't quote me on this. But IIRC, vqenc is missing a "place" after the final codebook split, which is needed in order to calculate the new code vector (avg of all vectors using that code) after a split.
vqenc doesn't do much about unused codes either.
I also do a pre-pass for 16BPP images where I check if the source images contain <=256 unique quads. If they do, you're guaranteed "lossless" compression (it'll still be downgraded to 16BPP)
Let me know if you find any issues though. I'm always up for improving the tool.
I see! I also found the preview and codebook output in your tool to be very useful.
Wiki & tutorials: http://dcemulation.org/?title=Development
Wiki feedback: viewtopic.php?f=29&t=103940
My libgl playground (not for production): https://bitbucket.org/bogglez/libgl15
My lxdream fork (with small fixes): https://bitbucket.org/bogglez/lxdream
Tvspelsfreak
Team Screamcast
Team Screamcast
Posts: 144
Joined: Tue Dec 23, 2003 6:04 pm
Location: Umeå, Sweden
Has liked: 0
Been liked: 0
Contact:

Re: Texture compression size comparison study

Post by Tvspelsfreak » Sun Nov 02, 2014 11:44 am

bogglez wrote:I'm not sure about twiddling, but VQ could in theory work with rectangles as well, so I'd be glad if you found something out about that.
Many game assets have rectangular texture sizes. I'd need to build texture atlases and change the UV maps of this mesh for example.. And we really don't want to waste any texture memory on the DC, so having to quadruple the size of the texture because it didn't fit into a square and rectangles aren't allowed hurts..
Rectangluar images can be twiddled without problem as long as the dimensions are a power of 2. texconv will twiddle everything except strided textures. I'm pretty sure all image loaders in KOS, as well as kmgenc and vqenc do that as well.
bogglez wrote:I see! I also found the preview and codebook output in your tool to be very useful.
Thanks!
https://github.com/tvspelsfreak/texconv - Converts images into any texture format supported on the DC.
Tvspelsfreak
Team Screamcast
Team Screamcast
Posts: 144
Joined: Tue Dec 23, 2003 6:04 pm
Location: Umeå, Sweden
Has liked: 0
Been liked: 0
Contact:

Re: Texture compression size comparison study

Post by Tvspelsfreak » Sun Nov 02, 2014 2:33 pm

Ok, I've done some testing. Rectangular VQ textures work fine on the actual hardware, and I only need to change a couple of lines in texconv to support it.

I've also tried rectangular VQ textures with mipmaps, and it may work, not sure yet. I'm getting a partially scrambled output, so I probably just don't have the right texel layout at the moment.
https://github.com/tvspelsfreak/texconv - Converts images into any texture format supported on the DC.
User avatar
bogglez
Moderator
Moderator
Posts: 576
Joined: Sun Apr 20, 2014 9:45 am
Has liked: 0
Been liked: 0

Re: Texture compression size comparison study

Post by bogglez » Sun Nov 02, 2014 2:41 pm

Tvspelsfreak wrote:Ok, I've done some testing. Rectangular VQ textures work fine on the actual hardware, and I only need to change a couple of lines in texconv to support it.
That's awesome to hear!! :D
Tvspelsfreak wrote:I've also tried rectangular VQ textures with mipmaps, and it may work, not sure yet. I'm getting a partially scrambled output, so I probably just don't have the right texel layout at the moment.
That would be perfect! Even if it doesn't work it would at least allow me to use a non-mipmapped VQ texture for rectangular textures then. :-)
Wiki & tutorials: http://dcemulation.org/?title=Development
Wiki feedback: viewtopic.php?f=29&t=103940
My libgl playground (not for production): https://bitbucket.org/bogglez/libgl15
My lxdream fork (with small fixes): https://bitbucket.org/bogglez/lxdream
Tvspelsfreak
Team Screamcast
Team Screamcast
Posts: 144
Joined: Tue Dec 23, 2003 6:04 pm
Location: Umeå, Sweden
Has liked: 0
Been liked: 0
Contact:

Re: Texture compression size comparison study

Post by Tvspelsfreak » Sun Nov 02, 2014 3:55 pm

I've updated texconv with experimental support for rectangular, non-mipmapped VQ textures. It's been tested with a couple of RGB565 textures, one where w>h, and one where h>w.

I also did some more testing with rectangular mipmaps, both with and without VQ. It seems the hardware assumes that w==h when it does a texel fetch, so I don't think it can be done. It makes sense for it to do that though since it simplifies having to find the offset of a given mipmap level.
https://github.com/tvspelsfreak/texconv - Converts images into any texture format supported on the DC.
User avatar
bogglez
Moderator
Moderator
Posts: 576
Joined: Sun Apr 20, 2014 9:45 am
Has liked: 0
Been liked: 0

Re: Texture compression size comparison study

Post by bogglez » Sun Nov 02, 2014 5:00 pm

Thanks for that :-)

I did some more tests and was surprised to see this:

Code: Select all

cloth4.png: PNG image data, 1024 x 512, 8-bit/color RGB, non-interlaced
1.6M	cloth4.tga
516K	cloth4.png
260K	cloth4.dds
1.1M	cloth4.dtex
I expected more savings here?
Attachments
cloth4.png
Wiki & tutorials: http://dcemulation.org/?title=Development
Wiki feedback: viewtopic.php?f=29&t=103940
My libgl playground (not for production): https://bitbucket.org/bogglez/libgl15
My lxdream fork (with small fixes): https://bitbucket.org/bogglez/lxdream
Tvspelsfreak
Team Screamcast
Team Screamcast
Posts: 144
Joined: Tue Dec 23, 2003 6:04 pm
Location: Umeå, Sweden
Has liked: 0
Been liked: 0
Contact:

Re: Texture compression size comparison study

Post by Tvspelsfreak » Sun Nov 02, 2014 5:11 pm

Did you compress that?

1.1M is pretty spot on for uncompressed. 1024*512*2 = 1048576 bytes, plus codebook and header. It should be around 130kB compressed.
https://github.com/tvspelsfreak/texconv - Converts images into any texture format supported on the DC.
User avatar
bogglez
Moderator
Moderator
Posts: 576
Joined: Sun Apr 20, 2014 9:45 am
Has liked: 0
Been liked: 0

Re: Texture compression size comparison study

Post by bogglez » Sun Nov 02, 2014 5:16 pm

Tvspelsfreak wrote:Did you compress that?

1.1M is pretty spot on for uncompressed. 1024*512*2 = 1048576 bytes, plus codebook and header. It should be around 130kB compressed.
Oh yeah, it seems I made a mistake while changing my batch script or so, sorry.. now at 132K, more like it :-)

You might want to look at this though:

Code: Select all

texconv --in hair2.png -o hair2.dtex --compress --format ARGB4444
[WARNING] Padding is 49152 but it should be less than 32!
Attachments
hair2.png
Wiki & tutorials: http://dcemulation.org/?title=Development
Wiki feedback: viewtopic.php?f=29&t=103940
My libgl playground (not for production): https://bitbucket.org/bogglez/libgl15
My lxdream fork (with small fixes): https://bitbucket.org/bogglez/lxdream
Tvspelsfreak
Team Screamcast
Team Screamcast
Posts: 144
Joined: Tue Dec 23, 2003 6:04 pm
Location: Umeå, Sweden
Has liked: 0
Been liked: 0
Contact:

Re: Texture compression size comparison study

Post by Tvspelsfreak » Sun Nov 02, 2014 5:33 pm

Fixed! I Forgot to update the devectorization function for alpha textures.
https://github.com/tvspelsfreak/texconv - Converts images into any texture format supported on the DC.
User avatar
bogglez
Moderator
Moderator
Posts: 576
Joined: Sun Apr 20, 2014 9:45 am
Has liked: 0
Been liked: 0

Re: Texture compression size comparison study

Post by bogglez » Mon Nov 03, 2014 2:28 pm

BTW would it be possible to leave out the format parameter and let the tool decide which format to use by itself? It should be quite obvious what format to use in which case I think.
So I can just do texconv -i a.png -o a.tex -c -m

Also, when providing -m I think it would be enough to print a warning that it's not possible to create a mipmap but create an unmipmapped texture anyway.
Those two changes would make batch tools much simpler.
Wiki & tutorials: http://dcemulation.org/?title=Development
Wiki feedback: viewtopic.php?f=29&t=103940
My libgl playground (not for production): https://bitbucket.org/bogglez/libgl15
My lxdream fork (with small fixes): https://bitbucket.org/bogglez/lxdream
User avatar
PH3NOM
DC Developer
DC Developer
Posts: 574
Joined: Fri Jun 18, 2010 9:29 pm
Has liked: 0
Been liked: 0

Re: Texture compression size comparison study

Post by PH3NOM » Mon Nov 03, 2014 9:28 pm

Cool stuff.

I wonder why VQ compression was not officially applied to rectangle textures if it actually works on real hardware?

If you need mip-mapped textures, you could combine rectangle textures into a square texture, sort of like a "sprite sheet", before compressing with VQ. You would have to adjust your u/v coordinates when rendering, of course.
User avatar
PH3NOM
DC Developer
DC Developer
Posts: 574
Joined: Fri Jun 18, 2010 9:29 pm
Has liked: 0
Been liked: 0

Re: Texture compression size comparison study

Post by PH3NOM » Mon Nov 03, 2014 9:29 pm

EDIT(double post)

I think it should still be able for the user to specify what color format to output ( maybe you don't want to preserve the alpha channel ).
User avatar
bogglez
Moderator
Moderator
Posts: 576
Joined: Sun Apr 20, 2014 9:45 am
Has liked: 0
Been liked: 0

Re: Texture compression size comparison study

Post by bogglez » Tue Nov 04, 2014 4:58 am

PH3NOM wrote:EDIT(double post)

I think it should still be able for the user to specify what color format to output ( maybe you don't want to preserve the alpha channel ).
I meant that -f should be optional and the format should be guessed if it's not provided.
Texture conversion should be as simple as possible so that people actually use it.
Wiki & tutorials: http://dcemulation.org/?title=Development
Wiki feedback: viewtopic.php?f=29&t=103940
My libgl playground (not for production): https://bitbucket.org/bogglez/libgl15
My lxdream fork (with small fixes): https://bitbucket.org/bogglez/lxdream
Tvspelsfreak
Team Screamcast
Team Screamcast
Posts: 144
Joined: Tue Dec 23, 2003 6:04 pm
Location: Umeå, Sweden
Has liked: 0
Been liked: 0
Contact:

Re: Texture compression size comparison study

Post by Tvspelsfreak » Tue Nov 04, 2014 11:29 am

I could make it pick between RGB565, ARGB1555 and ARGB4444 if no format flag is given.

Regarding the mipmap flag. I'm not sure it can be done easliy with the way it works now. The flags dictate what images are allowed to be loaded, not the other way around. It also allows for separate images for each mipmap level, so I'd have to take that into consideration as well. Besides, I like to keep things explicit as default.
https://github.com/tvspelsfreak/texconv - Converts images into any texture format supported on the DC.
User avatar
bogglez
Moderator
Moderator
Posts: 576
Joined: Sun Apr 20, 2014 9:45 am
Has liked: 0
Been liked: 0

Re: Texture compression size comparison study

Post by bogglez » Tue Nov 04, 2014 12:08 pm

Tvspelsfreak wrote:I could make it pick between RGB565, ARGB1555 and ARGB4444 if no format flag is given.
That would be greatly appreciated already.
Tvspelsfreak wrote: Regarding the mipmap flag. I'm not sure it can be done easliy with the way it works now. The flags dictate what images are allowed to be loaded, not the other way around. It also allows for separate images for each mipmap level, so I'd have to take that into consideration as well. Besides, I like to keep things explicit as default.
I see. For now I can just try to convert with -m first, then without if it didn't work (since you set the error code appropriately), but having to check the image dimensions yada yada in a Makefile is really annoying, and every person who wants to use this feature will have to write the same build code.
Wiki & tutorials: http://dcemulation.org/?title=Development
Wiki feedback: viewtopic.php?f=29&t=103940
My libgl playground (not for production): https://bitbucket.org/bogglez/libgl15
My lxdream fork (with small fixes): https://bitbucket.org/bogglez/lxdream
tonma
DCEmu Freak
DCEmu Freak
Posts: 82
Joined: Thu Mar 10, 2016 7:14 am
Has liked: 0
Been liked: 0

Re: Texture compression size comparison study

Post by tonma » Tue Mar 15, 2016 8:01 am

I test compression with texconv on Linux.

I have weird result with 8-bit png image :
Image

Code: Select all

TGA = 192 ko
PNG 8 bit (256c) = 1ko
Tex = 10ko  (pal8bpp)
Tex2 = 18ko  (rgb565)
For Tex file, I use "texconv --in dragon_walk.png --out dragon.tex -format PAL8BPP --compress -n
For Tex2 file, I use "texconv --in dragon_walk.png --out dragon.tex -format RGB565 --compress -n

Is it normal than my texture is bigger than png ?

If I use png, I use the tga size in memory so 192ko. If I use texture, I use only the texture size (10ko) ?
That's right ?


Do you have some example code to draw pal8bpp texture file image ?
I have not found on forum.

I use the libpng to load png files. I init my video mode with RGB565

Code: Select all

vid_set_mode(640x480, PM_RGB565);

back_tex = pvr_mem_malloc(512 * 512 * 2);
png_to_texture("/rd/background.png", back_tex, PNG_FULL_ALPHA);

pvr_poly_cxt_txr(&cxt, PVR_LIST_TR_POLY, PVR_TXRFMT_ARGB4444, 512, 512, back_tex, PVR_FILTER_NONE);
pvr_poly_compile(&hdr, &cxt);
pvr_prim(&hdr, sizeof(hdr));
Can I use a mix of 16-bit, 8-bit and 4-bit file on the PM_RGB565 or I need to choose only one mode (like 8-bit for example with only 8-bit pictures) ?
Post Reply