-
-
Notifications
You must be signed in to change notification settings - Fork 21.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BasisUniversal: Use RGTC compression when available #90170
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -84,14 +84,12 @@ Vector<uint8_t> basis_universal_packer(const Ref<Image> &p_image, Image::UsedCha | |
decompress_format = BASIS_DECOMPRESS_RGBA; | ||
} break; | ||
case Image::USED_CHANNELS_R: { | ||
decompress_format = BASIS_DECOMPRESS_RGB; | ||
decompress_format = BASIS_DECOMPRESS_R; | ||
} break; | ||
case Image::USED_CHANNELS_RG: { | ||
// Currently RG textures are compressed as DXT5/ETC2_RGBA8 with a RA -> RG swizzle, | ||
// as BasisUniversal didn't use to support ETC2_RG11 transcoding. | ||
params.m_force_alpha = true; | ||
image->convert_rg_to_ra_rgba8(); | ||
decompress_format = BASIS_DECOMPRESS_RG_AS_RA; | ||
decompress_format = BASIS_DECOMPRESS_RG; | ||
} break; | ||
case Image::USED_CHANNELS_RGB: { | ||
decompress_format = BASIS_DECOMPRESS_RGB; | ||
|
@@ -219,15 +217,68 @@ Ref<Image> basis_universal_unpacker_ptr(const uint8_t *p_data, int p_size) { | |
// Get supported compression formats. | ||
bool bptc_supported = RS::get_singleton()->has_os_feature("bptc"); | ||
bool astc_supported = RS::get_singleton()->has_os_feature("astc"); | ||
bool rgtc_supported = RS::get_singleton()->has_os_feature("rgtc"); | ||
bool s3tc_supported = RS::get_singleton()->has_os_feature("s3tc"); | ||
bool etc2_supported = RS::get_singleton()->has_os_feature("etc2"); | ||
|
||
bool needs_ra_rg_swap = false; | ||
bool needs_rg_trim = false; | ||
|
||
BasisDecompressFormat decompress_format = (BasisDecompressFormat)(*(uint32_t *)(src_ptr)); | ||
|
||
switch (*(uint32_t *)(src_ptr)) { | ||
switch (decompress_format) { | ||
case BASIS_DECOMPRESS_R: { | ||
if (rgtc_supported) { | ||
basisu_format = basist::transcoder_texture_format::cTFBC4_R; | ||
image_format = Image::FORMAT_RGTC_R; | ||
} else if (s3tc_supported) { | ||
basisu_format = basist::transcoder_texture_format::cTFBC1; | ||
image_format = Image::FORMAT_DXT1; | ||
} else if (etc2_supported) { | ||
basisu_format = basist::transcoder_texture_format::cTFETC2_EAC_R11; | ||
image_format = Image::FORMAT_ETC2_R11; | ||
} else { | ||
// No supported VRAM compression formats, decompress. | ||
basisu_format = basist::transcoder_texture_format::cTFRGBA32; | ||
image_format = Image::FORMAT_RGBA8; | ||
needs_rg_trim = true; | ||
} | ||
|
||
} break; | ||
case BASIS_DECOMPRESS_RG: { | ||
// RGTC transcoding is currently performed with RG_AS_RA, fail. | ||
ERR_FAIL_V(image); | ||
if (rgtc_supported) { | ||
basisu_format = basist::transcoder_texture_format::cTFBC5_RG; | ||
image_format = Image::FORMAT_RGTC_RG; | ||
} else if (s3tc_supported) { | ||
basisu_format = basist::transcoder_texture_format::cTFBC3; | ||
image_format = Image::FORMAT_DXT5_RA_AS_RG; | ||
} else if (etc2_supported) { | ||
basisu_format = basist::transcoder_texture_format::cTFETC2_EAC_RG11; | ||
image_format = Image::FORMAT_ETC2_RG11; | ||
} else { | ||
// No supported VRAM compression formats, decompress. | ||
basisu_format = basist::transcoder_texture_format::cTFRGBA32; | ||
image_format = Image::FORMAT_RGBA8; | ||
needs_ra_rg_swap = true; | ||
needs_rg_trim = true; | ||
} | ||
|
||
} break; | ||
case BASIS_DECOMPRESS_RG_AS_RA: { | ||
if (s3tc_supported) { | ||
basisu_format = basist::transcoder_texture_format::cTFBC3; | ||
image_format = Image::FORMAT_DXT5_RA_AS_RG; | ||
} else if (etc2_supported) { | ||
basisu_format = basist::transcoder_texture_format::cTFETC2; | ||
image_format = Image::FORMAT_ETC2_RA_AS_RG; | ||
} else { | ||
// No supported VRAM compression formats, decompress. | ||
basisu_format = basist::transcoder_texture_format::cTFRGBA32; | ||
image_format = Image::FORMAT_RGBA8; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Couldn't There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. BasisU doesn't allow directly decompressing textures to R8/RG8, so they have to be converted after decompression. This increases the loading time slightly, though I think the tradeoff is worth it since less VRAM is wasted. |
||
needs_ra_rg_swap = true; | ||
needs_rg_trim = true; | ||
} | ||
|
||
} break; | ||
case BASIS_DECOMPRESS_RGB: { | ||
if (bptc_supported) { | ||
|
@@ -267,20 +318,7 @@ Ref<Image> basis_universal_unpacker_ptr(const uint8_t *p_data, int p_size) { | |
basisu_format = basist::transcoder_texture_format::cTFRGBA32; | ||
image_format = Image::FORMAT_RGBA8; | ||
} | ||
} break; | ||
case BASIS_DECOMPRESS_RG_AS_RA: { | ||
if (s3tc_supported) { | ||
basisu_format = basist::transcoder_texture_format::cTFBC3; | ||
image_format = Image::FORMAT_DXT5_RA_AS_RG; | ||
} else if (etc2_supported) { | ||
basisu_format = basist::transcoder_texture_format::cTFETC2; | ||
image_format = Image::FORMAT_ETC2_RA_AS_RG; | ||
} else { | ||
// No supported VRAM compression formats, decompress. | ||
basisu_format = basist::transcoder_texture_format::cTFRGBA32; | ||
image_format = Image::FORMAT_RGBA8; | ||
needs_ra_rg_swap = true; | ||
} | ||
|
||
} break; | ||
} | ||
|
||
|
@@ -324,6 +362,15 @@ Ref<Image> basis_universal_unpacker_ptr(const uint8_t *p_data, int p_size) { | |
image->convert_ra_rgba8_to_rg(); | ||
} | ||
|
||
if (needs_rg_trim) { | ||
// Remove unnecessary color channels from uncompressed textures. | ||
if (decompress_format == BASIS_DECOMPRESS_R) { | ||
image->convert(Image::FORMAT_R8); | ||
} else if (decompress_format == BASIS_DECOMPRESS_RG || decompress_format == BASIS_DECOMPRESS_RG_AS_RA) { | ||
image->convert(Image::FORMAT_RG8); | ||
} | ||
} | ||
|
||
return image; | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couldn't
Image::FORMAT_R8
be used here?