@@ -144,12 +144,7 @@ TextureLoaderImpl::TextureLoaderImpl(IReferenceCounters* pRefCounters,
144144 LOG_ERROR_AND_THROW (" Unable to derive image format." );
145145 }
146146
147- if (ImgFileFormat == IMAGE_FILE_FORMAT_PNG ||
148- ImgFileFormat == IMAGE_FILE_FORMAT_JPEG ||
149- ImgFileFormat == IMAGE_FILE_FORMAT_TIFF ||
150- ImgFileFormat == IMAGE_FILE_FORMAT_SGI ||
151- ImgFileFormat == IMAGE_FILE_FORMAT_HDR ||
152- ImgFileFormat == IMAGE_FILE_FORMAT_TGA)
147+ if (Image::IsSupportedFileFormat (ImgFileFormat))
153148 {
154149 ImageLoadInfo ImgLoadInfo;
155150 ImgLoadInfo.Format = ImgFileFormat;
@@ -160,16 +155,13 @@ TextureLoaderImpl::TextureLoaderImpl(IReferenceCounters* pRefCounters,
160155 Image::CreateFromMemory (pData, DataSize, ImgLoadInfo, &pImage);
161156 LoadFromImage (std::move (pImage), TexLoadInfo);
162157 }
163- else
158+ else if (ImgFileFormat == IMAGE_FILE_FORMAT_DDS)
164159 {
165- if (ImgFileFormat == IMAGE_FILE_FORMAT_DDS)
166- {
167- LoadFromDDS (TexLoadInfo, pData, DataSize);
168- }
169- else if (ImgFileFormat == IMAGE_FILE_FORMAT_KTX)
170- {
171- LoadFromKTX (TexLoadInfo, pData, DataSize);
172- }
160+ LoadFromDDS (TexLoadInfo, pData, DataSize);
161+ }
162+ else if (ImgFileFormat == IMAGE_FILE_FORMAT_KTX)
163+ {
164+ LoadFromKTX (TexLoadInfo, pData, DataSize);
173165 }
174166
175167 if (TexLoadInfo.IsSRGB )
@@ -195,27 +187,16 @@ void TextureLoaderImpl::CreateTexture(IRenderDevice* pDevice,
195187 pDevice->CreateTexture (m_TexDesc, &InitData, ppTexture);
196188}
197189
198- void TextureLoaderImpl::LoadFromImage (RefCntAutoPtr<Image> pImage , const TextureLoadInfo& TexLoadInfo)
190+ static void TexDescFromImageDesc ( const ImageDesc& ImgDesc , const TextureLoadInfo& TexLoadInfo, TextureDesc& TexDesc )
199191{
200- VERIFY_EXPR (pImage != nullptr );
201-
202- ImageDesc ImgDesc = pImage->GetDesc ();
203- if (TexLoadInfo.UniformImageClipDim != 0 && pImage->IsUniform ())
204- {
205- ImgDesc.Width = std::min (ImgDesc.Width , TexLoadInfo.UniformImageClipDim );
206- ImgDesc.Height = std::min (ImgDesc.Height , TexLoadInfo.UniformImageClipDim );
207- }
208-
209- m_TexDesc.Type = RESOURCE_DIM_TEX_2D;
210- m_TexDesc.Width = ImgDesc.Width ;
211- m_TexDesc.Height = ImgDesc.Height ;
212- m_TexDesc.MipLevels = ComputeMipLevelsCount (m_TexDesc.Width , m_TexDesc.Height );
192+ TexDesc.Type = RESOURCE_DIM_TEX_2D;
193+ TexDesc.Width = ImgDesc.Width ;
194+ TexDesc.Height = ImgDesc.Height ;
195+ TexDesc.MipLevels = ComputeMipLevelsCount (TexDesc.Width , TexDesc.Height );
213196 if (TexLoadInfo.MipLevels > 0 )
214- m_TexDesc .MipLevels = std::min (m_TexDesc .MipLevels , TexLoadInfo.MipLevels );
197+ TexDesc .MipLevels = std::min (TexDesc .MipLevels , TexLoadInfo.MipLevels );
215198
216- const Uint32 CompSize = GetValueSize (ImgDesc.ComponentType );
217-
218- if (m_TexDesc.Format == TEX_FORMAT_UNKNOWN)
199+ if (TexDesc.Format == TEX_FORMAT_UNKNOWN)
219200 {
220201 const COMPONENT_TYPE CompType = ValueTypeToComponentType (ImgDesc.ComponentType , /* IsNormalized = */ true , TexLoadInfo.IsSRGB );
221202
@@ -227,26 +208,47 @@ void TextureLoaderImpl::LoadFromImage(RefCntAutoPtr<Image> pImage, const Texture
227208 }
228209 DEV_CHECK_ERR (CompType != COMPONENT_TYPE_UNDEFINED, " Failed to deduce component type from image component type " , GetValueTypeString (ImgDesc.ComponentType ), " and sRGB flag " , TexLoadInfo.IsSRGB );
229210
230- m_TexDesc.Format = TextureComponentAttribsToTextureFormat (CompType, CompSize, NumComponents);
231- if (m_TexDesc.Format == TEX_FORMAT_UNKNOWN)
211+ const Uint32 CompSize = GetValueSize (ImgDesc.ComponentType );
212+
213+ TexDesc.Format = TextureComponentAttribsToTextureFormat (CompType, CompSize, NumComponents);
214+ if (TexDesc.Format == TEX_FORMAT_UNKNOWN)
232215 {
233216 LOG_ERROR_AND_THROW (" Failed to deduce texture format from image component type " , GetValueTypeString (ImgDesc.ComponentType ), " and number of components " , ImgDesc.NumComponents );
234217 }
235218 }
236- const auto & TexFmtDesc = GetTextureFormatAttribs (m_TexDesc.Format );
237- const Uint32 NumComponents = TexFmtDesc.NumComponents ;
219+ }
238220
239- m_SubResources.resize (m_TexDesc.MipLevels );
240- m_Mips.resize (m_TexDesc.MipLevels );
221+ inline bool GetSwizzleRequired (Uint32 NumComponents, const TextureComponentMapping& Swizzle)
222+ {
223+ return ((NumComponents >= 1 && Swizzle.R != TEXTURE_COMPONENT_SWIZZLE_IDENTITY && Swizzle.R != TEXTURE_COMPONENT_SWIZZLE_R) ||
224+ (NumComponents >= 2 && Swizzle.G != TEXTURE_COMPONENT_SWIZZLE_IDENTITY && Swizzle.G != TEXTURE_COMPONENT_SWIZZLE_G) ||
225+ (NumComponents >= 3 && Swizzle.B != TEXTURE_COMPONENT_SWIZZLE_IDENTITY && Swizzle.B != TEXTURE_COMPONENT_SWIZZLE_B) ||
226+ (NumComponents >= 4 && Swizzle.A != TEXTURE_COMPONENT_SWIZZLE_IDENTITY && Swizzle.A != TEXTURE_COMPONENT_SWIZZLE_A));
227+ }
228+
229+ void TextureLoaderImpl::LoadFromImage (RefCntAutoPtr<Image> pImage, const TextureLoadInfo& TexLoadInfo)
230+ {
231+ VERIFY_EXPR (pImage != nullptr );
241232
242- const bool SwizzleRequired =
243- (NumComponents >= 1 && TexLoadInfo.Swizzle .R != TEXTURE_COMPONENT_SWIZZLE_IDENTITY && TexLoadInfo.Swizzle .R != TEXTURE_COMPONENT_SWIZZLE_R) ||
244- (NumComponents >= 2 && TexLoadInfo.Swizzle .G != TEXTURE_COMPONENT_SWIZZLE_IDENTITY && TexLoadInfo.Swizzle .G != TEXTURE_COMPONENT_SWIZZLE_G) ||
245- (NumComponents >= 3 && TexLoadInfo.Swizzle .B != TEXTURE_COMPONENT_SWIZZLE_IDENTITY && TexLoadInfo.Swizzle .B != TEXTURE_COMPONENT_SWIZZLE_B) ||
246- (NumComponents >= 4 && TexLoadInfo.Swizzle .A != TEXTURE_COMPONENT_SWIZZLE_IDENTITY && TexLoadInfo.Swizzle .A != TEXTURE_COMPONENT_SWIZZLE_A);
233+ ImageDesc ImgDesc = pImage->GetDesc ();
234+ if (TexLoadInfo.UniformImageClipDim != 0 && pImage->IsUniform ())
235+ {
236+ ImgDesc.Width = std::min (ImgDesc.Width , TexLoadInfo.UniformImageClipDim );
237+ ImgDesc.Height = std::min (ImgDesc.Height , TexLoadInfo.UniformImageClipDim );
238+ }
239+
240+ // Note: do not override Name field in m_TexDesc
241+ TexDescFromImageDesc (ImgDesc, TexLoadInfo, m_TexDesc);
247242
243+ const TextureFormatAttribs& TexFmtDesc = GetTextureFormatAttribs (m_TexDesc.Format );
244+ const Uint32 NumComponents = TexFmtDesc.NumComponents ;
245+ const Uint32 SrcCompSize = GetValueSize (ImgDesc.ComponentType );
246+ const bool SwizzleRequired = GetSwizzleRequired (NumComponents, TexLoadInfo.Swizzle );
247+
248+ m_SubResources.resize (m_TexDesc.MipLevels );
249+ m_Mips.resize (m_TexDesc.MipLevels );
248250 if (ImgDesc.NumComponents != NumComponents ||
249- TexFmtDesc.ComponentSize != CompSize ||
251+ TexFmtDesc.ComponentSize != SrcCompSize ||
250252 TexLoadInfo.FlipVertically ||
251253 SwizzleRequired)
252254 {
@@ -259,7 +261,7 @@ void TextureLoaderImpl::LoadFromImage(RefCntAutoPtr<Image> pImage, const Texture
259261 CopyPixelsAttribs CopyAttribs;
260262 CopyAttribs.Width = ImgDesc.Width ;
261263 CopyAttribs.Height = ImgDesc.Height ;
262- CopyAttribs.SrcComponentSize = CompSize ;
264+ CopyAttribs.SrcComponentSize = SrcCompSize ;
263265 CopyAttribs.pSrcPixels = pImage->GetData ()->GetConstDataPtr ();
264266 CopyAttribs.SrcStride = ImgDesc.RowStride ;
265267 CopyAttribs.SrcCompCount = ImgDesc.NumComponents ;
@@ -356,30 +358,32 @@ void TextureLoaderImpl::LoadFromImage(RefCntAutoPtr<Image> pImage, const Texture
356358 }
357359}
358360
359- void TextureLoaderImpl::CompressSubresources (Uint32 NumComponents, Uint32 NumSrcComponents, const TextureLoadInfo& TexLoadInfo )
361+ inline TEXTURE_FORMAT GetCompressedTextureFormat (Uint32 NumComponents, Uint32 NumSrcComponents, bool IsSRGB )
360362{
361- TEXTURE_FORMAT CompressedFormat = TEX_FORMAT_UNKNOWN;
362363 switch (NumComponents)
363364 {
364365 case 1 :
365- CompressedFormat = TEX_FORMAT_BC4_UNORM;
366- break ;
366+ return TEX_FORMAT_BC4_UNORM;
367367
368368 case 2 :
369- CompressedFormat = TEX_FORMAT_BC5_UNORM;
370- break ;
369+ return TEX_FORMAT_BC5_UNORM;
371370
372371 case 4 :
373372 if (NumSrcComponents == 4 )
374- CompressedFormat = TexLoadInfo. IsSRGB ? TEX_FORMAT_BC3_UNORM_SRGB : TEX_FORMAT_BC3_UNORM;
373+ return IsSRGB ? TEX_FORMAT_BC3_UNORM_SRGB : TEX_FORMAT_BC3_UNORM;
375374 else
376- CompressedFormat = TexLoadInfo. IsSRGB ? TEX_FORMAT_BC1_UNORM_SRGB : TEX_FORMAT_BC1_UNORM;
375+ return IsSRGB ? TEX_FORMAT_BC1_UNORM_SRGB : TEX_FORMAT_BC1_UNORM;
377376 break ;
378377
379378 default :
380379 UNEXPECTED (" Unexpected number of components " , NumComponents);
380+ return TEX_FORMAT_UNKNOWN;
381381 }
382+ }
382383
384+ void TextureLoaderImpl::CompressSubresources (Uint32 NumComponents, Uint32 NumSrcComponents, const TextureLoadInfo& TexLoadInfo)
385+ {
386+ const TEXTURE_FORMAT CompressedFormat = GetCompressedTextureFormat (NumComponents, NumSrcComponents, TexLoadInfo.IsSRGB );
383387 if (CompressedFormat == TEX_FORMAT_UNKNOWN)
384388 return ;
385389
@@ -567,6 +571,71 @@ void CreateTextureLoaderFromImage(Image* pSrcImage,
567571 }
568572}
569573
574+ size_t GetTextureLoaderMemoryRequirement (const void * pData,
575+ size_t Size,
576+ const TextureLoadInfo& TexLoadInfo)
577+ {
578+ const IMAGE_FILE_FORMAT ImgFileFormat = Image::GetFileFormat (static_cast <const Uint8*>(pData), Size);
579+ if (ImgFileFormat == IMAGE_FILE_FORMAT_UNKNOWN)
580+ {
581+ return 0 ;
582+ }
583+
584+ if (Image::IsSupportedFileFormat (ImgFileFormat))
585+ {
586+ const ImageDesc ImgDesc = Image::GetDesc (ImgFileFormat, pData, Size);
587+ const Uint32 ImgCompSize = GetValueSize (ImgDesc.ComponentType );
588+
589+ TextureDesc TexDesc;
590+ TexDescFromImageDesc (ImgDesc, TexLoadInfo, TexDesc);
591+ const TextureFormatAttribs& TexFmtDesc = GetTextureFormatAttribs (TexDesc.Format );
592+ const bool SwizzleRequired = GetSwizzleRequired (TexFmtDesc.NumComponents , TexLoadInfo.Swizzle );
593+
594+ const size_t SrcImageDataSize = size_t {ImgDesc.Width } * ImgDesc.Height * ImgDesc.NumComponents * ImgCompSize;
595+
596+ // Step 1 - decode image data
597+ size_t RequiredMemory = SrcImageDataSize;
598+
599+ // Step 2 - convert image data if needed
600+ if (ImgDesc.NumComponents != TexFmtDesc.NumComponents ||
601+ TexFmtDesc.ComponentSize != ImgCompSize ||
602+ TexLoadInfo.FlipVertically ||
603+ SwizzleRequired)
604+ {
605+ const size_t ConvertedImageDataSize = size_t {TexDesc.Width } * TexDesc.Height * TexFmtDesc.NumComponents * TexFmtDesc.ComponentSize ;
606+ // Original and converted data exist simultaneously
607+ RequiredMemory += ConvertedImageDataSize;
608+ // After conversion is done, original data is released
609+ }
610+
611+ // Step 3 - generate mip levels
612+ // Mip level 0 uses either the original image data or converted data
613+ const size_t TextureDataSize = static_cast <size_t >(GetStagingTextureDataSize (TexDesc));
614+ RequiredMemory = std::max (RequiredMemory, TextureDataSize);
615+
616+ if (TexLoadInfo.CompressMode != TEXTURE_LOAD_COMPRESS_MODE_NONE)
617+ {
618+ TexDesc.Format = GetCompressedTextureFormat (TexFmtDesc.NumComponents , ImgDesc.NumComponents , TexLoadInfo.IsSRGB );
619+ if (TexDesc.Format != TEX_FORMAT_UNKNOWN)
620+ {
621+ const size_t CompressedTextureDataSize = static_cast <size_t >(GetStagingTextureDataSize (TexDesc));
622+ // Uncompressed and compressed data exist simultaneously
623+ RequiredMemory = std::max (RequiredMemory, TextureDataSize + CompressedTextureDataSize);
624+ }
625+ }
626+
627+ return RequiredMemory;
628+ }
629+ else if (ImgFileFormat == IMAGE_FILE_FORMAT_DDS ||
630+ ImgFileFormat == IMAGE_FILE_FORMAT_KTX)
631+ {
632+ // The loader does not require any memory as the source data is used directly
633+ return 0 ;
634+ }
635+
636+ return 0 ;
637+ }
638+
570639} // namespace Diligent
571640
572641extern " C"
@@ -594,4 +663,12 @@ extern "C"
594663 {
595664 Diligent::CreateTextureLoaderFromImage (pSrcImage, TexLoadInfo, ppLoader);
596665 }
666+
667+
668+ size_t Diligent_GetTextureLoaderMemoryRequirement (const void * pData,
669+ size_t Size,
670+ const Diligent::TextureLoadInfo& TexLoadInfo)
671+ {
672+ return Diligent::GetTextureLoaderMemoryRequirement (pData, Size, TexLoadInfo);
673+ }
597674}
0 commit comments