23 if ( it._targetView._srcTexture !=
nullptr &&
25 it._sourceLayout != it._targetLayout )
57 Byte defaultTexData[1u * 1u * 4];
58 defaultTexData[0] = defaultTexData[1] = defaultTexData[2] =
to_byte( 0u );
59 defaultTexData[3] =
to_byte( 1u );
62 if ( !imgDataDefault.
loadFromMemory( defaultTexData, 4, 1u, 1u, 1u, 4 ) )
112 U8 bytesPerChannel = 1u;
125 return NumChannels( baseFormat ) * bytesPerChannel;
131 , _descriptor( descriptor._propertyDescriptor )
138 _loadedFromFile = !descriptor.assetName().empty();
140 if ( _loadedFromFile )
142 if ( assetLocation().empty() )
144 assetLocation( Paths::g_texturesLocation );
147 DIVIDE_ASSERT( assetLocation().
string().find(
',' ) == string::npos,
"TextureLoaderImpl error: All textures for a single array must be loaded from the same location!" );
149 const bool isCubeMap =
IsCubeTexture( _descriptor._texType );
151 const U16 numCommas =
to_U16( std::count( std::cbegin( descriptor.assetName() ), std::cend( descriptor.assetName() ),
',' ) );
152 if ( numCommas > 0u )
154 const U16 targetLayers = numCommas + 1u;
159 DIVIDE_ASSERT( targetLayers >= 6u && targetLayers % 6u == 0u,
"TextureLoaderImpl error: Invalid number of source textures specified for cube map!" );
161 if ( _descriptor._layerCount == 0u )
163 _descriptor._layerCount = targetLayers % 6;
166 DIVIDE_ASSERT( _descriptor._layerCount == targetLayers % 6 );
176 if ( _descriptor._layerCount == 0u )
178 _descriptor._layerCount = targetLayers;
181 DIVIDE_ASSERT( _descriptor._layerCount == targetLayers,
"TextureLoaderImpl error: Invalid number of source textures specified for texture array!" );
187 if ( _descriptor._layerCount == 0u )
189 _descriptor._layerCount = 1u;
222 if ( _loadedFromFile )
237 bool hasValidEntries =
false;
239 const ResourcePath currentTextureFullPath = assetLocation().
empty() ? Paths::g_texturesLocation : assetLocation();
241 string currentTextureFile;
242 while (
Util::GetLine( textureFileList, currentTextureFile,
',' ) )
245 if ( currentTextureFile.empty() )
251 if ( !
loadFile( currentTextureFullPath,
Util::Trim(currentTextureFile), dataStorage ) )
257 hasValidEntries =
true;
260 if ( hasValidEntries )
263 _descriptor._baseFormat = dataStorage.
format();
264 _descriptor._dataType = dataStorage.
dataType();
284 switch ( _descriptor._baseFormat )
329 DIVIDE_ASSERT( _width > 0 && _height > 0 && _depth > 0,
"Texture error: Invalid texture dimensions!" );
353 const bool emptyAllocation = dataSize == 0u || data ==
nullptr;
357 DIVIDE_ASSERT( _descriptor._msaaSamples == 0u || data ==
nullptr );
359 if ( !emptyAllocation )
362 if ( imgData.loadFromMemory( data, dataSize, dimensions.
width, dimensions.
height, 1,
GetBytesPerPixel( _descriptor._dataType, _descriptor._baseFormat, _descriptor._packing ) ) )
375 if ( data ==
nullptr || dataSize == 0u )
380 if ( offset.
x == 0u && offset.
y == 0u && offset.
z == 0u && (range.
x > _width || range.
y > _height || range.
z > _depth) )
390 loadDataInternal( data, dataSize, 0u, offset, range, pixelUnpackAlignment );
402 slices = slices / 6u;
426 if ( fileData.ignoreAlphaChannelTransparency() || fileData.hasDummyAlphaChannel() )
428 _hasTransparency =
false;
429 _hasTranslucency =
false;
440 const ResourcePath cachePath = Paths::Textures::g_metadataLocation / path;
441 const string cacheName =
string(name) +
".cache";
445 if ( metadataCache.
loadFromFile( cachePath, cacheName ) )
448 metadataCache >> tempVer;
451 metadataCache >> _hasTransparency;
452 metadataCache >> _hasTranslucency;
457 metadataCache.
clear();
465 bool hasTransulenctOrOpaquePixels =
false;
467 constexpr U32 transparentPixelsSkipCount = 4u;
469 std::atomic_uint transparentPixelCount = 0u;
478 for ( U32 i = start; i < end; ++i )
480 for ( I32 j = 0; j < height; ++j )
482 if ( _hasTransparency && (_hasTranslucency || hasTransulenctOrOpaquePixels) )
486 fileData.getAlpha( i, j, tempA, layer );
487 if ( IS_IN_RANGE_INCLUSIVE( tempA, 0, 250 ) )
489 if ( transparentPixelCount.fetch_add( 1u ) >= transparentPixelsSkipCount )
491 _hasTransparency = true;
492 _hasTranslucency = tempA > 1;
493 if ( _hasTranslucency )
495 hasTransulenctOrOpaquePixels = true;
500 else if ( tempA > 250 )
502 hasTransulenctOrOpaquePixels = true;
507 if ( _hasTransparency && !_hasTranslucency && !hasTransulenctOrOpaquePixels )
510 _hasTransparency = _hasTranslucency =
false;
514 metadataCache << _hasTransparency;
515 metadataCache << _hasTranslucency;
516 if ( !metadataCache.
dumpToFile( cachePath, cacheName ) )
525 _hasTransparency ?
"yes" :
"no",
526 _hasTranslucency ?
"yes" :
"no" );
531 void Texture::setSampleCount(
U8 newSampleCount )
533 CLAMP( newSampleCount,
U8_ZERO, DisplayManager::MaxMSAASamples() );
534 if ( _descriptor._msaaSamples != newSampleCount )
536 _descriptor._msaaSamples = newSampleCount;
537 createWithData(
nullptr, 0u, { width(), height(), depth() }, {});
541 void Texture::validateDescriptor()
543 if ( _descriptor._packing == GFXImagePacking::NORMALIZED_SRGB )
546 switch ( _descriptor._baseFormat )
548 case GFXImageFormat::RGB:
549 case GFXImageFormat::BGR:
550 case GFXImageFormat::RGBA:
551 case GFXImageFormat::BGRA:
552 case GFXImageFormat::BC1:
553 case GFXImageFormat::BC1a:
554 case GFXImageFormat::BC2:
555 case GFXImageFormat::BC3:
556 case GFXImageFormat::BC7:
558 valid = _descriptor._dataType == GFXDataFormat::UNSIGNED_BYTE;
561 case GFXImageFormat::RED:
562 case GFXImageFormat::RG:
563 case GFXImageFormat::BC3n:
564 case GFXImageFormat::BC4s:
565 case GFXImageFormat::BC4u:
566 case GFXImageFormat::BC5s:
567 case GFXImageFormat::BC5u:
568 case GFXImageFormat::BC6s:
569 case GFXImageFormat::BC6u:
break;
571 case GFXImageFormat::COUNT:
575 DIVIDE_ASSERT(valid,
"SRGB textures are only supported for RGB/BGR(A) normalized formats!" );
579 DIVIDE_ASSERT( _descriptor._baseFormat == GFXImageFormat::RED,
"Depth textures only supported for single channel formats");
586 if ( _descriptor._mipMappingState != MipMappingState::OFF )
599 const U16 layerCount = _descriptor._texType == TextureType::TEXTURE_3D ? 1u : _depth;
603 view._descriptor._msaaSamples = _descriptor._msaaSamples;
604 view._descriptor._dataType = _descriptor._dataType;
605 view._descriptor._baseFormat = _descriptor._baseFormat;
606 view._descriptor._packing = _descriptor._packing;
607 view._subRange._layerRange._count = layerCount;
608 view._subRange._mipLevels._count = _mipCount;
643 ImageView ret = getView( targetType, mipRange );
#define PROFILE_SCOPE_AUTO(CATEGORY)
bool loadFromFile(const ResourcePath &path, std::string_view fileName, const U8 version=BUFFER_FORMAT_VERSION)
void clear() noexcept
Resets the entire storage and the read and write positions.
bool dumpToFile(const ResourcePath &path, std::string_view fileName, const U8 version=BUFFER_FORMAT_VERSION)
Saves the entire buffer contents to file. Always appends the version at the end of the file.
virtual bool load(PlatformContext &context)
Loading and unloading interface.
Rough around the edges Adapter pattern abstracting the actual rendering API and access to the GPU.
GFXDevice & context() const noexcept
PlatformContext & context() noexcept
TaskPool & taskPool(const TaskPoolType type) noexcept
virtual void submitTextureData()
bool checkTransparency(const ResourcePath &path, std::string_view name, ImageTools::ImageData &fileData)
Texture(PlatformContext &context, const ResourceDescriptor< Texture > &descriptor)
static void OnShutdown() noexcept
bool loadInternal()
Load texture data using the specified file name.
static Handle< Texture > DefaultTexture2DArray() noexcept
bool load(PlatformContext &context) override
Loading and unloading interface.
static const SamplerDescriptor DefaultSampler() noexcept
virtual void prepareTextureData(U16 width, U16 height, U16 depth, bool emptyAllocation)
static SamplerDescriptor s_defaultSampler
U8 numChannels() const noexcept
static Handle< Texture > s_defaultTexture2D
static void OnStartup(GFXDevice &gfx)
static U8 GetBytesPerPixel(GFXDataFormat format, GFXImageFormat baseFormat, GFXImagePacking packing) noexcept
static Str< 64 > s_missingTextureFileName
static Handle< Texture > s_defaultTexture2DArray
void validateDescriptor()
static Handle< Texture > DefaultTexture2D() noexcept
virtual ~Texture() override
void createWithData(const ImageTools::ImageData &imageData, const PixelAlignment &pixelUnpackAlignment)
API-dependent loading function that uploads ptr data to the GPU using the specified parameters.
static bool UseTextureDDSCache() noexcept
static bool s_useDDSCache
bool loadFile(const ResourcePath &path, std::string_view name, ImageTools::ImageData &fileData)
Use STB to load a file into a Texture Object.
void replaceData(const Byte *data, size_t dataSize, const vec3< U16 > &offset, const vec3< U16 > &range, const PixelAlignment &pixelUnpackAlignment)
virtual void loadDataInternal(const ImageTools::ImageData &imageData, const vec3< U16 > &offset, const PixelAlignment &pixelUnpackAlignment)=0
constexpr Optick::Category::Type Streaming
constexpr Optick::Category::Type Graphics
bool GetLine(istringstream &input, T_str &line, char delimiter='\n')
Handle console commands that start with a forward slash.
constexpr U32 to_U32(const T value)
FORCE_INLINE void DestroyResource(Handle< T > &handle, const bool immediate=false)
constexpr U16 to_U16(const T value)
constexpr F32 to_F32(const T value)
bool IsCubeTexture(TextureType texType) noexcept
bool IsArrayTexture(TextureType texType) noexcept
eastl::fixed_vector< TextureLayoutChange, 6, true > TextureLayoutChanges
bool Is3DTexture(TextureType texType) noexcept
constexpr U16 BYTE_BUFFER_VERSION
bool IsDepthTexture(GFXImagePacking packing) noexcept
constexpr U64 _ID(const char *const str, const U64 value=val_64_const) noexcept
constexpr Byte to_byte(const T value)
std::basic_istringstream< char, std::char_traits< char >, dvd_allocator< char > > istringstream
FORCE_INLINE Handle< T > CreateResource(const ResourceDescriptor< T > &descriptor, bool &wasInCache, std::atomic_uint &taskCounter)
bool IsEmpty(const BufferLocks &locks) noexcept
std::basic_string< char, std::char_traits< char >, dvd_allocator< char > > string
::value constexpr void CLAMP(T &n, T min, T max) noexcept
Clamps value n between min and max.
void Parallel_For(TaskPool &pool, const ParallelForDescriptor &descriptor, const DELEGATE< void, const Task *, U32, U32 > &cbk)
bool fileExists(const ResourcePath &filePathAndName)
U8 NumChannels(GFXImageFormat format) noexcept
bool IsCompressed(GFXImageFormat format) noexcept
FORCE_INLINE T * Get(const Handle< T > handle)
bool HasAlphaChannel(GFXImageFormat format) noexcept
constexpr auto to_base(const Type value) -> Type
float floorf(const float in)
static NO_INLINE void errorfn(const char *format, T &&... args)
static NO_INLINE void printfn(const char *format, T &&... args)
const Texture * _srcTexture
U32 _partitionSize
How many elements should we process per async task.
bool _useCurrentThread
If true, we'll process a for partition on the calling thread.
U32 _iterCount
For loop iteration count.
bool empty() const noexcept
TextureFilter _minFilter
Texture filtering mode.
TextureWrap _wrapU
Texture wrap mode (Or S-R-T)
U8 _anisotropyLevel
The value must be in the range [0...255] and is automatically clamped by the max HW supported level.
TextureMipSampling _mipSampling