// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. #pragma once #include "Engine/Core/Math/Color.h" #include "Engine/Graphics/PixelFormat.h" #include "Engine/Graphics/Enums.h" /// /// GPU texture usage flags. /// API_ENUM(Attributes="Flags") enum class GPUTextureFlags { /// /// No texture flags. /// None = 0x0000, /// /// Create a texture that can be bound as a shader resource. /// ShaderResource = 0x0001, /// /// Create a texture that can be bound as a render target. /// RenderTarget = 0x0002, /// /// Create a texture can be bound as an unordered access buffer. /// UnorderedAccess = 0x0004, /// /// Create a texture can be bound as a depth stencil buffer. /// DepthStencil = 0x0008, /// /// Create texture views per texture mip map (valid only for Texture2D with ShaderResource or RenderTarget flag). /// PerMipViews = 0x0010, /// /// Create texture views per texture slice map (valid only for Texture3D with ShaderResource or RenderTarget flag). /// PerSliceViews = 0x0020, /// /// Create read-only view for depth-stencil buffer. Valid only if texture uses depth-stencil and the graphics device supports it. /// ReadOnlyDepthView = 0x0040, /// /// Create a texture that can be used as a native window swap chain backbuffer surface. /// BackBuffer = 0x0080, }; DECLARE_ENUM_OPERATORS(GPUTextureFlags); /// /// Defines the dimension of a texture object. /// API_ENUM() enum class TextureDimensions { /// /// The texture (2d). /// Texture, /// /// The volume texture (3d texture). /// VolumeTexture, /// /// The cube texture (2d texture array of 6 items). /// CubeTexture, }; /// /// A common description for all GPU textures. /// API_STRUCT() struct FLAXENGINE_API GPUTextureDescription { DECLARE_SCRIPTING_TYPE_MINIMAL(GPUTextureDescription); /// /// The dimensions of the texture. /// API_FIELD() TextureDimensions Dimensions; /// /// Texture width (in texels). /// API_FIELD() int32 Width; /// /// Texture height (in texels). /// API_FIELD() int32 Height; /// /// Texture depth (in texels) for Volume Textures. /// API_FIELD() int32 Depth; /// /// Number of textures in array for Texture Arrays. /// API_FIELD() int32 ArraySize; /// /// The maximum number of mipmap levels in the texture. Use 1 for a multisampled texture; or 0 to generate a full set of subtextures. /// API_FIELD() int32 MipLevels; /// /// Texture format (see ). /// API_FIELD() PixelFormat Format; /// /// Structure that specifies multisampling parameters for the texture. /// API_FIELD() MSAALevel MultiSampleLevel; /// /// Flags (see ) for binding to pipeline stages. The flags can be combined by a logical OR. /// API_FIELD() GPUTextureFlags Flags; /// /// Value that identifies how the texture is to be read from and written to. The most common value is ; see for all possible values. /// API_FIELD() GPUResourceUsage Usage; /// /// Default clear color for render targets /// API_FIELD() Color DefaultClearColor; public: /// /// Gets a value indicating whether this instance is a render target. /// FORCE_INLINE bool IsRenderTarget() const { return (Flags & GPUTextureFlags::RenderTarget) != GPUTextureFlags::None; } /// /// Gets a value indicating whether this instance is a depth stencil. /// FORCE_INLINE bool IsDepthStencil() const { return (Flags & GPUTextureFlags::DepthStencil) != GPUTextureFlags::None; } /// /// Gets a value indicating whether this instance is a shader resource. /// FORCE_INLINE bool IsShaderResource() const { return (Flags & GPUTextureFlags::ShaderResource) != GPUTextureFlags::None; } /// /// Gets a value indicating whether this instance is a unordered access. /// FORCE_INLINE bool IsUnorderedAccess() const { return (Flags & GPUTextureFlags::UnorderedAccess) != GPUTextureFlags::None; } /// /// Gets a value indicating whether this instance has per mip level handles. /// FORCE_INLINE bool HasPerMipViews() const { return (Flags & GPUTextureFlags::PerMipViews) != GPUTextureFlags::None; } /// /// Gets a value indicating whether this instance has per slice views. /// FORCE_INLINE bool HasPerSliceViews() const { return (Flags & GPUTextureFlags::PerSliceViews) != GPUTextureFlags::None; } /// /// Gets a value indicating whether this instance is a multi sample texture. /// FORCE_INLINE bool IsMultiSample() const { return MultiSampleLevel > MSAALevel::None; } /// /// Gets a value indicating whether this instance is a cubemap texture. /// FORCE_INLINE bool IsCubeMap() const { return Dimensions == TextureDimensions::CubeTexture; } /// /// Gets a value indicating whether this instance is a volume texture. /// FORCE_INLINE bool IsVolume() const { return Dimensions == TextureDimensions::VolumeTexture; } /// /// Gets a value indicating whether this instance is an array texture. /// FORCE_INLINE bool IsArray() const { return ArraySize != 1; } public: /// /// Creates a new 1D with a single mipmap. /// /// The width. /// Describes the format to use. /// true if the texture needs to support unordered read write. /// Size of the texture 2D array, default to 1. /// A new instance of 1D class. static GPUTextureDescription New1D(int32 width, PixelFormat format, GPUTextureFlags textureFlags = GPUTextureFlags::ShaderResource | GPUTextureFlags::RenderTarget, int32 arraySize = 1) { return New1D(width, format, textureFlags, 1, arraySize); } /// /// Creates a new 1D . /// /// The width. /// Number of mipmaps for the texture. Default is 1. Use 0 to allocate full mip chain. /// Describes the format to use. /// true if the texture needs to support unordered read write. /// Size of the texture 2D array, default to 1. /// A new instance of 1D class. static GPUTextureDescription New1D(int32 width, int32 mipCount, PixelFormat format, GPUTextureFlags textureFlags = GPUTextureFlags::ShaderResource | GPUTextureFlags::RenderTarget, int32 arraySize = 1) { return New1D(width, format, textureFlags, mipCount, arraySize); } /// /// Creates a new 1D . /// /// The width. /// Describes the format to use. /// true if the texture needs to support unordered read write. /// Number of mipmaps for the texture. Default is 1. Use 0 to allocate full mip chain. /// Size of the texture 2D array, default to 1. /// A new instance of 1D class. static GPUTextureDescription New1D(int32 width, PixelFormat format, GPUTextureFlags textureFlags, int32 mipCount, int32 arraySize); public: /// /// Creates a new with a single mipmap. /// /// The width. /// The height. /// Describes the format to use. /// true if the texture needs to support unordered read write. /// Size of the texture 2D array, default to 1. /// A new instance of class. static GPUTextureDescription New2D(int32 width, int32 height, PixelFormat format, GPUTextureFlags textureFlags = GPUTextureFlags::ShaderResource | GPUTextureFlags::RenderTarget, int32 arraySize = 1) { return New2D(width, height, 1, format, textureFlags, arraySize); } /// /// Creates a new . /// /// The width. /// The height. /// Number of mipmaps for the texture. Default is 1. Use 0 to allocate full mip chain. /// Describes the format to use. /// true if the texture needs to support unordered read write. /// Size of the texture 2D array, default to 1. /// The MSAA Level. /// A new instance of class. static GPUTextureDescription New2D(int32 width, int32 height, int32 mipCount, PixelFormat format, GPUTextureFlags textureFlags = GPUTextureFlags::ShaderResource | GPUTextureFlags::RenderTarget, int32 arraySize = 1, MSAALevel msaaLevel = MSAALevel::None) { return New2D(width, height, format, textureFlags, mipCount, arraySize, msaaLevel); } /// /// Creates a new . /// /// The width. /// The height. /// Describes the format to use. /// true if the texture needs to support unordered read write. /// Number of mipmaps for the texture. Default is 1. Use 0 to allocate full mip chain. /// Size of the texture 2D array, default to 1. /// The MSAA Level. /// A new instance of class. static GPUTextureDescription New2D(int32 width, int32 height, PixelFormat format, GPUTextureFlags textureFlags, int32 mipCount, int32 arraySize, MSAALevel msaaLevel = MSAALevel::None); public: /// /// Creates a new with a single mipmap. /// /// The size (width, height and depth). /// Describes the format to use. /// true if the texture needs to support unordered read write. /// A new instance of class. static GPUTextureDescription New3D(const Float3& size, PixelFormat format, GPUTextureFlags textureFlags = GPUTextureFlags::ShaderResource | GPUTextureFlags::RenderTarget); /// /// Creates a new with a single mipmap. /// /// The width. /// The height. /// The depth. /// Describes the format to use. /// true if the texture needs to support unordered read write. /// A new instance of class. static GPUTextureDescription New3D(int32 width, int32 height, int32 depth, PixelFormat format, GPUTextureFlags textureFlags = GPUTextureFlags::ShaderResource | GPUTextureFlags::RenderTarget) { return New3D(width, height, depth, 1, format, textureFlags); } /// /// Creates a new . /// /// The width. /// The height. /// The depth. /// Number of mipmaps for the texture. Default is 1. Use 0 to allocate full mip chain. /// Describes the format to use. /// true if the texture needs to support unordered read write. /// A new instance of class. static GPUTextureDescription New3D(int32 width, int32 height, int32 depth, int32 mipCount, PixelFormat format, GPUTextureFlags textureFlags = GPUTextureFlags::ShaderResource | GPUTextureFlags::RenderTarget) { return New3D(width, height, depth, format, textureFlags, mipCount); } /// /// Creates a new . /// /// The width. /// The height. /// The depth. /// Describes the format to use. /// true if the texture needs to support unordered read write. /// Number of mipmaps for the texture. Default is 1. Use 0 to allocate full mip chain. /// A new instance of class. static GPUTextureDescription New3D(int32 width, int32 height, int32 depth, PixelFormat format, GPUTextureFlags textureFlags, int32 mipCount); public: /// /// Creates a new Cube . /// /// The size (in pixels) of the top-level faces of the cube texture. /// Describes the format to use. /// The texture flags. /// A new instance of class. static GPUTextureDescription NewCube(int32 size, PixelFormat format, GPUTextureFlags textureFlags = GPUTextureFlags::ShaderResource | GPUTextureFlags::RenderTarget) { return NewCube(size, 1, format, textureFlags); } /// /// Creates a new Cube . /// /// The size (in pixels) of the top-level faces of the cube texture. /// Number of mipmaps for the texture. Default is 1. Use 0 to allocate full mip chain. /// Describes the format to use. /// The texture flags. /// A new instance of class. static GPUTextureDescription NewCube(int32 size, int32 mipCount, PixelFormat format, GPUTextureFlags textureFlags = GPUTextureFlags::ShaderResource | GPUTextureFlags::RenderTarget) { return NewCube(size, format, textureFlags, mipCount); } /// /// Creates a new Cube . /// /// The size (in pixels) of the top-level faces of the cube texture. /// Describes the format to use. /// The texture flags. /// Number of mipmaps for the texture. Default is 1. Use 0 to allocate full mip chain. /// A new instance of class. static GPUTextureDescription NewCube(int32 size, PixelFormat format, GPUTextureFlags textureFlags, int32 mipCount); public: void Clear(); GPUTextureDescription ToStagingUpload() const; GPUTextureDescription ToStagingReadback() const; bool Equals(const GPUTextureDescription& other) const; String ToString() const; public: FORCE_INLINE bool operator==(const GPUTextureDescription& other) const { return Equals(other); } FORCE_INLINE bool operator!=(const GPUTextureDescription& other) const { return !Equals(other); } }; uint32 GetHash(const GPUTextureDescription& key);