ATOM-16029 Add direct support for Astc compression (#4157)
* ATOM-16029 Add direct support for Astc compression Changes include: - Add ASTCCompressor class - Enabled 3rdparty::astc-encoder static library. - Remove ASTC support in PVRTC compressor and ISPC compressor. - Update unit test to include texts for ASTC compress/decompress. Signed-off-by: Qing Tao <qingtao@amazon.com>
This commit is contained in:
@@ -0,0 +1,322 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <astcenc.h>
|
||||
|
||||
#include <AzCore/Jobs/JobCompletion.h>
|
||||
#include <AzCore/Jobs/JobFunction.h>
|
||||
#include <AzCore/PlatformIncl.h>
|
||||
|
||||
#include <Atom/ImageProcessing/ImageObject.h>
|
||||
#include <Compressors/ASTCCompressor.h>
|
||||
#include <Processing/ImageFlags.h>
|
||||
#include <Processing/ImageToProcess.h>
|
||||
#include <Processing/PixelFormatInfo.h>
|
||||
|
||||
|
||||
namespace ImageProcessingAtom
|
||||
{
|
||||
bool ASTCCompressor::IsCompressedPixelFormatSupported(EPixelFormat fmt)
|
||||
{
|
||||
return IsASTCFormat(fmt);
|
||||
}
|
||||
|
||||
bool ASTCCompressor::IsUncompressedPixelFormatSupported(EPixelFormat fmt)
|
||||
{
|
||||
// astc encoder requires the compress input image or decompress output image to have four channels
|
||||
switch (fmt)
|
||||
{
|
||||
// uint 8
|
||||
case ePixelFormat_R8G8B8A8:
|
||||
case ePixelFormat_R8G8B8X8:
|
||||
// fp16
|
||||
case ePixelFormat_R16G16B16A16F:
|
||||
// fp32
|
||||
case ePixelFormat_R32G32B32A32F:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
EPixelFormat ASTCCompressor::GetSuggestedUncompressedFormat([[maybe_unused]] EPixelFormat compressedfmt, EPixelFormat uncompressedfmt) const
|
||||
{
|
||||
if (IsUncompressedPixelFormatSupported(uncompressedfmt))
|
||||
{
|
||||
return uncompressedfmt;
|
||||
}
|
||||
|
||||
auto formatInfo = CPixelFormats::GetInstance().GetPixelFormatInfo(uncompressedfmt);
|
||||
switch (formatInfo->eSampleType)
|
||||
{
|
||||
case ESampleType::eSampleType_Half:
|
||||
return ePixelFormat_R16G16B16A16F;
|
||||
case ESampleType::eSampleType_Float:
|
||||
return ePixelFormat_R32G32B32A32F;
|
||||
}
|
||||
|
||||
return ePixelFormat_R8G8B8A8;
|
||||
}
|
||||
|
||||
ColorSpace ASTCCompressor::GetSupportedColorSpace([[maybe_unused]] EPixelFormat compressFormat) const
|
||||
{
|
||||
return ColorSpace::autoSelect;
|
||||
}
|
||||
|
||||
const char* ASTCCompressor::GetName() const
|
||||
{
|
||||
return "ASTCCompressor";
|
||||
}
|
||||
|
||||
bool ASTCCompressor::DoesSupportDecompress([[maybe_unused]] EPixelFormat fmtDst)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
astcenc_profile GetAstcProfile(bool isSrgb, EPixelFormat pixelFormat)
|
||||
{
|
||||
// select profile depends on LDR or HDR, SRGB or Linear
|
||||
// ASTCENC_PRF_LDR
|
||||
// ASTCENC_PRF_LDR_SRGB
|
||||
// ASTCENC_PRF_HDR_RGB_LDR_A
|
||||
// ASTCENC_PRF_HDR
|
||||
|
||||
auto formatInfo = CPixelFormats::GetInstance().GetPixelFormatInfo(pixelFormat);
|
||||
bool isHDR = formatInfo->eSampleType == ESampleType::eSampleType_Half || formatInfo->eSampleType == ESampleType::eSampleType_Float;
|
||||
astcenc_profile profile;
|
||||
if (isHDR)
|
||||
{
|
||||
// HDR is not support in core vulkan 1.1 for android.
|
||||
// https://arm-software.github.io/vulkan-sdk/_a_s_t_c.html
|
||||
profile = isSrgb?ASTCENC_PRF_HDR_RGB_LDR_A:ASTCENC_PRF_HDR;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
profile = isSrgb?ASTCENC_PRF_LDR_SRGB:ASTCENC_PRF_LDR;
|
||||
}
|
||||
return profile;
|
||||
}
|
||||
|
||||
astcenc_type GetAstcDataType(EPixelFormat pixelFormat)
|
||||
{
|
||||
auto formatInfo = CPixelFormats::GetInstance().GetPixelFormatInfo(pixelFormat);
|
||||
astcenc_type dataType = ASTCENC_TYPE_U8;
|
||||
|
||||
switch (formatInfo->eSampleType)
|
||||
{
|
||||
case ESampleType::eSampleType_Uint8:
|
||||
dataType = ASTCENC_TYPE_U8;
|
||||
break;
|
||||
case ESampleType::eSampleType_Half:
|
||||
dataType = ASTCENC_TYPE_F16;
|
||||
break;
|
||||
case ESampleType::eSampleType_Float:
|
||||
dataType = ASTCENC_TYPE_F32;
|
||||
break;
|
||||
default:
|
||||
dataType = ASTCENC_TYPE_U8;
|
||||
AZ_Assert(false, "Unsupport uncompressed format %s", formatInfo->szName);
|
||||
break;
|
||||
}
|
||||
|
||||
return dataType;
|
||||
}
|
||||
|
||||
float GetAstcCompressQuality(ICompressor::EQuality quality)
|
||||
{
|
||||
switch (quality)
|
||||
{
|
||||
case ICompressor::EQuality::eQuality_Fast:
|
||||
return ASTCENC_PRE_FAST;
|
||||
case ICompressor::EQuality::eQuality_Slow:
|
||||
return ASTCENC_PRE_THOROUGH;
|
||||
case ICompressor::EQuality::eQuality_Preview:
|
||||
case ICompressor::EQuality::eQuality_Normal:
|
||||
default:
|
||||
return ASTCENC_PRE_MEDIUM;
|
||||
}
|
||||
}
|
||||
|
||||
IImageObjectPtr ASTCCompressor::CompressImage(IImageObjectPtr srcImage, EPixelFormat fmtDst, const CompressOption* compressOption) const
|
||||
{
|
||||
//validate input
|
||||
EPixelFormat fmtSrc = srcImage->GetPixelFormat();
|
||||
|
||||
//src format need to be uncompressed and dst format need to compressed.
|
||||
if (!IsUncompressedPixelFormatSupported(fmtSrc) || !IsCompressedPixelFormatSupported(fmtDst))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
astcenc_swizzle swizzle {ASTCENC_SWZ_R, ASTCENC_SWZ_G, ASTCENC_SWZ_B, compressOption->discardAlpha? ASTCENC_SWZ_1:ASTCENC_SWZ_A};
|
||||
AZ::u32 flags = 0;
|
||||
if (srcImage->HasImageFlags(EIF_RenormalizedTexture))
|
||||
{
|
||||
ImageToProcess imageToProcess(srcImage);
|
||||
imageToProcess.ConvertFormatUncompressed(ePixelFormat_R8G8B8X8);
|
||||
srcImage = imageToProcess.Get();
|
||||
fmtSrc = srcImage->GetPixelFormat();
|
||||
|
||||
flags = ASTCENC_FLG_MAP_NORMAL;
|
||||
swizzle = astcenc_swizzle{ ASTCENC_SWZ_R, ASTCENC_SWZ_R, ASTCENC_SWZ_R, ASTCENC_SWZ_G };
|
||||
}
|
||||
|
||||
auto dstFormatInfo = CPixelFormats::GetInstance().GetPixelFormatInfo(fmtDst);
|
||||
|
||||
const float quality = GetAstcCompressQuality(compressOption->compressQuality);
|
||||
const astcenc_profile profile = GetAstcProfile(srcImage->HasImageFlags(EIF_SRGBRead), fmtSrc);
|
||||
|
||||
astcenc_config config;
|
||||
astcenc_error status;
|
||||
status = astcenc_config_init(profile, dstFormatInfo->blockWidth, dstFormatInfo->blockHeight, 1, quality, flags, &config);
|
||||
|
||||
//ASTCENC_FLG_MAP_NORMAL
|
||||
AZ_Assert( status == ASTCENC_SUCCESS, "ERROR: Codec config init failed: %s\n", astcenc_get_error_string(status));
|
||||
|
||||
// Create a context based on the configuration
|
||||
astcenc_context* context;
|
||||
AZ::u32 blockCount = ((srcImage->GetWidth(0)+ dstFormatInfo->blockWidth-1)/dstFormatInfo->blockWidth) * ((srcImage->GetHeight(0) + dstFormatInfo->blockHeight-1)/dstFormatInfo->blockHeight);
|
||||
AZ::u32 threadCount = AZStd::min(AZStd::thread::hardware_concurrency(), blockCount);
|
||||
status = astcenc_context_alloc(&config, threadCount, &context);
|
||||
AZ_Assert( status == ASTCENC_SUCCESS, "ERROR: Codec context alloc failed: %s\n", astcenc_get_error_string(status));
|
||||
|
||||
const astcenc_type dataType =GetAstcDataType(fmtSrc);
|
||||
|
||||
// Compress the image for each mips
|
||||
IImageObjectPtr dstImage(srcImage->AllocateImage(fmtDst));
|
||||
const AZ::u32 dstMips = dstImage->GetMipCount();
|
||||
for (AZ::u32 mip = 0; mip < dstMips; ++mip)
|
||||
{
|
||||
astcenc_image image;
|
||||
image.dim_x = srcImage->GetWidth(mip);
|
||||
image.dim_y = srcImage->GetHeight(mip);
|
||||
image.dim_z = 1;
|
||||
image.data_type = dataType;
|
||||
|
||||
AZ::u8* srcMem;
|
||||
AZ::u32 srcPitch;
|
||||
srcImage->GetImagePointer(mip, srcMem, srcPitch);
|
||||
image.data = reinterpret_cast<void**>(&srcMem);
|
||||
|
||||
AZ::u8* dstMem;
|
||||
AZ::u32 dstPitch;
|
||||
dstImage->GetImagePointer(mip, dstMem, dstPitch);
|
||||
AZ::u32 dataSize = dstImage->GetMipBufSize(mip);
|
||||
|
||||
// Create jobs for each compression thread
|
||||
auto completionJob = aznew AZ::JobCompletion();
|
||||
for (AZ::u32 threadIdx = 0; threadIdx < threadCount; threadIdx++)
|
||||
{
|
||||
const auto jobLambda = [&status, context, &image, &swizzle, dstMem, dataSize, threadIdx]()
|
||||
{
|
||||
astcenc_error error = astcenc_compress_image(context, &image, &swizzle, dstMem, dataSize, threadIdx);
|
||||
if (error != ASTCENC_SUCCESS)
|
||||
{
|
||||
status = error;
|
||||
}
|
||||
};
|
||||
|
||||
AZ::Job* simulationJob = AZ::CreateJobFunction(AZStd::move(jobLambda), true, nullptr); //auto-deletes
|
||||
simulationJob->SetDependent(completionJob);
|
||||
simulationJob->Start();
|
||||
}
|
||||
|
||||
if (completionJob)
|
||||
{
|
||||
completionJob->StartAndWaitForCompletion();
|
||||
delete completionJob;
|
||||
completionJob = nullptr;
|
||||
}
|
||||
|
||||
if (status != ASTCENC_SUCCESS)
|
||||
{
|
||||
AZ_Error("Image Processing", false, "ASTCCompressor::CompressImage failed: %s\n", astcenc_get_error_string(status));
|
||||
astcenc_context_free(context);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Need to reset to compress next mip
|
||||
astcenc_compress_reset(context);
|
||||
}
|
||||
astcenc_context_free(context);
|
||||
|
||||
return dstImage;
|
||||
}
|
||||
|
||||
IImageObjectPtr ASTCCompressor::DecompressImage(IImageObjectPtr srcImage, EPixelFormat fmtDst) const
|
||||
{
|
||||
//validate input
|
||||
EPixelFormat fmtSrc = srcImage->GetPixelFormat(); //compressed
|
||||
auto srcFormatInfo = CPixelFormats::GetInstance().GetPixelFormatInfo(fmtSrc);
|
||||
|
||||
if (!IsCompressedPixelFormatSupported(fmtSrc) || !IsUncompressedPixelFormatSupported(fmtDst))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const float quality = ASTCENC_PRE_MEDIUM;
|
||||
astcenc_swizzle swizzle {ASTCENC_SWZ_R, ASTCENC_SWZ_G, ASTCENC_SWZ_B, ASTCENC_SWZ_A};
|
||||
if (srcImage->HasImageFlags(EIF_RenormalizedTexture))
|
||||
{
|
||||
swizzle = astcenc_swizzle{ASTCENC_SWZ_R, ASTCENC_SWZ_A, ASTCENC_SWZ_Z, ASTCENC_SWZ_1};
|
||||
}
|
||||
|
||||
astcenc_config config;
|
||||
astcenc_error status;
|
||||
astcenc_profile profile = GetAstcProfile(srcImage->HasImageFlags(EIF_SRGBRead), fmtDst);
|
||||
AZ::u32 flags = ASTCENC_FLG_DECOMPRESS_ONLY;
|
||||
status = astcenc_config_init(profile, srcFormatInfo->blockWidth, srcFormatInfo->blockHeight, 1, quality, flags, &config);
|
||||
|
||||
//ASTCENC_FLG_MAP_NORMAL
|
||||
AZ_Assert( status == ASTCENC_SUCCESS, "astcenc_config_init failed: %s\n", astcenc_get_error_string(status));
|
||||
|
||||
// Create a context based on the configuration
|
||||
const AZ::u32 threadCount = 1; // Decompress function doesn't support multiple threads
|
||||
astcenc_context* context;
|
||||
status = astcenc_context_alloc(&config, threadCount, &context);
|
||||
AZ_Assert( status == ASTCENC_SUCCESS, "astcenc_context_alloc failed: %s\n", astcenc_get_error_string(status));
|
||||
|
||||
astcenc_type dataType =GetAstcDataType(fmtDst);
|
||||
|
||||
// Decompress the image for each mips
|
||||
IImageObjectPtr dstImage(srcImage->AllocateImage(fmtDst));
|
||||
const AZ::u32 dstMips = dstImage->GetMipCount();
|
||||
for (AZ::u32 mip = 0; mip < dstMips; ++mip)
|
||||
{
|
||||
astcenc_image image;
|
||||
image.dim_x = srcImage->GetWidth(mip);
|
||||
image.dim_y = srcImage->GetHeight(mip);
|
||||
image.dim_z = 1;
|
||||
image.data_type = dataType;
|
||||
|
||||
AZ::u8* srcMem;
|
||||
AZ::u32 srcPitch;
|
||||
srcImage->GetImagePointer(mip, srcMem, srcPitch);
|
||||
AZ::u32 srcDataSize = srcImage->GetMipBufSize(mip);
|
||||
|
||||
AZ::u8* dstMem;
|
||||
AZ::u32 dstPitch;
|
||||
dstImage->GetImagePointer(mip, dstMem, dstPitch);
|
||||
image.data = reinterpret_cast<void**>(&dstMem);
|
||||
|
||||
status = astcenc_decompress_image(context, srcMem, srcDataSize, &image, &swizzle, 0);
|
||||
|
||||
if (status != ASTCENC_SUCCESS)
|
||||
{
|
||||
AZ_Error("Image Processing", false, "ASTCCompressor::DecompressImage failed: %s\n", astcenc_get_error_string(status));
|
||||
astcenc_context_free(context);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
astcenc_context_free(context);
|
||||
|
||||
return dstImage;
|
||||
}
|
||||
} //namespace ImageProcessingAtom
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Compressors/Compressor.h>
|
||||
|
||||
namespace ImageProcessingAtom
|
||||
{
|
||||
class ASTCCompressor
|
||||
: public ICompressor
|
||||
{
|
||||
public:
|
||||
static bool IsCompressedPixelFormatSupported(EPixelFormat fmt);
|
||||
static bool IsUncompressedPixelFormatSupported(EPixelFormat fmt);
|
||||
static bool DoesSupportDecompress(EPixelFormat fmtDst);
|
||||
|
||||
IImageObjectPtr CompressImage(IImageObjectPtr srcImage, EPixelFormat fmtDst, const CompressOption* compressOption) const override;
|
||||
IImageObjectPtr DecompressImage(IImageObjectPtr srcImage, EPixelFormat fmtDst) const override;
|
||||
|
||||
EPixelFormat GetSuggestedUncompressedFormat(EPixelFormat compressedfmt, EPixelFormat uncompressedfmt) const override;
|
||||
ColorSpace GetSupportedColorSpace(EPixelFormat compressFormat) const final;
|
||||
const char* GetName() const final;
|
||||
};
|
||||
} // namespace ImageProcessingAtom
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
|
||||
#include <AzCore/PlatformIncl.h>
|
||||
#include <Compressors/ASTCCompressor.h>
|
||||
#include <Compressors/CTSquisher.h>
|
||||
#include <Compressors/PVRTC.h>
|
||||
#include <Compressors/ETC2.h>
|
||||
@@ -15,11 +16,8 @@
|
||||
|
||||
namespace ImageProcessingAtom
|
||||
{
|
||||
ICompressorPtr ICompressor::FindCompressor(EPixelFormat fmt, [[maybe_unused]] ColorSpace colorSpace, bool isCompressing)
|
||||
ICompressorPtr ICompressor::FindCompressor(EPixelFormat fmt, ColorSpace colorSpace, bool isCompressing)
|
||||
{
|
||||
// The ISPC texture compressor is able to compress BC1, BC3, BC6H and BC7 formats, and all of the ASTC formats.
|
||||
// Note: The ISPC texture compressor is only able to compress images that are a multiple of the compressed format's blocksize.
|
||||
// Another limitation is that the compressor requires LDR source images to be in sRGB colorspace.
|
||||
if (ISPCCompressor::IsCompressedPixelFormatSupported(fmt))
|
||||
{
|
||||
if ((isCompressing && ISPCCompressor::IsSourceColorSpaceSupported(colorSpace, fmt)) || (!isCompressing && ISPCCompressor::DoesSupportDecompress(fmt)))
|
||||
@@ -35,6 +33,14 @@ namespace ImageProcessingAtom
|
||||
return ICompressorPtr(new CTSquisher());
|
||||
}
|
||||
}
|
||||
|
||||
if (ASTCCompressor::IsCompressedPixelFormatSupported(fmt))
|
||||
{
|
||||
if (isCompressing || (!isCompressing && ASTCCompressor::DoesSupportDecompress(fmt)))
|
||||
{
|
||||
return ICompressorPtr(new ASTCCompressor());
|
||||
}
|
||||
}
|
||||
|
||||
// Both ETC2Compressor and PVRTCCompressor can process ETC formats
|
||||
// According to Mobile team, Etc2Com is faster than PVRTexLib, so we check with ETC2Compressor before PVRTCCompressor
|
||||
|
||||
@@ -38,8 +38,7 @@ namespace ImageProcessingAtom
|
||||
EQuality compressQuality = eQuality_Normal;
|
||||
//required for CTSquisher
|
||||
AZ::Vector3 rgbWeight = AZ::Vector3(0.3333f, 0.3334f, 0.3333f);
|
||||
//required for ISPC texture compressor
|
||||
bool ispcDiscardAlpha = false;
|
||||
bool discardAlpha = false;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
+13
-19
@@ -57,6 +57,12 @@ namespace ImageProcessingAtom
|
||||
|
||||
bool ISPCCompressor::IsCompressedPixelFormatSupported(EPixelFormat fmt)
|
||||
{
|
||||
// Even though the ISPC compressor support ASTC formats. But it has restrictions
|
||||
// 1. Only supports LDR color profile
|
||||
// 2. Only supports a subset of 2D block sizes
|
||||
// Also it has overall lower quality compare to astc-encoder
|
||||
// So we won't add ASTC as part of supported formats here
|
||||
// Ref: https://solidpixel.github.io/2020/03/02/astc-compared.html
|
||||
switch (fmt)
|
||||
{
|
||||
case ePixelFormat_BC3:
|
||||
@@ -152,7 +158,7 @@ namespace ImageProcessingAtom
|
||||
if (compressOption)
|
||||
{
|
||||
quality = compressOption->compressQuality;
|
||||
discardAlpha = compressOption->ispcDiscardAlpha;
|
||||
discardAlpha = compressOption->discardAlpha;
|
||||
}
|
||||
|
||||
// Get the compression profile
|
||||
@@ -230,24 +236,12 @@ namespace ImageProcessingAtom
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (IsASTCFormat(destinationFormat))
|
||||
{
|
||||
const PixelFormatInfo* info = CPixelFormats::GetInstance().GetPixelFormatInfo(destinationFormat);
|
||||
astc_enc_settings settings = {};
|
||||
|
||||
const auto setProfile = compressionProfile->GetASTC(discardAlpha);
|
||||
setProfile(&settings, info->blockWidth, info->blockHeight);
|
||||
|
||||
// Compress with ASTC
|
||||
CompressBlocksASTC(&sourceSurface, destinationImageData, &settings);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No valid pixel format
|
||||
AZ_Assert(false, "Unhandled pixel format %d", destinationFormat);
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
{
|
||||
// No valid pixel format
|
||||
AZ_Assert(false, "Unhandled pixel format %d", destinationFormat);
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
namespace ImageProcessingAtom
|
||||
{
|
||||
// Note: PVRTexLib supports ASTC formats, ETC formats, PVRTC formats and BC formats
|
||||
// Note: PVRTexLib supports ETC formats, PVRTC formats and BC formats
|
||||
// We haven't tested the performace to compress BC formats compare to CTSquisher
|
||||
// For PVRTC formats, we only added PVRTC 1 support for now
|
||||
// The compression for ePVRTPF_EAC_R11 and ePVRTPF_EAC_RG11 are very slow. It takes 7 and 14 minutes for a 2048x2048 texture.
|
||||
@@ -27,34 +27,6 @@ namespace ImageProcessingAtom
|
||||
{
|
||||
switch (fmt)
|
||||
{
|
||||
case ePixelFormat_ASTC_4x4:
|
||||
return ePVRTPF_ASTC_4x4;
|
||||
case ePixelFormat_ASTC_5x4:
|
||||
return ePVRTPF_ASTC_5x4;
|
||||
case ePixelFormat_ASTC_5x5:
|
||||
return ePVRTPF_ASTC_5x5;
|
||||
case ePixelFormat_ASTC_6x5:
|
||||
return ePVRTPF_ASTC_6x5;
|
||||
case ePixelFormat_ASTC_6x6:
|
||||
return ePVRTPF_ASTC_6x6;
|
||||
case ePixelFormat_ASTC_8x5:
|
||||
return ePVRTPF_ASTC_8x5;
|
||||
case ePixelFormat_ASTC_8x6:
|
||||
return ePVRTPF_ASTC_8x6;
|
||||
case ePixelFormat_ASTC_8x8:
|
||||
return ePVRTPF_ASTC_8x8;
|
||||
case ePixelFormat_ASTC_10x5:
|
||||
return ePVRTPF_ASTC_10x5;
|
||||
case ePixelFormat_ASTC_10x6:
|
||||
return ePVRTPF_ASTC_10x6;
|
||||
case ePixelFormat_ASTC_10x8:
|
||||
return ePVRTPF_ASTC_10x8;
|
||||
case ePixelFormat_ASTC_10x10:
|
||||
return ePVRTPF_ASTC_10x10;
|
||||
case ePixelFormat_ASTC_12x10:
|
||||
return ePVRTPF_ASTC_12x10;
|
||||
case ePixelFormat_ASTC_12x12:
|
||||
return ePVRTPF_ASTC_12x12;
|
||||
case ePixelFormat_PVRTC2:
|
||||
return ePVRTPF_PVRTCI_2bpp_RGBA;
|
||||
case ePixelFormat_PVRTC4:
|
||||
@@ -156,26 +128,7 @@ namespace ImageProcessingAtom
|
||||
internalQuality = pvrtexture::eETCSlow;
|
||||
}
|
||||
}
|
||||
else if (IsASTCFormat(fmtDst))
|
||||
{
|
||||
if (quality == eQuality_Preview)
|
||||
{
|
||||
internalQuality = pvrtexture::eASTCVeryFast;
|
||||
}
|
||||
else if (quality == eQuality_Fast)
|
||||
{
|
||||
internalQuality = pvrtexture::eASTCFast;
|
||||
}
|
||||
else if (quality == eQuality_Normal)
|
||||
{
|
||||
internalQuality = pvrtexture::eASTCMedium;
|
||||
}
|
||||
else
|
||||
{
|
||||
internalQuality = pvrtexture::eASTCThorough;
|
||||
}
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
if (quality == eQuality_Preview)
|
||||
{
|
||||
@@ -252,7 +205,7 @@ namespace ImageProcessingAtom
|
||||
|
||||
if (!isSuccess)
|
||||
{
|
||||
AZ_Error("Image Processing", false, "Failed to compress image with PVRTexLib. You may not have astcenc.exe for compressing ASTC formates");
|
||||
AZ_Error("Image Processing", false, "Failed to compress image with PVRTexLib.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user