From fea4b3fcbac1e8b0fa1793ec849fa6799d376bff Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Thu, 15 Jun 2023 12:14:23 +0200 Subject: [PATCH] Add better Texture initialization API with custom data --- Source/Engine/Graphics/TextureBase.cs | 2 +- .../Engine/Graphics/Textures/TextureBase.cpp | 34 +++++++++++++++---- Source/Engine/Graphics/Textures/TextureBase.h | 29 ++++++++++++++-- 3 files changed, 56 insertions(+), 9 deletions(-) diff --git a/Source/Engine/Graphics/TextureBase.cs b/Source/Engine/Graphics/TextureBase.cs index 93b646d98..c4a915212 100644 --- a/Source/Engine/Graphics/TextureBase.cs +++ b/Source/Engine/Graphics/TextureBase.cs @@ -176,7 +176,7 @@ namespace FlaxEngine } // Call backend - if (Internal_Init(__unmanagedPtr, new IntPtr(&t))) + if (Internal_InitCSharp(__unmanagedPtr, new IntPtr(&t))) throw new Exception("Failed to init texture data."); } } diff --git a/Source/Engine/Graphics/Textures/TextureBase.cpp b/Source/Engine/Graphics/Textures/TextureBase.cpp index 36720a318..538b15a4a 100644 --- a/Source/Engine/Graphics/Textures/TextureBase.cpp +++ b/Source/Engine/Graphics/Textures/TextureBase.cpp @@ -556,6 +556,7 @@ bool TextureBase::Init(InitData* initData) if (!IsVirtual()) { LOG(Error, "Texture must be virtual."); + Delete(initData); return true; } if (initData->Format == PixelFormat::Unknown || @@ -565,6 +566,7 @@ bool TextureBase::Init(InitData* initData) Math::IsNotInRange(initData->Mips.Count(), 1, GPU_MAX_TEXTURE_MIP_LEVELS)) { Log::ArgumentOutOfRangeException(); + Delete(initData); return true; } ScopeLock lock(Locker); @@ -579,11 +581,11 @@ bool TextureBase::Init(InitData* initData) // Create texture TextureHeader textureHeader; - textureHeader.Format = initData->Format; - textureHeader.Width = initData->Width; - textureHeader.Height = initData->Height; - textureHeader.IsCubeMap = initData->ArraySize == 6; - textureHeader.MipLevels = initData->Mips.Count(); + textureHeader.Format = _customData->Format; + textureHeader.Width = _customData->Width; + textureHeader.Height = _customData->Height; + textureHeader.IsCubeMap = _customData->ArraySize == 6; + textureHeader.MipLevels = _customData->Mips.Count(); textureHeader.Type = TextureFormatType::ColorRGBA; textureHeader.NeverStream = true; if (_texture.Create(textureHeader)) @@ -595,7 +597,9 @@ bool TextureBase::Init(InitData* initData) return false; } -bool TextureBase::Init(void* ptr) +#if !COMPILE_WITHOUT_CSHARP + +bool TextureBase::InitCSharp(void* ptr) { PROFILE_CPU_NAMED("Texture.Init"); struct InternalInitData @@ -637,6 +641,8 @@ bool TextureBase::Init(void* ptr) return Init(initData); } +#endif + uint64 TextureBase::GetMemoryUsage() const { Locker.Lock(); @@ -764,6 +770,22 @@ Asset::LoadResult TextureBase::load() return LoadResult::Ok; } +TextureBase::InitData::MipData::MipData(MipData&& other) noexcept + : Data(MoveTemp(other.Data)) + , RowPitch(other.RowPitch) + , SlicePitch(other.SlicePitch) +{ +} + +TextureBase::InitData::InitData(InitData&& other) noexcept + : Format(other.Format) + , Width(other.Width) + , Height(other.Height) + , ArraySize(other.ArraySize) + , Mips(MoveTemp(other.Mips)) +{ +} + bool TextureBase::InitData::GenerateMip(int32 mipIndex, bool linear) { // Validate input diff --git a/Source/Engine/Graphics/Textures/TextureBase.h b/Source/Engine/Graphics/Textures/TextureBase.h index e09b1bf4e..e47bb548d 100644 --- a/Source/Engine/Graphics/Textures/TextureBase.h +++ b/Source/Engine/Graphics/Textures/TextureBase.h @@ -27,6 +27,9 @@ API_CLASS(Abstract, NoSpawn) class FLAXENGINE_API TextureBase : public BinaryAss BytesContainer Data; uint32 RowPitch; uint32 SlicePitch; + + MipData() = default; + MipData(MipData&& other) noexcept; }; PixelFormat Format; @@ -35,6 +38,16 @@ API_CLASS(Abstract, NoSpawn) class FLAXENGINE_API TextureBase : public BinaryAss int32 ArraySize; Array> Mips; + InitData() = default; + InitData(InitData&& other) noexcept; + + InitData& operator=(InitData&& other) + { + if (this != &other) + *this = MoveTemp(other); + return *this; + } + /// /// Generates the mip map data. /// @@ -208,16 +221,28 @@ public: /// /// Initializes the texture with specified initialize data source (asset must be virtual). /// - /// The initialize data (allocated by the called, will be used and released by the asset internal layer). + /// The initializer data allocated by the caller with New. It will be owned and released by the asset internal layer. /// True if failed, otherwise false. bool Init(InitData* initData); + /// + /// Initializes the texture with specified initialize data source (asset must be virtual). + /// + /// The initializer data. It will be used and released by the asset internal layer (memory allocation will be swapped). + /// True if failed, otherwise false. + bool Init(InitData&& initData) + { + return Init(New(MoveTemp(initData))); + } + protected: virtual int32 CalculateChunkIndex(int32 mipIndex) const; private: +#if !COMPILE_WITHOUT_CSHARP // Internal bindings - API_FUNCTION(NoProxy) bool Init(void* ptr); + API_FUNCTION(NoProxy) bool InitCSharp(void* ptr); +#endif public: // [BinaryAsset]