// 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);