diff --git a/Source/Engine/Graphics/Enums.h b/Source/Engine/Graphics/Enums.h index 8aa88756a..a5615ccfa 100644 --- a/Source/Engine/Graphics/Enums.h +++ b/Source/Engine/Graphics/Enums.h @@ -4,7 +4,6 @@ #include "Engine/Core/Types/BaseTypes.h" #include "Engine/Core/Config.h" -#include "Engine/Scripting/ScriptingType.h" /// /// Graphics rendering backend system types. diff --git a/Source/Engine/Graphics/GPUBuffer.cpp b/Source/Engine/Graphics/GPUBuffer.cpp index eba53aba2..07a5242b3 100644 --- a/Source/Engine/Graphics/GPUBuffer.cpp +++ b/Source/Engine/Graphics/GPUBuffer.cpp @@ -2,8 +2,11 @@ #include "GPUBuffer.h" #include "GPUDevice.h" +#include "GPUBufferDescription.h" +#include "PixelFormatExtensions.h" #include "Async/Tasks/GPUCopyResourceTask.h" #include "Engine/Core/Utilities.h" +#include "Engine/Core/Types/String.h" #include "Engine/Core/Types/DataContainer.h" #include "Engine/Debug/Exceptions/InvalidOperationException.h" #include "Engine/Debug/Exceptions/ArgumentNullException.h" @@ -12,6 +15,117 @@ #include "Engine/Debug/Exceptions/ArgumentOutOfRangeException.h" #include "Engine/Threading/Threading.h" +GPUBufferDescription GPUBufferDescription::Buffer(uint32 size, GPUBufferFlags flags, PixelFormat format, const void* initData, uint32 stride, GPUResourceUsage usage) +{ + GPUBufferDescription desc; + desc.Size = size; + desc.Stride = stride; + desc.Flags = flags; + desc.Format = format; + desc.InitData = initData; + desc.Usage = usage; + return desc; +} + +GPUBufferDescription GPUBufferDescription::Typed(int32 count, PixelFormat viewFormat, bool isUnorderedAccess, GPUResourceUsage usage) +{ + auto bufferFlags = GPUBufferFlags::ShaderResource; + if (isUnorderedAccess) + bufferFlags |= GPUBufferFlags::UnorderedAccess; + const auto stride = PixelFormatExtensions::SizeInBytes(viewFormat); + return Buffer(count * stride, bufferFlags, viewFormat, nullptr, stride, usage); +} + +GPUBufferDescription GPUBufferDescription::Typed(const void* data, int32 count, PixelFormat viewFormat, bool isUnorderedAccess, GPUResourceUsage usage) +{ + auto bufferFlags = GPUBufferFlags::ShaderResource; + if (isUnorderedAccess) + bufferFlags |= GPUBufferFlags::UnorderedAccess; + const auto stride = PixelFormatExtensions::SizeInBytes(viewFormat); + return Buffer(count * stride, bufferFlags, viewFormat, data, stride, usage); +} + +void GPUBufferDescription::Clear() +{ + Platform::MemoryClear(this, sizeof(GPUBufferDescription)); +} + +GPUBufferDescription GPUBufferDescription::ToStagingUpload() const +{ + auto desc = *this; + desc.Usage = GPUResourceUsage::StagingUpload; + desc.Flags = GPUBufferFlags::None; + desc.InitData = nullptr; + return desc; +} + +GPUBufferDescription GPUBufferDescription::ToStagingReadback() const +{ + auto desc = *this; + desc.Usage = GPUResourceUsage::StagingReadback; + desc.Flags = GPUBufferFlags::None; + desc.InitData = nullptr; + return desc; +} + +bool GPUBufferDescription::Equals(const GPUBufferDescription& other) const +{ + return Size == other.Size + && Stride == other.Stride + && Flags == other.Flags + && Format == other.Format + && Usage == other.Usage + && InitData == other.InitData; +} + +String GPUBufferDescription::ToString() const +{ + // TODO: add tool to Format to string + + String flags; + if (Flags == GPUBufferFlags::None) + { + flags = TEXT("None"); + } + else + { + // TODO: create tool to auto convert flag enums to string + +#define CONVERT_FLAGS_FLAGS_2_STR(value) if(Flags & GPUBufferFlags::value) { if (flags.HasChars()) flags += TEXT('|'); flags += TEXT(#value); } + CONVERT_FLAGS_FLAGS_2_STR(ShaderResource); + CONVERT_FLAGS_FLAGS_2_STR(VertexBuffer); + CONVERT_FLAGS_FLAGS_2_STR(IndexBuffer); + CONVERT_FLAGS_FLAGS_2_STR(UnorderedAccess); + CONVERT_FLAGS_FLAGS_2_STR(Append); + CONVERT_FLAGS_FLAGS_2_STR(Counter); + CONVERT_FLAGS_FLAGS_2_STR(Argument); + CONVERT_FLAGS_FLAGS_2_STR(Structured); +#undef CONVERT_FLAGS_FLAGS_2_STR + } + + return String::Format(TEXT("Size: {0}, Stride: {1}, Flags: {2}, Format: {3}, Usage: {4}"), + Size, + Stride, + flags, + (int32)Format, + (int32)Usage); +} + +uint32 GetHash(const GPUBufferDescription& key) +{ + uint32 hashCode = key.Size; + hashCode = (hashCode * 397) ^ key.Stride; + hashCode = (hashCode * 397) ^ (uint32)key.Flags; + hashCode = (hashCode * 397) ^ (uint32)key.Format; + hashCode = (hashCode * 397) ^ (uint32)key.Usage; + return hashCode; +} + +GPUBufferView::GPUBufferView() + : GPUResourceView(SpawnParams(Guid::New(), TypeInitializer)) +{ +} + GPUBuffer* GPUBuffer::Spawn(const SpawnParams& params) { return GPUDevice::Instance->CreateBuffer(String::Empty); @@ -22,6 +136,12 @@ GPUBuffer* GPUBuffer::New() return GPUDevice::Instance->CreateBuffer(String::Empty); } +GPUBuffer::GPUBuffer() +{ + // Buffer with size 0 is considered to be invalid + _desc.Size = 0; +} + bool GPUBuffer::Init(const GPUBufferDescription& desc) { ASSERT(Math::IsInRange(desc.Size, 1, MAX_int32) @@ -157,12 +277,6 @@ private: public: - /// - /// Initializes a new instance of the class. - /// - /// The target buffer. - /// The staging buffer. - /// The output buffer data. BufferDownloadDataTask(GPUBuffer* buffer, GPUBuffer* staging, BytesContainer& data) : _buffer(buffer) , _staging(staging) @@ -170,9 +284,6 @@ public: { } - /// - /// Finalizes an instance of the class. - /// ~BufferDownloadDataTask() { SAFE_DELETE_GPU_RESOURCE(_staging); diff --git a/Source/Engine/Graphics/GPUBuffer.h b/Source/Engine/Graphics/GPUBuffer.h index 97be261a4..32e55ae56 100644 --- a/Source/Engine/Graphics/GPUBuffer.h +++ b/Source/Engine/Graphics/GPUBuffer.h @@ -18,10 +18,7 @@ API_CLASS(Sealed, NoSpawn) class FLAXENGINE_API GPUBufferView : public GPUResour DECLARE_SCRIPTING_TYPE_NO_SPAWN(GPUBufferView); protected: - GPUBufferView() - : GPUResourceView(SpawnParams(Guid::New(), TypeInitializer)) - { - } + GPUBufferView(); }; /// @@ -39,23 +36,7 @@ protected: GPUBufferDescription _desc; bool _isLocked = false; - /// - /// Initializes a new instance of the class. - /// - GPUBuffer() - { - // Buffer with size 0 is considered to be invalid - _desc.Size = 0; - } - -public: - - /// - /// Finalizes an instance of the class. - /// - virtual ~GPUBuffer() - { - } + GPUBuffer(); public: diff --git a/Source/Engine/Graphics/GPUBufferDescription.cpp b/Source/Engine/Graphics/GPUBufferDescription.cpp deleted file mode 100644 index e679e8b06..000000000 --- a/Source/Engine/Graphics/GPUBufferDescription.cpp +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. - -#include "GPUBufferDescription.h" -#include "PixelFormatExtensions.h" -#include "Engine/Core/Types/String.h" - -void GPUBufferDescription::Clear() -{ - Platform::MemoryClear(this, sizeof(GPUBufferDescription)); -} - -GPUBufferDescription GPUBufferDescription::Buffer(uint32 size, GPUBufferFlags flags, PixelFormat format, const void* initData, uint32 stride, GPUResourceUsage usage) -{ - GPUBufferDescription desc; - desc.Size = size; - desc.Stride = stride; - desc.Flags = flags; - desc.Format = format; - desc.InitData = initData; - desc.Usage = usage; - return desc; -} - -GPUBufferDescription GPUBufferDescription::Typed(int32 count, PixelFormat viewFormat, bool isUnorderedAccess, GPUResourceUsage usage) -{ - auto bufferFlags = GPUBufferFlags::ShaderResource; - if (isUnorderedAccess) - bufferFlags |= GPUBufferFlags::UnorderedAccess; - const auto stride = PixelFormatExtensions::SizeInBytes(viewFormat); - return Buffer(count * stride, bufferFlags, viewFormat, nullptr, stride, usage); -} - -GPUBufferDescription GPUBufferDescription::Typed(const void* data, int32 count, PixelFormat viewFormat, bool isUnorderedAccess, GPUResourceUsage usage) -{ - auto bufferFlags = GPUBufferFlags::ShaderResource; - if (isUnorderedAccess) - bufferFlags |= GPUBufferFlags::UnorderedAccess; - const auto stride = PixelFormatExtensions::SizeInBytes(viewFormat); - return Buffer(count * stride, bufferFlags, viewFormat, data, stride, usage); -} - -bool GPUBufferDescription::Equals(const GPUBufferDescription& other) const -{ - return Size == other.Size - && Stride == other.Stride - && Flags == other.Flags - && Format == other.Format - && Usage == other.Usage - && InitData == other.InitData; -} - -String GPUBufferDescription::ToString() const -{ - // TODO: add tool to Format to string - - String flags; - if (Flags == GPUBufferFlags::None) - { - flags = TEXT("None"); - } - else - { - // TODO: create tool to auto convert flag enums to string - -#define CONVERT_FLAGS_FLAGS_2_STR(value) if(Flags & GPUBufferFlags::value) { if (flags.HasChars()) flags += TEXT('|'); flags += TEXT(#value); } - CONVERT_FLAGS_FLAGS_2_STR(ShaderResource); - CONVERT_FLAGS_FLAGS_2_STR(VertexBuffer); - CONVERT_FLAGS_FLAGS_2_STR(IndexBuffer); - CONVERT_FLAGS_FLAGS_2_STR(UnorderedAccess); - CONVERT_FLAGS_FLAGS_2_STR(Append); - CONVERT_FLAGS_FLAGS_2_STR(Counter); - CONVERT_FLAGS_FLAGS_2_STR(Argument); - CONVERT_FLAGS_FLAGS_2_STR(Structured); -#undef CONVERT_FLAGS_FLAGS_2_STR - } - - return String::Format(TEXT("Size: {0}, Stride: {1}, Flags: {2}, Format: {3}, Usage: {4}"), - Size, - Stride, - flags, - (int32)Format, - (int32)Usage); -} - -uint32 GetHash(const GPUBufferDescription& key) -{ - uint32 hashCode = key.Size; - hashCode = (hashCode * 397) ^ key.Stride; - hashCode = (hashCode * 397) ^ (uint32)key.Flags; - hashCode = (hashCode * 397) ^ (uint32)key.Format; - hashCode = (hashCode * 397) ^ (uint32)key.Usage; - return hashCode; -} diff --git a/Source/Engine/Graphics/GPUBufferDescription.h b/Source/Engine/Graphics/GPUBufferDescription.h index a5d07243b..677748bde 100644 --- a/Source/Engine/Graphics/GPUBufferDescription.h +++ b/Source/Engine/Graphics/GPUBufferDescription.h @@ -136,13 +136,6 @@ public: return (Flags & GPUBufferFlags::UnorderedAccess) != 0; } -public: - - /// - /// Clears description. - /// - void Clear(); - public: /// @@ -342,64 +335,23 @@ public: public: - /// - /// Gets the staging upload description for this instance. - /// - /// A staging buffer description - GPUBufferDescription ToStagingUpload() const - { - auto desc = *this; - desc.Usage = GPUResourceUsage::StagingUpload; - desc.Flags = GPUBufferFlags::None; - desc.InitData = nullptr; - return desc; - } - - /// - /// Gets the staging readback description for this instance. - /// - /// A staging buffer description - GPUBufferDescription ToStagingReadback() const - { - auto desc = *this; - desc.Usage = GPUResourceUsage::StagingReadback; - desc.Flags = GPUBufferFlags::None; - desc.InitData = nullptr; - return desc; - } + void Clear(); + GPUBufferDescription ToStagingUpload() const; + GPUBufferDescription ToStagingReadback() const; + bool Equals(const GPUBufferDescription& other) const; + String ToString() const; public: - /// - /// Compares with other instance of GPUBufferDescription - /// - /// The other object to compare. - /// True if objects are the same, otherwise false. - bool Equals(const GPUBufferDescription& other) const; - - /// - /// Implements the operator ==. - /// - /// The other description. - /// The result of the operator. FORCE_INLINE bool operator==(const GPUBufferDescription& other) const { return Equals(other); } - /// - /// Implements the operator !=. - /// - /// The other description. - /// The result of the operator. FORCE_INLINE bool operator!=(const GPUBufferDescription& other) const { return !Equals(other); } - -public: - - String ToString() const; }; uint32 GetHash(const GPUBufferDescription& key); diff --git a/Source/Engine/Graphics/Shaders/Cache/ShaderCacheManager.cpp b/Source/Engine/Graphics/Shaders/Cache/ShaderCacheManager.cpp index cd63b3ec4..37c905375 100644 --- a/Source/Engine/Graphics/Shaders/Cache/ShaderCacheManager.cpp +++ b/Source/Engine/Graphics/Shaders/Cache/ShaderCacheManager.cpp @@ -24,105 +24,59 @@ const Char* ShaderProfileCacheDirNames[8] = TEXT("DX_SM6"), // DirectX_SM6 // @formatter:on }; + static_assert(ARRAY_COUNT(ShaderProfileCacheDirNames) == (int32)ShaderProfile::MAX, "Invalid shaders cache dirs"); class ShaderProfileDatabase { -private: +public: - ShaderProfile _profile; - String _folder; + ShaderProfile Profile; + String Folder; public: - /// - /// Gets the folder path. - /// - const String& GetFolder() const - { - return _folder; - } - -public: - - /// - /// Internalizes the database. - /// - /// Shader profile for that cache database - /// Parent root folder for cache databases void Init(ShaderProfile profile, const String& cacheRoot) { - // Init - _profile = profile; - _folder = cacheRoot / ShaderProfileCacheDirNames[static_cast(profile)]; - - // Ensure that directory exists - if (!FileSystem::DirectoryExists(_folder)) + Profile = profile; + Folder = cacheRoot / ShaderProfileCacheDirNames[static_cast(profile)]; + if (!FileSystem::DirectoryExists(Folder)) { - if (FileSystem::CreateDirectory(_folder)) + if (FileSystem::CreateDirectory(Folder)) { - LOG(Warning, "Cannot create cache directory for ShaderProfileDatabase: {0} (path: \'{1}\')", ::ToString(_profile), _folder); + LOG(Warning, "Cannot create cache directory for ShaderProfileDatabase: {0} (path: \'{1}\')", ::ToString(Profile), Folder); } } } - /// - /// Tries to get cached shader entry for a given shader. - /// - /// Shader ID - /// Result entry if success - /// False if cannot get it, otherwise true bool TryGetEntry(const Guid& id, ShaderCacheManager::CachedEntryHandle& cachedEntry) const { ASSERT(id.IsValid()); cachedEntry.ID = id; - cachedEntry.Path = _folder / id.ToString(Guid::FormatType::D); + cachedEntry.Path = Folder / id.ToString(Guid::FormatType::D); return cachedEntry.Exists(); } - /// - /// Gets shader cache. - /// - /// Cached entry handle - /// Output data - /// True if cannot set cache data, otherwise false bool GetCache(const ShaderCacheManager::CachedEntryHandle& cachedEntry, BytesContainer& outputShaderCache) const { ASSERT(cachedEntry.IsValid()); - - // Read raw bytes return File::ReadAllBytes(cachedEntry.Path, outputShaderCache); } - /// - /// Sets shader cache. - /// - /// Cached entry handle - /// Input data - /// True if cannot set cache data, otherwise false static bool SetCache(const ShaderCacheManager::CachedEntryHandle& cachedEntry, MemoryWriteStream& inputShaderCache) { ASSERT(cachedEntry.IsValid() && inputShaderCache.GetHandle() != nullptr); - - // Write raw bytes return inputShaderCache.SaveToFile(cachedEntry.Path); } - /// - /// Removes shader cache. - /// - /// Shader ID void RemoveCache(const Guid& id) const { ASSERT(id.IsValid()); - ShaderCacheManager::CachedEntryHandle cachedEntry; cachedEntry.ID = id; - cachedEntry.Path = _folder / id.ToString(Guid::FormatType::D); - - // Delete file - cachedEntry.Delete(); + cachedEntry.Path = Folder / id.ToString(Guid::FormatType::D); + FileSystem::DeleteFile(cachedEntry.Path); } }; @@ -152,6 +106,21 @@ static ShaderProfile index2ShaderProfile(const int32 index) return static_cast(index + 1); } +bool ShaderCacheManager::CachedEntryHandle::IsValid() const +{ + return ID.IsValid(); +} + +bool ShaderCacheManager::CachedEntryHandle::Exists() const +{ + return FileSystem::FileExists(Path); +} + +DateTime ShaderCacheManager::CachedEntryHandle::GetModificationDate() const +{ + return FileSystem::GetFileLastEditTime(Path); +} + bool ShaderCacheManager::TryGetEntry(const ShaderProfile profile, const Guid& id, CachedEntryHandle& cachedEntry) { ASSERT(profile != ShaderProfile::Unknown); @@ -190,7 +159,7 @@ void ShaderCacheManager::CopyCache(const Guid& dstId, const Guid& srcId) String srcFilename = srcId.ToString(Guid::FormatType::D); for (int32 i = 0; i < ARRAY_COUNT(Databases); i++) { - const String& folder = Databases[i].GetFolder(); + const String& folder = Databases[i].Folder; String dstPath = folder / dstFilename; String srcPath = folder / srcFilename; diff --git a/Source/Engine/Graphics/Shaders/Cache/ShaderCacheManager.h b/Source/Engine/Graphics/Shaders/Cache/ShaderCacheManager.h index 5ffa41393..947046735 100644 --- a/Source/Engine/Graphics/Shaders/Cache/ShaderCacheManager.h +++ b/Source/Engine/Graphics/Shaders/Cache/ShaderCacheManager.h @@ -21,33 +21,12 @@ public: struct CachedEntryHandle { - Guid ID; + Guid ID = Guid::Empty; String Path; - CachedEntryHandle() - { - ID = Guid::Empty; - } - - bool IsValid() const - { - return ID.IsValid(); - } - - bool Exists() const - { - return FileSystem::FileExists(Path); - } - - bool Delete() const - { - return FileSystem::DeleteFile(Path); - } - - DateTime GetModificationDate() const - { - return FileSystem::GetFileLastEditTime(Path); - } + bool IsValid() const; + bool Exists() const; + DateTime GetModificationDate() const; }; public: diff --git a/Source/Engine/Graphics/Textures/GPUTexture.cpp b/Source/Engine/Graphics/Textures/GPUTexture.cpp index 29268e721..106dacaac 100644 --- a/Source/Engine/Graphics/Textures/GPUTexture.cpp +++ b/Source/Engine/Graphics/Textures/GPUTexture.cpp @@ -1,10 +1,13 @@ // Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. #include "GPUTexture.h" +#include "GPUTextureDescription.h" #include "TextureData.h" #include "Engine/Core/Log.h" -#include "../Config.h" +#include "Engine/Core/Types/String.h" +#include "Engine/Core/Math/Vector3.h" #include "Engine/Threading/Threading.h" +#include "Engine/Graphics/Config.h" #include "Engine/Graphics/Async/Tasks/GPUCopyResourceTask.h" #include "Engine/Graphics/Async/Tasks/GPUUploadTextureMipTask.h" #include "Engine/Graphics/RenderTools.h" @@ -13,6 +16,199 @@ #include "Engine/Threading/ThreadPoolTask.h" #include "Engine/Graphics/GPUDevice.h" +namespace +{ + int32 CalculateMipMapCount(int32 requestedLevel, int32 width) + { + //int32 size = width; + //int32 maxMipMap = 1 + Math::CeilToInt(Math::Log(size) / Math::Log(2.0)); + //return requestedLevel == 0 ? maxMipMap : Math::Min(requestedLevel, maxMipMap); + if (requestedLevel == 0) + requestedLevel = GPU_MAX_TEXTURE_MIP_LEVELS; + int32 maxMipMap = 1; + while (width > 1) + { + width >>= 1; + maxMipMap++; + } + return Math::Min(requestedLevel, maxMipMap); + } +} + +const Char* ToString(TextureDimensions value) +{ + const Char* result; + switch (value) + { + case TextureDimensions::Texture: + result = TEXT("Texture"); + break; + case TextureDimensions::VolumeTexture: + result = TEXT("VolumeTexture"); + break; + case TextureDimensions::CubeTexture: + result = TEXT("CubeTexture"); + break; + default: + result = TEXT(""); + } + return result; +} + +GPUTextureDescription GPUTextureDescription::New1D(int32 width, PixelFormat format, GPUTextureFlags textureFlags, int32 mipCount, int32 arraySize) +{ + GPUTextureDescription desc; + desc.Dimensions = TextureDimensions::Texture; + desc.Width = width; + desc.Height = 1; + desc.Depth = 1; + desc.ArraySize = arraySize; + desc.MipLevels = CalculateMipMapCount(mipCount, width); + desc.Format = format; + desc.MultiSampleLevel = MSAALevel::None; + desc.Flags = textureFlags; + desc.Usage = GPUResourceUsage::Default; + desc.DefaultClearColor = Color::Black; + return desc; +} + +GPUTextureDescription GPUTextureDescription::New2D(int32 width, int32 height, PixelFormat format, GPUTextureFlags textureFlags, int32 mipCount, int32 arraySize, MSAALevel msaaLevel) +{ + GPUTextureDescription desc; + desc.Dimensions = TextureDimensions::Texture; + desc.Width = width; + desc.Height = height; + desc.Depth = 1; + desc.ArraySize = arraySize; + desc.MipLevels = CalculateMipMapCount(mipCount, Math::Max(width, height)); + desc.Format = format; + desc.MultiSampleLevel = msaaLevel; + desc.Flags = textureFlags; + desc.DefaultClearColor = Color::Black; + desc.Usage = GPUResourceUsage::Default; + return desc; +} + +GPUTextureDescription GPUTextureDescription::New3D(const Vector3& size, PixelFormat format, GPUTextureFlags textureFlags) +{ + return New3D((int32)size.X, (int32)size.Y, (int32)size.Z, 1, format, textureFlags); +} + +GPUTextureDescription GPUTextureDescription::New3D(int32 width, int32 height, int32 depth, PixelFormat format, GPUTextureFlags textureFlags, int32 mipCount) +{ + GPUTextureDescription desc; + desc.Dimensions = TextureDimensions::VolumeTexture; + desc.Width = width; + desc.Height = height; + desc.Depth = depth; + desc.ArraySize = 1; + desc.MipLevels = CalculateMipMapCount(mipCount, Math::Max(width, height, depth)); + desc.Format = format; + desc.MultiSampleLevel = MSAALevel::None; + desc.Flags = textureFlags; + desc.DefaultClearColor = Color::Black; + desc.Usage = GPUResourceUsage::Default; + return desc; +} + +GPUTextureDescription GPUTextureDescription::NewCube(int32 size, PixelFormat format, GPUTextureFlags textureFlags, int32 mipCount) +{ + auto desc = New2D(size, size, format, textureFlags, mipCount, 6, MSAALevel::None); + desc.Dimensions = TextureDimensions::CubeTexture; + return desc; +} + +void GPUTextureDescription::Clear() +{ + Platform::MemoryClear(this, sizeof(GPUTextureDescription)); + MultiSampleLevel = MSAALevel::None; +} + +GPUTextureDescription GPUTextureDescription::ToStagingUpload() const +{ + auto copy = *this; + copy.Flags = GPUTextureFlags::None; + copy.Usage = GPUResourceUsage::StagingUpload; + return copy; +} + +GPUTextureDescription GPUTextureDescription::ToStagingReadback() const +{ + auto copy = *this; + copy.Flags = GPUTextureFlags::None; + copy.Usage = GPUResourceUsage::StagingReadback; + return copy; +} + +bool GPUTextureDescription::Equals(const GPUTextureDescription& other) const +{ + return Dimensions == other.Dimensions + && Width == other.Width + && Height == other.Height + && Depth == other.Depth + && ArraySize == other.ArraySize + && MipLevels == other.MipLevels + && Format == other.Format + && MultiSampleLevel == other.MultiSampleLevel + && Flags == other.Flags + && Usage == other.Usage + && Color::NearEqual(DefaultClearColor, other.DefaultClearColor); +} + +String GPUTextureDescription::ToString() const +{ + // TODO: add tool to Format to string + + String flags; + if (Flags == GPUTextureFlags::None) + { + flags = TEXT("None"); + } + else + { + // TODO: create tool to auto convert flag enums to string + +#define CONVERT_FLAGS_FLAGS_2_STR(value) if(Flags & GPUTextureFlags::value) { if (flags.HasChars()) flags += TEXT('|'); flags += TEXT(#value); } + CONVERT_FLAGS_FLAGS_2_STR(ShaderResource); + CONVERT_FLAGS_FLAGS_2_STR(RenderTarget); + CONVERT_FLAGS_FLAGS_2_STR(UnorderedAccess); + CONVERT_FLAGS_FLAGS_2_STR(DepthStencil); + CONVERT_FLAGS_FLAGS_2_STR(PerMipViews); + CONVERT_FLAGS_FLAGS_2_STR(PerSliceViews); + CONVERT_FLAGS_FLAGS_2_STR(ReadOnlyDepthView); + CONVERT_FLAGS_FLAGS_2_STR(BackBuffer); +#undef CONVERT_FLAGS_FLAGS_2_STR + } + + return String::Format(TEXT("Size: {0}x{1}x{2}[{3}], Type: {4}, Mips: {5}, Format: {6}, MSAA: {7}, Flags: {8}, Usage: {9}"), + Width, + Height, + Depth, + ArraySize, + ::ToString(Dimensions), + MipLevels, + (int32)Format, + ::ToString(MultiSampleLevel), + flags, + (int32)Usage); +} + +uint32 GetHash(const GPUTextureDescription& key) +{ + uint32 hashCode = key.Width; + hashCode = (hashCode * 397) ^ key.Height; + hashCode = (hashCode * 397) ^ key.Depth; + hashCode = (hashCode * 397) ^ key.ArraySize; + hashCode = (hashCode * 397) ^ (uint32)key.Dimensions; + hashCode = (hashCode * 397) ^ key.MipLevels; + hashCode = (hashCode * 397) ^ (uint32)key.Format; + hashCode = (hashCode * 397) ^ (uint32)key.MultiSampleLevel; + hashCode = (hashCode * 397) ^ (uint32)key.Flags; + hashCode = (hashCode * 397) ^ (uint32)key.Usage; + hashCode = (hashCode * 397) ^ key.DefaultClearColor.GetHashCode(); + return hashCode; +} + GPUTexture* GPUTexture::Spawn(const SpawnParams& params) { return GPUDevice::Instance->CreateTexture(String::Empty); @@ -422,12 +618,6 @@ private: public: - /// - /// Initializes a new instance of the class. - /// - /// The target texture. - /// The staging texture. - /// The output texture data. TextureDownloadDataTask(GPUTexture* texture, GPUTexture* staging, TextureData& data) : _texture(texture) , _staging(staging) @@ -436,9 +626,6 @@ public: _deleteStaging = texture != staging; } - /// - /// Finalizes an instance of the class. - /// ~TextureDownloadDataTask() { if (_deleteStaging && _staging) diff --git a/Source/Engine/Graphics/Textures/GPUTextureDescription.cpp b/Source/Engine/Graphics/Textures/GPUTextureDescription.cpp deleted file mode 100644 index afd63295d..000000000 --- a/Source/Engine/Graphics/Textures/GPUTextureDescription.cpp +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. - -#include "GPUTextureDescription.h" -#include "Engine/Core/Types/String.h" -#include "Engine/Core/Math/Vector3.h" -#include "Engine/Graphics/Config.h" - -namespace -{ - int32 CalculateMipMapCount(int32 requestedLevel, int32 width) - { - //int32 size = width; - //int32 maxMipMap = 1 + Math::CeilToInt(Math::Log(size) / Math::Log(2.0)); - //return requestedLevel == 0 ? maxMipMap : Math::Min(requestedLevel, maxMipMap); - - if (requestedLevel == 0) - requestedLevel = GPU_MAX_TEXTURE_MIP_LEVELS; - - int32 maxMipMap = 1; - while (width > 1) - { - width >>= 1; - maxMipMap++; - } - - return Math::Min(requestedLevel, maxMipMap); - } -} - -const Char* ToString(TextureDimensions value) -{ - const Char* result; - switch (value) - { - case TextureDimensions::Texture: - result = TEXT("Texture"); - break; - case TextureDimensions::VolumeTexture: - result = TEXT("VolumeTexture"); - break; - case TextureDimensions::CubeTexture: - result = TEXT("CubeTexture"); - break; - default: - result = TEXT(""); - } - return result; -} - -void GPUTextureDescription::Clear() -{ - Platform::MemoryClear(this, sizeof(GPUTextureDescription)); - MultiSampleLevel = MSAALevel::None; -} - -GPUTextureDescription GPUTextureDescription::New1D(int32 width, PixelFormat format, GPUTextureFlags textureFlags, int32 mipCount, int32 arraySize) -{ - GPUTextureDescription desc; - desc.Dimensions = TextureDimensions::Texture; - desc.Width = width; - desc.Height = 1; - desc.Depth = 1; - desc.ArraySize = arraySize; - desc.MipLevels = CalculateMipMapCount(mipCount, width); - desc.Format = format; - desc.MultiSampleLevel = MSAALevel::None; - desc.Flags = textureFlags; - desc.Usage = GPUResourceUsage::Default; - desc.DefaultClearColor = Color::Black; - return desc; -} - -GPUTextureDescription GPUTextureDescription::New2D(int32 width, int32 height, PixelFormat format, GPUTextureFlags textureFlags, int32 mipCount, int32 arraySize, MSAALevel msaaLevel) -{ - GPUTextureDescription desc; - desc.Dimensions = TextureDimensions::Texture; - desc.Width = width; - desc.Height = height; - desc.Depth = 1; - desc.ArraySize = arraySize; - desc.MipLevels = CalculateMipMapCount(mipCount, Math::Max(width, height)); - desc.Format = format; - desc.MultiSampleLevel = msaaLevel; - desc.Flags = textureFlags; - desc.DefaultClearColor = Color::Black; - desc.Usage = GPUResourceUsage::Default; - return desc; -} - -GPUTextureDescription GPUTextureDescription::New3D(const Vector3& size, PixelFormat format, GPUTextureFlags textureFlags) -{ - return New3D((int32)size.X, (int32)size.Y, (int32)size.Z, 1, format, textureFlags); -} - -GPUTextureDescription GPUTextureDescription::New3D(int32 width, int32 height, int32 depth, PixelFormat format, GPUTextureFlags textureFlags, int32 mipCount) -{ - GPUTextureDescription desc; - desc.Dimensions = TextureDimensions::VolumeTexture; - desc.Width = width; - desc.Height = height; - desc.Depth = depth; - desc.ArraySize = 1; - desc.MipLevels = CalculateMipMapCount(mipCount, Math::Max(width, height, depth)); - desc.Format = format; - desc.MultiSampleLevel = MSAALevel::None; - desc.Flags = textureFlags; - desc.DefaultClearColor = Color::Black; - desc.Usage = GPUResourceUsage::Default; - return desc; -} - -GPUTextureDescription GPUTextureDescription::NewCube(int32 size, PixelFormat format, GPUTextureFlags textureFlags, int32 mipCount) -{ - auto desc = New2D(size, size, format, textureFlags, mipCount, 6, MSAALevel::None); - desc.Dimensions = TextureDimensions::CubeTexture; - return desc; -} - -bool GPUTextureDescription::Equals(const GPUTextureDescription& other) const -{ - return Dimensions == other.Dimensions - && Width == other.Width - && Height == other.Height - && Depth == other.Depth - && ArraySize == other.ArraySize - && MipLevels == other.MipLevels - && Format == other.Format - && MultiSampleLevel == other.MultiSampleLevel - && Flags == other.Flags - && Usage == other.Usage - && Color::NearEqual(DefaultClearColor, other.DefaultClearColor); -} - -String GPUTextureDescription::ToString() const -{ - // TODO: add tool to Format to string - - String flags; - if (Flags == GPUTextureFlags::None) - { - flags = TEXT("None"); - } - else - { - // TODO: create tool to auto convert flag enums to string - -#define CONVERT_FLAGS_FLAGS_2_STR(value) if(Flags & GPUTextureFlags::value) { if (flags.HasChars()) flags += TEXT('|'); flags += TEXT(#value); } - CONVERT_FLAGS_FLAGS_2_STR(ShaderResource); - CONVERT_FLAGS_FLAGS_2_STR(RenderTarget); - CONVERT_FLAGS_FLAGS_2_STR(UnorderedAccess); - CONVERT_FLAGS_FLAGS_2_STR(DepthStencil); - CONVERT_FLAGS_FLAGS_2_STR(PerMipViews); - CONVERT_FLAGS_FLAGS_2_STR(PerSliceViews); - CONVERT_FLAGS_FLAGS_2_STR(ReadOnlyDepthView); - CONVERT_FLAGS_FLAGS_2_STR(BackBuffer); -#undef CONVERT_FLAGS_FLAGS_2_STR - } - - return String::Format(TEXT("Size: {0}x{1}x{2}[{3}], Type: {4}, Mips: {5}, Format: {6}, MSAA: {7}, Flags: {8}, Usage: {9}"), - Width, - Height, - Depth, - ArraySize, - ::ToString(Dimensions), - MipLevels, - (int32)Format, - ::ToString(MultiSampleLevel), - flags, - (int32)Usage); -} - -uint32 GetHash(const GPUTextureDescription& key) -{ - uint32 hashCode = key.Width; - hashCode = (hashCode * 397) ^ key.Height; - hashCode = (hashCode * 397) ^ key.Depth; - hashCode = (hashCode * 397) ^ key.ArraySize; - hashCode = (hashCode * 397) ^ (uint32)key.Dimensions; - hashCode = (hashCode * 397) ^ key.MipLevels; - hashCode = (hashCode * 397) ^ (uint32)key.Format; - hashCode = (hashCode * 397) ^ (uint32)key.MultiSampleLevel; - hashCode = (hashCode * 397) ^ (uint32)key.Flags; - hashCode = (hashCode * 397) ^ (uint32)key.Usage; - hashCode = (hashCode * 397) ^ key.DefaultClearColor.GetHashCode(); - return hashCode; -} diff --git a/Source/Engine/Graphics/Textures/GPUTextureDescription.h b/Source/Engine/Graphics/Textures/GPUTextureDescription.h index 6caadefb5..92557a9c0 100644 --- a/Source/Engine/Graphics/Textures/GPUTextureDescription.h +++ b/Source/Engine/Graphics/Textures/GPUTextureDescription.h @@ -80,8 +80,6 @@ API_ENUM() enum class TextureDimensions CubeTexture, }; -const Char* ToString(TextureDimensions value); - /// /// A common description for all GPU textures. /// @@ -226,13 +224,6 @@ public: return ArraySize != 1; } -public: - - /// - /// Clears description. - /// - void Clear(); - public: /// @@ -408,63 +399,24 @@ public: static GPUTextureDescription NewCube(int32 size, PixelFormat format, GPUTextureFlags textureFlags, int32 mipCount); public: - - /// - /// Gets the staging description for this instance. - /// - /// A staging texture description - GPUTextureDescription ToStagingUpload() const - { - auto copy = *this; - copy.Flags = GPUTextureFlags::None; - copy.Usage = GPUResourceUsage::StagingUpload; - return copy; - } - - /// - /// Gets the staging description for this instance. - /// - /// A staging texture description - GPUTextureDescription ToStagingReadback() const - { - auto copy = *this; - copy.Flags = GPUTextureFlags::None; - copy.Usage = GPUResourceUsage::StagingReadback; - return copy; - } + + void Clear(); + GPUTextureDescription ToStagingUpload() const; + GPUTextureDescription ToStagingReadback() const; + bool Equals(const GPUTextureDescription& other) const; + String ToString() const; public: - /// - /// Compares with other instance of GPUTextureDescription - /// - /// The other object to compare. - /// True if objects are the same, otherwise false. - bool Equals(const GPUTextureDescription& other) const; - - /// - /// Implements the operator ==. - /// - /// The other description. - /// The result of the operator. FORCE_INLINE bool operator==(const GPUTextureDescription& other) const { return Equals(other); } - /// - /// Implements the operator !=. - /// - /// The other description. - /// The result of the operator. FORCE_INLINE bool operator!=(const GPUTextureDescription& other) const { return !Equals(other); } - -public: - - String ToString() const; }; uint32 GetHash(const GPUTextureDescription& key); diff --git a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUDeviceDX11.cpp b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUDeviceDX11.cpp index 2f7560141..b0db7da93 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUDeviceDX11.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUDeviceDX11.cpp @@ -345,7 +345,7 @@ bool GPUDeviceDX11::Init() limits.MaximumTexture2DSize = D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; limits.MaximumTexture2DArraySize = D3D10_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION; limits.MaximumTexture3DSize = D3D10_REQ_TEXTURE3D_U_V_OR_W_DIMENSION; - limits.MaximumTextureCubeSize = D3D11_REQ_TEXTURECUBE_DIMENSION; + limits.MaximumTextureCubeSize = D3D10_REQ_TEXTURECUBE_DIMENSION; } for (int32 i = 0; i < static_cast(PixelFormat::MAX); i++) diff --git a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUDeviceDX11.h b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUDeviceDX11.h index 7b9bc367c..d75c0b88a 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUDeviceDX11.h +++ b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUDeviceDX11.h @@ -46,20 +46,8 @@ private: public: - // Create new graphics device (returns null if failed) - // @returns Created device or null static GPUDevice* Create(); - - /// - /// Initializes a new instance of the class. - /// - /// The DXGI factory handle. - /// The GPU device adapter. GPUDeviceDX11(IDXGIFactory* dxgiFactory, GPUAdapterDX* adapter); - - /// - /// Finalizes an instance of the class. - /// ~GPUDeviceDX11(); public: @@ -122,9 +110,8 @@ class IGPUResourceDX11 public: /// - /// Gets DirectX 11 resource object handle + /// Gets DirectX 11 resource object handle. /// - /// DirectX 11 resource object handle virtual ID3D11Resource* GetResource() = 0; }; diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.cpp b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.cpp index b2af2e6d7..fa5e698d5 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.cpp @@ -327,7 +327,6 @@ bool GPUDeviceDX12::Init() LOG(Info, "Resource Binding Tier: {0}", options.ResourceBindingTier); LOG(Info, "Conservative Rasterization Tier: {0}", options.ConservativeRasterizationTier); LOG(Info, "Resource Heap Tier: {0}", options.ResourceHeapTier); - LOG(Info, "ROVs Supported: {0}", options.ROVsSupported != 0); // Init device limits { diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.h b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.h index 940be58c3..f14305ea7 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.h +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.h @@ -60,20 +60,8 @@ private: public: - // Create new graphics device (returns null if failed) - // @returns Created device or null static GPUDevice* Create(); - - /// - /// Initializes a new instance of the class. - /// - /// The DXGI factory handle. - /// The GPU device adapter. GPUDeviceDX12(IDXGIFactory4* dxgiFactory, GPUAdapterDX* adapter); - - /// - /// Finalizes an instance of the class. - /// ~GPUDeviceDX12(); public: diff --git a/Source/Engine/GraphicsDevice/Null/GPUDeviceNull.h b/Source/Engine/GraphicsDevice/Null/GPUDeviceNull.h index d13166a27..2562a2744 100644 --- a/Source/Engine/GraphicsDevice/Null/GPUDeviceNull.h +++ b/Source/Engine/GraphicsDevice/Null/GPUDeviceNull.h @@ -26,18 +26,8 @@ private: public: - // Create new graphics device (returns null if failed) - // @returns Created device or null static GPUDevice* Create(); - - /// - /// Initializes a new instance of the class. - /// GPUDeviceNull(); - - /// - /// Finalizes an instance of the class. - /// ~GPUDeviceNull(); public: diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp index 5c9a7032a..2ad04d2cb 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp @@ -734,7 +734,7 @@ VkSampler HelperResourcesVulkan::GetStaticSampler(StaticSamplers type) { if (!_staticSamplers[0]) { - const bool supportsMirrorClampToEdge = _device->OptionalDeviceExtensions.HasMirrorClampToEdge; + const bool supportsMirrorClampToEdge = GPUDeviceVulkan::OptionalDeviceExtensions.HasMirrorClampToEdge; VkSamplerCreateInfo createInfo; RenderToolsVulkan::ZeroStruct(createInfo, VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO);