diff --git a/CMakeLists.txt b/CMakeLists.txt index ec5d2a04d..7b373ca61 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -355,6 +355,8 @@ set(LOVE_SRC_MODULE_IMAGE_ROOT ) set(LOVE_SRC_MODULE_IMAGE_MAGPIE + src/modules/image/magpie/ASTCHandler.cpp + src/modules/image/magpie/ASTCHandler.h src/modules/image/magpie/CompressedImageData.cpp src/modules/image/magpie/CompressedImageData.h src/modules/image/magpie/CompressedFormatHandler.h diff --git a/platform/xcode/liblove.xcodeproj/project.pbxproj b/platform/xcode/liblove.xcodeproj/project.pbxproj index 6cb0a9a8b..a6ac81ecd 100644 --- a/platform/xcode/liblove.xcodeproj/project.pbxproj +++ b/platform/xcode/liblove.xcodeproj/project.pbxproj @@ -817,6 +817,9 @@ FA0B7EEA1A95902D000E1D17 /* wrap_Window.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7CCC1A95902C000E1D17 /* wrap_Window.h */; }; FA0B7EF21A959D2C000E1D17 /* ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7EF11A959D2C000E1D17 /* ios.mm */; }; FA317EBA18F28B6D00B0BCD7 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FA317EB918F28B6D00B0BCD7 /* libz.dylib */; }; + FA41A3C81C0A1F950084430C /* ASTCHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA41A3C61C0A1F950084430C /* ASTCHandler.cpp */; }; + FA41A3C91C0A1F950084430C /* ASTCHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA41A3C61C0A1F950084430C /* ASTCHandler.cpp */; }; + FA41A3CA1C0A1F950084430C /* ASTCHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FA41A3C71C0A1F950084430C /* ASTCHandler.h */; }; FA4B66C91ABBCF1900558F15 /* Timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA4B66C81ABBCF1900558F15 /* Timer.cpp */; }; FA4B66CA1ABBCF1900558F15 /* Timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA4B66C81ABBCF1900558F15 /* Timer.cpp */; }; FA577AB016C7507900860150 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A7916C71A1700860150 /* Cocoa.framework */; }; @@ -1474,6 +1477,8 @@ FA283EDC1B27CFAA00C70067 /* nogame.lua */ = {isa = PBXFileReference; lastKnownFileType = text; path = nogame.lua; sourceTree = ""; }; FA283EDD1B27CFAA00C70067 /* nogame.lua.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = nogame.lua.h; sourceTree = ""; }; FA317EB918F28B6D00B0BCD7 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; }; + FA41A3C61C0A1F950084430C /* ASTCHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ASTCHandler.cpp; sourceTree = ""; }; + FA41A3C71C0A1F950084430C /* ASTCHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASTCHandler.h; sourceTree = ""; }; FA4B66C81ABBCF1900558F15 /* Timer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Timer.cpp; sourceTree = ""; }; FA577A6716C719D900860150 /* FreeType.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FreeType.framework; path = /Library/Frameworks/FreeType.framework; sourceTree = ""; }; FA577A6D16C719EA00860150 /* Lua.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Lua.framework; path = /Library/Frameworks/Lua.framework; sourceTree = ""; }; @@ -2298,9 +2303,11 @@ FA0B7BC81A95902C000E1D17 /* magpie */ = { isa = PBXGroup; children = ( + FA41A3C61C0A1F950084430C /* ASTCHandler.cpp */, + FA41A3C71C0A1F950084430C /* ASTCHandler.h */, + FA0B7BCB1A95902C000E1D17 /* CompressedFormatHandler.h */, FA0B7BC91A95902C000E1D17 /* CompressedImageData.cpp */, FA0B7BCA1A95902C000E1D17 /* CompressedImageData.h */, - FA0B7BCB1A95902C000E1D17 /* CompressedFormatHandler.h */, FA0B7BCC1A95902C000E1D17 /* ddsHandler.cpp */, FA0B7BCD1A95902C000E1D17 /* ddsHandler.h */, FA0B7BCE1A95902C000E1D17 /* FormatHandler.cpp */, @@ -3108,6 +3115,7 @@ FA0B7E171A95902C000E1D17 /* Joint.h in Headers */, FA0B793F1A958E3B000E1D17 /* types.h in Headers */, FA0B7AB31A958EA3000E1D17 /* b2Rope.h in Headers */, + FA41A3CA1C0A1F950084430C /* ASTCHandler.h in Headers */, FA0B7D5D1A95902C000E1D17 /* wrap_Font.h in Headers */, FA0B7ED31A95902C000E1D17 /* wrap_ThreadModule.h in Headers */, FA0B7A511A958EA3000E1D17 /* b2GrowableStack.h in Headers */, @@ -3336,6 +3344,7 @@ FA0B7A781A958EA3000E1D17 /* b2CircleContact.cpp in Sources */, FA0B7D5F1A95902C000E1D17 /* wrap_Graphics.cpp in Sources */, FA0B7A9C1A958EA3000E1D17 /* b2MouseJoint.cpp in Sources */, + FA41A3C91C0A1F950084430C /* ASTCHandler.cpp in Sources */, FA0B7E551A95902C000E1D17 /* wrap_GearJoint.cpp in Sources */, FA0B7E791A95902C000E1D17 /* wrap_WheelJoint.cpp in Sources */, FA0B7DDD1A95902C000E1D17 /* wrap_BezierCurve.cpp in Sources */, @@ -3622,6 +3631,7 @@ FA0B7D5E1A95902C000E1D17 /* wrap_Graphics.cpp in Sources */, FA0B7A801A958EA3000E1D17 /* b2EdgeAndCircleContact.cpp in Sources */, FA0B7E541A95902C000E1D17 /* wrap_GearJoint.cpp in Sources */, + FA41A3C81C0A1F950084430C /* ASTCHandler.cpp in Sources */, FA0B7E781A95902C000E1D17 /* wrap_WheelJoint.cpp in Sources */, FA0B7DDC1A95902C000E1D17 /* wrap_BezierCurve.cpp in Sources */, FA0B7AF71A958EA3000E1D17 /* luasocket.c in Sources */, diff --git a/src/modules/graphics/opengl/Image.cpp b/src/modules/graphics/opengl/Image.cpp index f86ce5b49..52b1a4a20 100644 --- a/src/modules/graphics/opengl/Image.cpp +++ b/src/modules/graphics/opengl/Image.cpp @@ -589,112 +589,101 @@ bool Image::isCompressed() const GLenum Image::getCompressedFormat(image::CompressedImageData::Format cformat, bool &isSRGB) const { + using image::CompressedImageData; + switch (cformat) { - case image::CompressedImageData::FORMAT_DXT1: - if (isSRGB) - return GL_COMPRESSED_SRGB_S3TC_DXT1_EXT; - else - return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; - case image::CompressedImageData::FORMAT_DXT3: - if (isSRGB) - return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT; - else - return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; - case image::CompressedImageData::FORMAT_DXT5: - if (isSRGB) - return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT; - else - return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; - case image::CompressedImageData::FORMAT_BC4: + case CompressedImageData::FORMAT_DXT1: + return isSRGB ? GL_COMPRESSED_SRGB_S3TC_DXT1_EXT : GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + case CompressedImageData::FORMAT_DXT3: + return isSRGB ? GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT : GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + case CompressedImageData::FORMAT_DXT5: + return isSRGB ? GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT : GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + case CompressedImageData::FORMAT_BC4: isSRGB = false; return GL_COMPRESSED_RED_RGTC1; - case image::CompressedImageData::FORMAT_BC4s: + case CompressedImageData::FORMAT_BC4s: isSRGB = false; return GL_COMPRESSED_SIGNED_RED_RGTC1; - case image::CompressedImageData::FORMAT_BC5: + case CompressedImageData::FORMAT_BC5: isSRGB = false; return GL_COMPRESSED_RG_RGTC2; - case image::CompressedImageData::FORMAT_BC5s: + case CompressedImageData::FORMAT_BC5s: isSRGB = false; return GL_COMPRESSED_SIGNED_RG_RGTC2; - case image::CompressedImageData::FORMAT_BC6H: + case CompressedImageData::FORMAT_BC6H: isSRGB = false; return GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT; - case image::CompressedImageData::FORMAT_BC6Hs: + case CompressedImageData::FORMAT_BC6Hs: isSRGB = false; return GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT; - case image::CompressedImageData::FORMAT_BC7: - if (isSRGB) - return GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM; - else - return GL_COMPRESSED_RGBA_BPTC_UNORM; - case image::CompressedImageData::FORMAT_ETC1: + case CompressedImageData::FORMAT_BC7: + return isSRGB ? GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM : GL_COMPRESSED_RGBA_BPTC_UNORM; + case CompressedImageData::FORMAT_PVR1_RGB2: + return isSRGB ? GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT : GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG; + case CompressedImageData::FORMAT_PVR1_RGB4: + return isSRGB ? GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT : GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG; + case CompressedImageData::FORMAT_PVR1_RGBA2: + return isSRGB ? GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT : GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; + case CompressedImageData::FORMAT_PVR1_RGBA4: + return isSRGB ? GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT : GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; + case CompressedImageData::FORMAT_ETC1: // The ETC2 format can load ETC1 textures. if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_4_3 || GLAD_ARB_ES3_compatibility) - { - if (isSRGB) - return GL_COMPRESSED_SRGB8_ETC2; - else - return GL_COMPRESSED_RGB8_ETC2; - } + return isSRGB ? GL_COMPRESSED_SRGB8_ETC2 : GL_COMPRESSED_RGB8_ETC2; else { isSRGB = false; return GL_ETC1_RGB8_OES; } - case image::CompressedImageData::FORMAT_ETC2_RGB: - if (isSRGB) - return GL_COMPRESSED_SRGB8_ETC2; - else - return GL_COMPRESSED_RGB8_ETC2; - case image::CompressedImageData::FORMAT_ETC2_RGBA: - if (isSRGB) - return GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC; - else - return GL_COMPRESSED_RGBA8_ETC2_EAC; - case image::CompressedImageData::FORMAT_ETC2_RGBA1: - if (isSRGB) - return GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2; - else - return GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2; - case image::CompressedImageData::FORMAT_EAC_R: + case CompressedImageData::FORMAT_ETC2_RGB: + return isSRGB ? GL_COMPRESSED_SRGB8_ETC2 : GL_COMPRESSED_RGB8_ETC2; + case CompressedImageData::FORMAT_ETC2_RGBA: + return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC : GL_COMPRESSED_RGBA8_ETC2_EAC; + case CompressedImageData::FORMAT_ETC2_RGBA1: + return isSRGB ? GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 : GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2; + case CompressedImageData::FORMAT_EAC_R: isSRGB = false; return GL_COMPRESSED_R11_EAC; - case image::CompressedImageData::FORMAT_EAC_Rs: + case CompressedImageData::FORMAT_EAC_Rs: isSRGB = false; return GL_COMPRESSED_SIGNED_R11_EAC; - case image::CompressedImageData::FORMAT_EAC_RG: + case CompressedImageData::FORMAT_EAC_RG: isSRGB = false; return GL_COMPRESSED_RG11_EAC; - case image::CompressedImageData::FORMAT_EAC_RGs: + case CompressedImageData::FORMAT_EAC_RGs: isSRGB = false; return GL_COMPRESSED_SIGNED_RG11_EAC; - case image::CompressedImageData::FORMAT_PVR1_RGB2: - if (isSRGB) - return GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT; - else - return GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG; - case image::CompressedImageData::FORMAT_PVR1_RGB4: - if (isSRGB) - return GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT; - else - return GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG; - case image::CompressedImageData::FORMAT_PVR1_RGBA2: - if (isSRGB) - return GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT; - else - return GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; - case image::CompressedImageData::FORMAT_PVR1_RGBA4: - if (isSRGB) - return GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT; - else - return GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; + case CompressedImageData::FORMAT_ASTC_4x4: + return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR : GL_COMPRESSED_RGBA_ASTC_4x4_KHR; + case CompressedImageData::FORMAT_ASTC_5x4: + return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR : GL_COMPRESSED_RGBA_ASTC_5x4_KHR; + case CompressedImageData::FORMAT_ASTC_5x5: + return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR : GL_COMPRESSED_RGBA_ASTC_5x5_KHR; + case CompressedImageData::FORMAT_ASTC_6x5: + return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR : GL_COMPRESSED_RGBA_ASTC_6x5_KHR; + case CompressedImageData::FORMAT_ASTC_6x6: + return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR : GL_COMPRESSED_RGBA_ASTC_6x6_KHR; + case CompressedImageData::FORMAT_ASTC_8x5: + return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR : GL_COMPRESSED_RGBA_ASTC_8x5_KHR; + case CompressedImageData::FORMAT_ASTC_8x6: + return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR : GL_COMPRESSED_RGBA_ASTC_8x6_KHR; + case CompressedImageData::FORMAT_ASTC_8x8: + return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR : GL_COMPRESSED_RGBA_ASTC_8x8_KHR; + case CompressedImageData::FORMAT_ASTC_10x5: + return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR : GL_COMPRESSED_RGBA_ASTC_10x5_KHR; + case CompressedImageData::FORMAT_ASTC_10x6: + return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR : GL_COMPRESSED_RGBA_ASTC_10x6_KHR; + case CompressedImageData::FORMAT_ASTC_10x8: + return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR : GL_COMPRESSED_RGBA_ASTC_10x8_KHR; + case CompressedImageData::FORMAT_ASTC_10x10: + return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR : GL_COMPRESSED_RGBA_ASTC_10x10_KHR; + case CompressedImageData::FORMAT_ASTC_12x10: + return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR : GL_COMPRESSED_RGBA_ASTC_12x10_KHR; + case CompressedImageData::FORMAT_ASTC_12x12: + return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR : GL_COMPRESSED_RGBA_ASTC_12x12_KHR; default: - if (isSRGB) - return GL_SRGB8_ALPHA8; - else - return GL_RGBA8; + return isSRGB ? GL_SRGB8_ALPHA8 : GL_RGBA8; } } @@ -705,42 +694,56 @@ bool Image::hasAnisotropicFilteringSupport() bool Image::hasCompressedTextureSupport(image::CompressedImageData::Format format, bool sRGB) { + using image::CompressedImageData; + switch (format) { - case image::CompressedImageData::FORMAT_DXT1: + case CompressedImageData::FORMAT_DXT1: return GLAD_EXT_texture_compression_s3tc || GLAD_EXT_texture_compression_dxt1; - case image::CompressedImageData::FORMAT_DXT3: + case CompressedImageData::FORMAT_DXT3: return GLAD_EXT_texture_compression_s3tc || GLAD_ANGLE_texture_compression_dxt3; - case image::CompressedImageData::FORMAT_DXT5: + case CompressedImageData::FORMAT_DXT5: return GLAD_EXT_texture_compression_s3tc || GLAD_ANGLE_texture_compression_dxt5; - case image::CompressedImageData::FORMAT_BC4: - case image::CompressedImageData::FORMAT_BC4s: - case image::CompressedImageData::FORMAT_BC5: - case image::CompressedImageData::FORMAT_BC5s: + case CompressedImageData::FORMAT_BC4: + case CompressedImageData::FORMAT_BC4s: + case CompressedImageData::FORMAT_BC5: + case CompressedImageData::FORMAT_BC5s: return (GLAD_VERSION_3_0 || GLAD_ARB_texture_compression_rgtc || GLAD_EXT_texture_compression_rgtc); - case image::CompressedImageData::FORMAT_BC6H: - case image::CompressedImageData::FORMAT_BC6Hs: - case image::CompressedImageData::FORMAT_BC7: + case CompressedImageData::FORMAT_BC6H: + case CompressedImageData::FORMAT_BC6Hs: + case CompressedImageData::FORMAT_BC7: return GLAD_VERSION_4_2 || GLAD_ARB_texture_compression_bptc; - case image::CompressedImageData::FORMAT_ETC1: + case CompressedImageData::FORMAT_PVR1_RGB2: + case CompressedImageData::FORMAT_PVR1_RGB4: + case CompressedImageData::FORMAT_PVR1_RGBA2: + case CompressedImageData::FORMAT_PVR1_RGBA4: + return sRGB ? GLAD_EXT_pvrtc_sRGB : GLAD_IMG_texture_compression_pvrtc; + case CompressedImageData::FORMAT_ETC1: // ETC2 support guarantees ETC1 support as well. return GLAD_ES_VERSION_3_0 || GLAD_VERSION_4_3 || GLAD_ARB_ES3_compatibility || GLAD_OES_compressed_ETC1_RGB8_texture; - case image::CompressedImageData::FORMAT_ETC2_RGB: - case image::CompressedImageData::FORMAT_ETC2_RGBA: - case image::CompressedImageData::FORMAT_ETC2_RGBA1: - case image::CompressedImageData::FORMAT_EAC_R: - case image::CompressedImageData::FORMAT_EAC_Rs: - case image::CompressedImageData::FORMAT_EAC_RG: - case image::CompressedImageData::FORMAT_EAC_RGs: + case CompressedImageData::FORMAT_ETC2_RGB: + case CompressedImageData::FORMAT_ETC2_RGBA: + case CompressedImageData::FORMAT_ETC2_RGBA1: + case CompressedImageData::FORMAT_EAC_R: + case CompressedImageData::FORMAT_EAC_Rs: + case CompressedImageData::FORMAT_EAC_RG: + case CompressedImageData::FORMAT_EAC_RGs: return GLAD_ES_VERSION_3_0 || GLAD_VERSION_4_3 || GLAD_ARB_ES3_compatibility; - case image::CompressedImageData::FORMAT_PVR1_RGB2: - case image::CompressedImageData::FORMAT_PVR1_RGB4: - case image::CompressedImageData::FORMAT_PVR1_RGBA2: - case image::CompressedImageData::FORMAT_PVR1_RGBA4: - if (sRGB) - return GLAD_EXT_pvrtc_sRGB; - else - return GLAD_IMG_texture_compression_pvrtc; + case CompressedImageData::FORMAT_ASTC_4x4: + case CompressedImageData::FORMAT_ASTC_5x4: + case CompressedImageData::FORMAT_ASTC_5x5: + case CompressedImageData::FORMAT_ASTC_6x5: + case CompressedImageData::FORMAT_ASTC_6x6: + case CompressedImageData::FORMAT_ASTC_8x5: + case CompressedImageData::FORMAT_ASTC_8x6: + case CompressedImageData::FORMAT_ASTC_8x8: + case CompressedImageData::FORMAT_ASTC_10x5: + case CompressedImageData::FORMAT_ASTC_10x6: + case CompressedImageData::FORMAT_ASTC_10x8: + case CompressedImageData::FORMAT_ASTC_10x10: + case CompressedImageData::FORMAT_ASTC_12x10: + case CompressedImageData::FORMAT_ASTC_12x12: + return /*GLAD_ES_VERSION_3_2 ||*/ GLAD_KHR_texture_compression_astc_ldr; default: return false; } @@ -763,8 +766,8 @@ bool Image::getConstant(FlagType in, const char *&out) StringMap::Entry Image::flagNameEntries[] = { - {"mipmaps", Image::FLAG_TYPE_MIPMAPS}, - {"linear", Image::FLAG_TYPE_LINEAR}, + {"mipmaps", FLAG_TYPE_MIPMAPS}, + {"linear", FLAG_TYPE_LINEAR}, }; StringMap Image::flagNames(Image::flagNameEntries, sizeof(Image::flagNameEntries)); diff --git a/src/modules/image/CompressedImageData.cpp b/src/modules/image/CompressedImageData.cpp index 1ee4090c9..68e977dc6 100644 --- a/src/modules/image/CompressedImageData.cpp +++ b/src/modules/image/CompressedImageData.cpp @@ -119,6 +119,10 @@ StringMap::En {"BC6h", FORMAT_BC6H}, {"BC6hs", FORMAT_BC6Hs}, {"BC7", FORMAT_BC7}, + {"PVR1rgb2", FORMAT_PVR1_RGB2}, + {"PVR1rgb4", FORMAT_PVR1_RGB4}, + {"PVR1rgba2", FORMAT_PVR1_RGBA2}, + {"PVR1rgba4", FORMAT_PVR1_RGBA4}, {"ETC1", FORMAT_ETC1}, {"ETC2rgb", FORMAT_ETC2_RGB}, {"ETC2rgba", FORMAT_ETC2_RGBA}, @@ -127,10 +131,20 @@ StringMap::En {"EACrs", FORMAT_EAC_Rs}, {"EACrg", FORMAT_EAC_RG}, {"EACrgs", FORMAT_EAC_RGs}, - {"PVR1rgb2", FORMAT_PVR1_RGB2}, - {"PVR1rgb4", FORMAT_PVR1_RGB4}, - {"PVR1rgba2", FORMAT_PVR1_RGBA2}, - {"PVR1rgba4", FORMAT_PVR1_RGBA4}, + {"ASTC4x4", FORMAT_ASTC_4x4}, + {"ASTC5x4", FORMAT_ASTC_5x4}, + {"ASTC5x5", FORMAT_ASTC_5x5}, + {"ASTC6x5", FORMAT_ASTC_6x5}, + {"ASTC6x6", FORMAT_ASTC_6x6}, + {"ASTC8x5", FORMAT_ASTC_8x5}, + {"ASTC8x6", FORMAT_ASTC_8x6}, + {"ASTC8x8", FORMAT_ASTC_8x8}, + {"ASTC10x5", FORMAT_ASTC_10x5}, + {"ASTC10x6", FORMAT_ASTC_10x6}, + {"ASTC10x8", FORMAT_ASTC_10x8}, + {"ASTC10x10", FORMAT_ASTC_10x10}, + {"ASTC12x10", FORMAT_ASTC_12x10}, + {"ASTC12x12", FORMAT_ASTC_12x12}, }; StringMap CompressedImageData::formats(CompressedImageData::formatEntries, sizeof(CompressedImageData::formatEntries)); diff --git a/src/modules/image/CompressedImageData.h b/src/modules/image/CompressedImageData.h index 7dcaa2586..bf3939b01 100644 --- a/src/modules/image/CompressedImageData.h +++ b/src/modules/image/CompressedImageData.h @@ -57,6 +57,10 @@ public: FORMAT_BC6H, FORMAT_BC6Hs, FORMAT_BC7, + FORMAT_PVR1_RGB2, + FORMAT_PVR1_RGB4, + FORMAT_PVR1_RGBA2, + FORMAT_PVR1_RGBA4, FORMAT_ETC1, FORMAT_ETC2_RGB, FORMAT_ETC2_RGBA, @@ -65,10 +69,20 @@ public: FORMAT_EAC_Rs, FORMAT_EAC_RG, FORMAT_EAC_RGs, - FORMAT_PVR1_RGB2, - FORMAT_PVR1_RGB4, - FORMAT_PVR1_RGBA2, - FORMAT_PVR1_RGBA4, + FORMAT_ASTC_4x4, + FORMAT_ASTC_5x4, + FORMAT_ASTC_5x5, + FORMAT_ASTC_6x5, + FORMAT_ASTC_6x6, + FORMAT_ASTC_8x5, + FORMAT_ASTC_8x6, + FORMAT_ASTC_8x8, + FORMAT_ASTC_10x5, + FORMAT_ASTC_10x6, + FORMAT_ASTC_10x8, + FORMAT_ASTC_10x10, + FORMAT_ASTC_12x10, + FORMAT_ASTC_12x12, FORMAT_MAX_ENUM }; diff --git a/src/modules/image/magpie/ASTCHandler.cpp b/src/modules/image/magpie/ASTCHandler.cpp new file mode 100644 index 000000000..b6fbcc6bb --- /dev/null +++ b/src/modules/image/magpie/ASTCHandler.cpp @@ -0,0 +1,166 @@ +/** + * Copyright (c) 2006-2015 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +// LOVE +#include "ASTCHandler.h" +#include "common/int.h" + +namespace love +{ +namespace image +{ +namespace magpie +{ + +namespace +{ + +static const uint32 ASTC_IDENTIFIER = 0x5CA1AB13; + +#pragma pack(push, 1) +struct ASTCHeader +{ + uint8 identifier[4]; + uint8 blockdimX; + uint8 blockdimY; + uint8 blockdimZ; + uint8 sizeX[3]; + uint8 sizeY[3]; + uint8 sizeZ[3]; +}; +#pragma pack(pop) + +static CompressedImageData::Format convertFormat(uint32 blockX, uint32 blockY, uint32 blockZ) +{ + if (blockZ > 1) + return CompressedImageData::FORMAT_UNKNOWN; + + if (blockX == 4 && blockY == 4) + return CompressedImageData::FORMAT_ASTC_4x4; + else if (blockX == 5 && blockY == 4) + return CompressedImageData::FORMAT_ASTC_5x4; + else if (blockX == 5 && blockY == 5) + return CompressedImageData::FORMAT_ASTC_5x5; + else if (blockX == 6 && blockY == 5) + return CompressedImageData::FORMAT_ASTC_6x5; + else if (blockX == 6 && blockY == 6) + return CompressedImageData::FORMAT_ASTC_6x6; + else if (blockX == 8 && blockY == 5) + return CompressedImageData::FORMAT_ASTC_8x5; + else if (blockX == 8 && blockY == 6) + return CompressedImageData::FORMAT_ASTC_8x6; + else if (blockX == 8 && blockY == 8) + return CompressedImageData::FORMAT_ASTC_8x8; + else if (blockX == 10 && blockY == 5) + return CompressedImageData::FORMAT_ASTC_10x5; + else if (blockX == 10 && blockY == 6) + return CompressedImageData::FORMAT_ASTC_10x6; + else if (blockX == 10 && blockY == 8) + return CompressedImageData::FORMAT_ASTC_10x8; + else if (blockX == 10 && blockY == 10) + return CompressedImageData::FORMAT_ASTC_10x10; + else if (blockX == 12 && blockY == 10) + return CompressedImageData::FORMAT_ASTC_12x10; + else if (blockX == 12 && blockY == 12) + return CompressedImageData::FORMAT_ASTC_12x12; + + return CompressedImageData::FORMAT_UNKNOWN; +} + +} // Anonymous namespace. + +bool ASTCHandler::canParse(const filesystem::FileData *data) +{ + if (data->getSize() <= sizeof(ASTCHeader)) + return false; + + const ASTCHeader *header = (const ASTCHeader *) data->getData(); + + uint32 identifier = (uint32) header->identifier[0] + + ((uint32) header->identifier[1] << 8) + + ((uint32) header->identifier[2] << 16) + + ((uint32) header->identifier[3] << 24); + + if (identifier != ASTC_IDENTIFIER) + return false; + + return true; +} + +uint8 *ASTCHandler::parse(filesystem::FileData *filedata, std::vector &images, size_t &dataSize, CompressedImageData::Format &format, bool &sRGB) +{ + if (!canParse(filedata)) + throw love::Exception("Could not decode compressed data (not an .astc file?)"); + + ASTCHeader header = *(const ASTCHeader *) filedata->getData(); + + CompressedImageData::Format cformat = convertFormat(header.blockdimX, header.blockdimY, header.blockdimZ); + + if (cformat == CompressedImageData::FORMAT_UNKNOWN) + throw love::Exception("Could not parse .astc file: unsupported ASTC format %dx%dx%d.", header.blockdimX, header.blockdimY, header.blockdimZ); + + uint32 sizeX = header.sizeX[0] + (header.sizeX[1] << 8) + (header.sizeX[2] << 16); + uint32 sizeY = header.sizeY[0] + (header.sizeY[1] << 8) + (header.sizeY[2] << 16); + uint32 sizeZ = header.sizeZ[0] + (header.sizeZ[1] << 8) + (header.sizeZ[2] << 16); + + uint32 blocksX = (sizeX + header.blockdimX - 1) / header.blockdimX; + uint32 blocksY = (sizeY + header.blockdimY - 1) / header.blockdimY; + uint32 blocksZ = (sizeZ + header.blockdimZ - 1) / header.blockdimZ; + + size_t totalsize = blocksX * blocksY * blocksZ * 16; + + if (totalsize + sizeof(header) > filedata->getSize()) + throw love::Exception("Could not parse .astc file: file is too small."); + + uint8 *data = nullptr; + + try + { + data = new uint8[totalsize]; + } + catch (std::bad_alloc &) + { + throw love::Exception("Out of memory."); + } + + // .astc files only store a single mipmap level. + memcpy(data, (uint8 *) filedata->getData() + sizeof(ASTCHeader), totalsize); + + CompressedImageData::SubImage mip; + + mip.width = sizeX; + mip.height = sizeY; + + mip.size = totalsize; + mip.data = data; + + images.push_back(mip); + + dataSize = totalsize; + format = cformat; + sRGB = false; + + return data; +} + +} // magpie +} // image +} // love + diff --git a/src/modules/image/magpie/ASTCHandler.h b/src/modules/image/magpie/ASTCHandler.h new file mode 100644 index 000000000..5c293a19e --- /dev/null +++ b/src/modules/image/magpie/ASTCHandler.h @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2006-2015 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#ifndef LOVE_IMAGE_MAGPIE_ASTC_HANDLER_H +#define LOVE_IMAGE_MAGPIE_ASTC_HANDLER_H + +#include "common/config.h" +#include "CompressedFormatHandler.h" + +namespace love +{ +namespace image +{ +namespace magpie +{ + +/** + * Handles simple .astc files (generated by ARM's astcenc tool) with compressed + * ASTC data inside. + **/ +class ASTCHandler : public CompressedFormatHandler +{ +public: + + virtual ~ASTCHandler() {} + + // Implements CompressedFormatHandler. + virtual bool canParse(const filesystem::FileData *data); + virtual uint8 *parse(filesystem::FileData *filedata, std::vector &images, size_t &dataSize, CompressedImageData::Format &format, bool &sRGB); + +}; // ASTCHandler + +} // magpie +} // image +} // love + +#endif // LOVE_IMAGE_MAGPIE_ASTC_HANDLER_H diff --git a/src/modules/image/magpie/Image.cpp b/src/modules/image/magpie/Image.cpp index 7caeb4710..575f04b92 100644 --- a/src/modules/image/magpie/Image.cpp +++ b/src/modules/image/magpie/Image.cpp @@ -30,6 +30,7 @@ #include "PVRHandler.h" #include "KTXHandler.h" #include "PKMHandler.h" +#include "ASTCHandler.h" namespace love { @@ -47,6 +48,7 @@ Image::Image() compressedFormatHandlers.push_back(new PVRHandler); compressedFormatHandlers.push_back(new KTXHandler); compressedFormatHandlers.push_back(new PKMHandler); + compressedFormatHandlers.push_back(new ASTCHandler); } Image::~Image() diff --git a/src/modules/image/magpie/KTXHandler.cpp b/src/modules/image/magpie/KTXHandler.cpp index 4b3f095ed..f421a920d 100644 --- a/src/modules/image/magpie/KTXHandler.cpp +++ b/src/modules/image/magpie/KTXHandler.cpp @@ -87,13 +87,44 @@ enum KTXGLInternalFormat // Same with DXT1/3/5. KTX_GL_COMPRESSED_RGB_S3TC_DXT1_EXT = 0x83F0, KTX_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT = 0x83F2, - KTX_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT = 0x83F3 + KTX_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT = 0x83F3, + + KTX_GL_COMPRESSED_RGBA_ASTC_4x4_KHR = 0x93B0, + KTX_GL_COMPRESSED_RGBA_ASTC_5x4_KHR = 0x93B1, + KTX_GL_COMPRESSED_RGBA_ASTC_5x5_KHR = 0x93B2, + KTX_GL_COMPRESSED_RGBA_ASTC_6x5_KHR = 0x93B3, + KTX_GL_COMPRESSED_RGBA_ASTC_6x6_KHR = 0x93B4, + KTX_GL_COMPRESSED_RGBA_ASTC_8x5_KHR = 0x93B5, + KTX_GL_COMPRESSED_RGBA_ASTC_8x6_KHR = 0x93B6, + KTX_GL_COMPRESSED_RGBA_ASTC_8x8_KHR = 0x93B7, + KTX_GL_COMPRESSED_RGBA_ASTC_10x5_KHR = 0x93B8, + KTX_GL_COMPRESSED_RGBA_ASTC_10x6_KHR = 0x93B9, + KTX_GL_COMPRESSED_RGBA_ASTC_10x8_KHR = 0x93BA, + KTX_GL_COMPRESSED_RGBA_ASTC_10x10_KHR = 0x93BB, + KTX_GL_COMPRESSED_RGBA_ASTC_12x10_KHR = 0x93BC, + KTX_GL_COMPRESSED_RGBA_ASTC_12x12_KHR = 0x93BD, + KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR = 0x93D0, + KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR = 0x93D1, + KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR = 0x93D2, + KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR = 0x93D3, + KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR = 0x93D4, + KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR = 0x93D5, + KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR = 0x93D6, + KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR = 0x93D7, + KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR = 0x93D8, + KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR = 0x93D9, + KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR = 0x93DA, + KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR = 0x93DB, + KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR = 0x93DC, + KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR = 0x93DD }; CompressedImageData::Format convertFormat(uint32 glformat, bool &sRGB) { sRGB = false; + // hnnngg ASTC... + switch (glformat) { case KTX_GL_ETC1_RGB8_OES: @@ -135,6 +166,62 @@ CompressedImageData::Format convertFormat(uint32 glformat, bool &sRGB) return CompressedImageData::FORMAT_DXT3; case KTX_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: return CompressedImageData::FORMAT_DXT5; + case KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: + sRGB = true; + case KTX_GL_COMPRESSED_RGBA_ASTC_4x4_KHR: + return CompressedImageData::FORMAT_ASTC_4x4; + case KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: + sRGB = true; + case KTX_GL_COMPRESSED_RGBA_ASTC_5x4_KHR: + return CompressedImageData::FORMAT_ASTC_5x4; + case KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: + sRGB = true; + case KTX_GL_COMPRESSED_RGBA_ASTC_5x5_KHR: + return CompressedImageData::FORMAT_ASTC_5x5; + case KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: + sRGB = true; + case KTX_GL_COMPRESSED_RGBA_ASTC_6x5_KHR: + return CompressedImageData::FORMAT_ASTC_6x5; + case KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: + sRGB = true; + case KTX_GL_COMPRESSED_RGBA_ASTC_6x6_KHR: + return CompressedImageData::FORMAT_ASTC_6x6; + case KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: + sRGB = true; + case KTX_GL_COMPRESSED_RGBA_ASTC_8x5_KHR: + return CompressedImageData::FORMAT_ASTC_8x5; + case KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: + sRGB = true; + case KTX_GL_COMPRESSED_RGBA_ASTC_8x6_KHR: + return CompressedImageData::FORMAT_ASTC_8x6; + case KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: + sRGB = true; + case KTX_GL_COMPRESSED_RGBA_ASTC_8x8_KHR: + return CompressedImageData::FORMAT_ASTC_8x8; + case KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: + sRGB = true; + case KTX_GL_COMPRESSED_RGBA_ASTC_10x5_KHR: + return CompressedImageData::FORMAT_ASTC_10x5; + case KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: + sRGB = true; + case KTX_GL_COMPRESSED_RGBA_ASTC_10x6_KHR: + return CompressedImageData::FORMAT_ASTC_10x6; + case KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: + sRGB = true; + case KTX_GL_COMPRESSED_RGBA_ASTC_10x8_KHR: + return CompressedImageData::FORMAT_ASTC_10x8; + case KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: + sRGB = true; + case KTX_GL_COMPRESSED_RGBA_ASTC_10x10_KHR: + return CompressedImageData::FORMAT_ASTC_10x10; + case KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: + sRGB = true; + case KTX_GL_COMPRESSED_RGBA_ASTC_12x10_KHR: + return CompressedImageData::FORMAT_ASTC_12x10; + case KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: + sRGB = true; + case KTX_GL_COMPRESSED_RGBA_ASTC_12x12_KHR: + return CompressedImageData::FORMAT_ASTC_12x12; default: return CompressedImageData::FORMAT_UNKNOWN; } diff --git a/src/modules/image/magpie/PVRHandler.cpp b/src/modules/image/magpie/PVRHandler.cpp index cb951b2f8..32a0f7833 100644 --- a/src/modules/image/magpie/PVRHandler.cpp +++ b/src/modules/image/magpie/PVRHandler.cpp @@ -237,20 +237,11 @@ static CompressedImageData::Format convertFormat(PVRV3PixelFormat format, PVRV3C case ePVRTPF_DXT5: return CompressedImageData::FORMAT_DXT5; case ePVRTPF_BC4: - if (snorm) - return CompressedImageData::FORMAT_BC4s; - else - return CompressedImageData::FORMAT_BC4; + return snorm ? CompressedImageData::FORMAT_BC4s : CompressedImageData::FORMAT_BC4; case ePVRTPF_BC5: - if (snorm) - return CompressedImageData::FORMAT_BC5s; - else - return CompressedImageData::FORMAT_BC5; + return snorm ? CompressedImageData::FORMAT_BC5s : CompressedImageData::FORMAT_BC5; case ePVRTPF_BC6: - if (snorm) - return CompressedImageData::FORMAT_BC6Hs; - else - return CompressedImageData::FORMAT_BC6H; + return snorm ? CompressedImageData::FORMAT_BC6Hs : CompressedImageData::FORMAT_BC6H; case ePVRTPF_BC7: return CompressedImageData::FORMAT_BC7; case ePVRTPF_ETC2_RGB: @@ -260,15 +251,37 @@ static CompressedImageData::Format convertFormat(PVRV3PixelFormat format, PVRV3C case ePVRTPF_ETC2_RGBA1: return CompressedImageData::FORMAT_ETC2_RGBA1; case ePVRTPF_EAC_R: - if (snorm) - return CompressedImageData::FORMAT_EAC_Rs; - else - return CompressedImageData::FORMAT_EAC_R; + return snorm ? CompressedImageData::FORMAT_EAC_Rs : CompressedImageData::FORMAT_EAC_R; case ePVRTPF_EAC_RG: - if (snorm) - return CompressedImageData::FORMAT_EAC_RGs; - else - return CompressedImageData::FORMAT_EAC_RG; + return snorm ? CompressedImageData::FORMAT_EAC_RGs : CompressedImageData::FORMAT_EAC_RG; + case ePVRTPF_ASTC_4x4: + return CompressedImageData::FORMAT_ASTC_4x4; + case ePVRTPF_ASTC_5x4: + return CompressedImageData::FORMAT_ASTC_5x4; + case ePVRTPF_ASTC_5x5: + return CompressedImageData::FORMAT_ASTC_5x5; + case ePVRTPF_ASTC_6x5: + return CompressedImageData::FORMAT_ASTC_6x5; + case ePVRTPF_ASTC_6x6: + return CompressedImageData::FORMAT_ASTC_6x6; + case ePVRTPF_ASTC_8x5: + return CompressedImageData::FORMAT_ASTC_8x5; + case ePVRTPF_ASTC_8x6: + return CompressedImageData::FORMAT_ASTC_8x6; + case ePVRTPF_ASTC_8x8: + return CompressedImageData::FORMAT_ASTC_8x8; + case ePVRTPF_ASTC_10x5: + return CompressedImageData::FORMAT_ASTC_10x5; + case ePVRTPF_ASTC_10x6: + return CompressedImageData::FORMAT_ASTC_10x6; + case ePVRTPF_ASTC_10x8: + return CompressedImageData::FORMAT_ASTC_10x8; + case ePVRTPF_ASTC_10x10: + return CompressedImageData::FORMAT_ASTC_10x10; + case ePVRTPF_ASTC_12x10: + return CompressedImageData::FORMAT_ASTC_12x10; + case ePVRTPF_ASTC_12x12: + return CompressedImageData::FORMAT_ASTC_12x12; default: return CompressedImageData::FORMAT_UNKNOWN; } @@ -314,8 +327,10 @@ int getBitsPerPixel(uint64 pixelformat) } } -void getFormatMinDimensions(uint64 pixelformat, int &minX, int &minY) +void getFormatMinDimensions(uint64 pixelformat, int &minX, int &minY, int &minZ) { + minZ = 1; + switch (pixelformat) { case ePVRTPF_PVRTCI_2bpp_RGB: @@ -351,6 +366,62 @@ void getFormatMinDimensions(uint64 pixelformat, int &minX, int &minY) case ePVRTPF_EAC_RG: minX = minY = 4; break; + case ePVRTPF_ASTC_4x4: + minX = 4; + minY = 4; + break; + case ePVRTPF_ASTC_5x4: + minX = 5; + minY = 4; + break; + case ePVRTPF_ASTC_5x5: + minX = 5; + minY = 5; + break; + case ePVRTPF_ASTC_6x5: + minX = 6; + minY = 5; + break; + case ePVRTPF_ASTC_6x6: + minX = 6; + minY = 6; + break; + case ePVRTPF_ASTC_8x5: + minX = 8; + minY = 5; + break; + case ePVRTPF_ASTC_8x6: + minX = 8; + minY = 6; + break; + case ePVRTPF_ASTC_8x8: + minX = 8; + minY = 8; + break; + case ePVRTPF_ASTC_10x5: + minX = 10; + minY = 5; + break; + case ePVRTPF_ASTC_10x6: + minX = 10; + minY = 6; + break; + case ePVRTPF_ASTC_10x8: + minX = 10; + minY = 8; + break; + case ePVRTPF_ASTC_10x10: + minX = 10; + minY = 10; + break; + case ePVRTPF_ASTC_12x10: + minX = 12; + minY = 10; + break; + case ePVRTPF_ASTC_12x12: + minX = 12; + minY = 12; + break; default: // We don't handle all possible formats, but that's fine. minX = minY = 1; break; @@ -361,17 +432,22 @@ size_t getMipLevelSize(const PVRTexHeaderV3 &header, int miplevel) { int smallestwidth = 1; int smallestheight = 1; - getFormatMinDimensions(header.pixelFormat, smallestwidth, smallestheight); + int smallestdepth = 1; + getFormatMinDimensions(header.pixelFormat, smallestwidth, smallestheight, smallestdepth); int width = std::max((int) header.width >> miplevel, 1); int height = std::max((int) header.height >> miplevel, 1); int depth = std::max((int) header.depth >> miplevel, 1); // Pad the dimensions. - width += (-width) % smallestwidth; - height += (-height) % smallestheight; + width = ((width + smallestwidth - 1) / smallestwidth) * smallestwidth; + height = ((height + smallestheight - 1) / smallestheight) * smallestheight; + depth = ((depth + smallestdepth - 1) / smallestdepth) * smallestdepth; - return getBitsPerPixel(header.pixelFormat) * width * height * depth / 8; + if (header.pixelFormat >= ePVRTPF_ASTC_4x4 && header.pixelFormat <= ePVRTPF_ASTC_12x12) + return (width / smallestwidth) * (height / smallestheight) * (depth / smallestdepth) * (128 / 8); + else + return getBitsPerPixel(header.pixelFormat) * width * height * depth / 8; } } // Anonymous namespace.