2021-01-20 03:33:27 +00:00
|
|
|
|
using System;
|
2022-05-12 04:22:20 +00:00
|
|
|
|
using System.IO;
|
2021-01-20 03:33:27 +00:00
|
|
|
|
using RefreshCS;
|
|
|
|
|
|
|
|
|
|
namespace MoonWorks.Graphics
|
|
|
|
|
{
|
2022-02-23 05:14:32 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// A container for pixel data.
|
|
|
|
|
/// </summary>
|
2023-12-15 18:46:43 +00:00
|
|
|
|
public class Texture : RefreshResource
|
2022-02-23 05:14:32 +00:00
|
|
|
|
{
|
2022-12-13 08:52:35 +00:00
|
|
|
|
public uint Width { get; internal set; }
|
|
|
|
|
public uint Height { get; internal set; }
|
2022-02-23 05:14:32 +00:00
|
|
|
|
public uint Depth { get; }
|
2022-12-13 08:52:35 +00:00
|
|
|
|
public TextureFormat Format { get; internal set; }
|
2022-02-23 05:14:32 +00:00
|
|
|
|
public bool IsCube { get; }
|
|
|
|
|
public uint LevelCount { get; }
|
2023-01-31 20:27:26 +00:00
|
|
|
|
public SampleCount SampleCount { get; }
|
2022-02-23 05:14:32 +00:00
|
|
|
|
public TextureUsageFlags UsageFlags { get; }
|
2024-01-16 06:19:59 +00:00
|
|
|
|
public uint Size { get; }
|
2022-02-23 05:14:32 +00:00
|
|
|
|
|
2022-12-13 08:52:35 +00:00
|
|
|
|
// FIXME: this allocates a delegate instance
|
2022-03-04 01:16:39 +00:00
|
|
|
|
protected override Action<IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyTexture;
|
2022-02-23 05:14:32 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Creates a 2D texture.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="device">An initialized GraphicsDevice.</param>
|
|
|
|
|
/// <param name="width">The width of the texture.</param>
|
|
|
|
|
/// <param name="height">The height of the texture.</param>
|
|
|
|
|
/// <param name="format">The format of the texture.</param>
|
|
|
|
|
/// <param name="usageFlags">Specifies how the texture will be used.</param>
|
|
|
|
|
/// <param name="levelCount">Specifies the number of mip levels.</param>
|
|
|
|
|
public static Texture CreateTexture2D(
|
|
|
|
|
GraphicsDevice device,
|
|
|
|
|
uint width,
|
|
|
|
|
uint height,
|
|
|
|
|
TextureFormat format,
|
|
|
|
|
TextureUsageFlags usageFlags,
|
2023-01-31 20:27:26 +00:00
|
|
|
|
uint levelCount = 1,
|
|
|
|
|
SampleCount sampleCount = SampleCount.One
|
|
|
|
|
) {
|
2022-02-23 05:14:32 +00:00
|
|
|
|
var textureCreateInfo = new TextureCreateInfo
|
|
|
|
|
{
|
|
|
|
|
Width = width,
|
|
|
|
|
Height = height,
|
|
|
|
|
Depth = 1,
|
|
|
|
|
IsCube = false,
|
|
|
|
|
LevelCount = levelCount,
|
2023-01-31 20:27:26 +00:00
|
|
|
|
SampleCount = sampleCount,
|
2022-02-23 05:14:32 +00:00
|
|
|
|
Format = format,
|
|
|
|
|
UsageFlags = usageFlags
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return new Texture(device, textureCreateInfo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Creates a 3D texture.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="device">An initialized GraphicsDevice.</param>
|
|
|
|
|
/// <param name="width">The width of the texture.</param>
|
|
|
|
|
/// <param name="height">The height of the texture.</param>
|
|
|
|
|
/// <param name="depth">The depth of the texture.</param>
|
|
|
|
|
/// <param name="format">The format of the texture.</param>
|
|
|
|
|
/// <param name="usageFlags">Specifies how the texture will be used.</param>
|
|
|
|
|
/// <param name="levelCount">Specifies the number of mip levels.</param>
|
|
|
|
|
public static Texture CreateTexture3D(
|
|
|
|
|
GraphicsDevice device,
|
|
|
|
|
uint width,
|
|
|
|
|
uint height,
|
|
|
|
|
uint depth,
|
|
|
|
|
TextureFormat format,
|
|
|
|
|
TextureUsageFlags usageFlags,
|
|
|
|
|
uint levelCount = 1
|
2023-01-31 20:27:26 +00:00
|
|
|
|
) {
|
2022-02-23 05:14:32 +00:00
|
|
|
|
var textureCreateInfo = new TextureCreateInfo
|
|
|
|
|
{
|
|
|
|
|
Width = width,
|
|
|
|
|
Height = height,
|
|
|
|
|
Depth = depth,
|
|
|
|
|
IsCube = false,
|
|
|
|
|
LevelCount = levelCount,
|
|
|
|
|
Format = format,
|
|
|
|
|
UsageFlags = usageFlags
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return new Texture(device, textureCreateInfo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Creates a cube texture.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="device">An initialized GraphicsDevice.</param>
|
|
|
|
|
/// <param name="size">The length of one side of the cube.</param>
|
|
|
|
|
/// <param name="format">The format of the texture.</param>
|
|
|
|
|
/// <param name="usageFlags">Specifies how the texture will be used.</param>
|
|
|
|
|
/// <param name="levelCount">Specifies the number of mip levels.</param>
|
|
|
|
|
public static Texture CreateTextureCube(
|
|
|
|
|
GraphicsDevice device,
|
|
|
|
|
uint size,
|
|
|
|
|
TextureFormat format,
|
|
|
|
|
TextureUsageFlags usageFlags,
|
|
|
|
|
uint levelCount = 1
|
2023-01-31 20:27:26 +00:00
|
|
|
|
) {
|
2022-02-23 05:14:32 +00:00
|
|
|
|
var textureCreateInfo = new TextureCreateInfo
|
|
|
|
|
{
|
|
|
|
|
Width = size,
|
|
|
|
|
Height = size,
|
|
|
|
|
Depth = 1,
|
|
|
|
|
IsCube = true,
|
|
|
|
|
LevelCount = levelCount,
|
|
|
|
|
Format = format,
|
|
|
|
|
UsageFlags = usageFlags
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return new Texture(device, textureCreateInfo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Creates a new texture using a TextureCreateInfo struct.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="device">An initialized GraphicsDevice.</param>
|
|
|
|
|
/// <param name="textureCreateInfo">The parameters to use when creating the texture.</param>
|
|
|
|
|
public Texture(
|
|
|
|
|
GraphicsDevice device,
|
|
|
|
|
in TextureCreateInfo textureCreateInfo
|
|
|
|
|
) : base(device)
|
|
|
|
|
{
|
|
|
|
|
Handle = Refresh.Refresh_CreateTexture(
|
|
|
|
|
device.Handle,
|
|
|
|
|
textureCreateInfo.ToRefreshTextureCreateInfo()
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
Format = textureCreateInfo.Format;
|
|
|
|
|
Width = textureCreateInfo.Width;
|
|
|
|
|
Height = textureCreateInfo.Height;
|
|
|
|
|
Depth = textureCreateInfo.Depth;
|
|
|
|
|
IsCube = textureCreateInfo.IsCube;
|
|
|
|
|
LevelCount = textureCreateInfo.LevelCount;
|
2023-01-31 20:27:26 +00:00
|
|
|
|
SampleCount = textureCreateInfo.SampleCount;
|
2022-02-23 05:14:32 +00:00
|
|
|
|
UsageFlags = textureCreateInfo.UsageFlags;
|
2024-01-16 06:19:59 +00:00
|
|
|
|
Size = Width * Height * BytesPerPixel(Format) / BlockSizeSquared(Format);
|
2022-02-23 05:14:32 +00:00
|
|
|
|
}
|
2022-03-02 06:57:10 +00:00
|
|
|
|
|
2022-03-24 06:07:34 +00:00
|
|
|
|
public static implicit operator TextureSlice(Texture t) => new TextureSlice(t);
|
|
|
|
|
|
2022-03-02 06:57:10 +00:00
|
|
|
|
// Used by AcquireSwapchainTexture.
|
2022-03-02 07:21:42 +00:00
|
|
|
|
// Should not be tracked, because swapchain textures are managed by Vulkan.
|
2022-03-02 06:57:10 +00:00
|
|
|
|
internal Texture(
|
2024-01-16 06:19:59 +00:00
|
|
|
|
GraphicsDevice device,
|
|
|
|
|
TextureFormat format
|
2023-10-04 21:45:17 +00:00
|
|
|
|
) : base(device)
|
2022-03-02 06:57:10 +00:00
|
|
|
|
{
|
2023-10-04 21:45:17 +00:00
|
|
|
|
Handle = IntPtr.Zero;
|
2022-03-02 06:57:10 +00:00
|
|
|
|
|
2024-01-16 06:19:59 +00:00
|
|
|
|
Format = format;
|
2023-10-04 21:45:17 +00:00
|
|
|
|
Width = 0;
|
|
|
|
|
Height = 0;
|
2022-03-02 06:57:10 +00:00
|
|
|
|
Depth = 1;
|
|
|
|
|
IsCube = false;
|
|
|
|
|
LevelCount = 1;
|
2023-01-31 20:27:26 +00:00
|
|
|
|
SampleCount = SampleCount.One;
|
2022-03-02 06:57:10 +00:00
|
|
|
|
UsageFlags = TextureUsageFlags.ColorTarget;
|
2024-01-16 06:19:59 +00:00
|
|
|
|
Size = Width * Height * BytesPerPixel(Format) / BlockSizeSquared(Format);
|
2022-03-02 06:57:10 +00:00
|
|
|
|
}
|
2022-05-12 04:22:20 +00:00
|
|
|
|
|
2024-01-16 06:19:59 +00:00
|
|
|
|
public static uint BytesPerPixel(TextureFormat format)
|
|
|
|
|
{
|
|
|
|
|
switch (format)
|
|
|
|
|
{
|
|
|
|
|
case TextureFormat.R8:
|
|
|
|
|
case TextureFormat.R8_UINT:
|
|
|
|
|
return 1;
|
|
|
|
|
case TextureFormat.R5G6B5:
|
|
|
|
|
case TextureFormat.B4G4R4A4:
|
|
|
|
|
case TextureFormat.A1R5G5B5:
|
|
|
|
|
case TextureFormat.R16_SFLOAT:
|
|
|
|
|
case TextureFormat.R8G8_SNORM:
|
|
|
|
|
case TextureFormat.R8G8_UINT:
|
|
|
|
|
case TextureFormat.R16_UINT:
|
|
|
|
|
case TextureFormat.D16:
|
|
|
|
|
return 2;
|
|
|
|
|
case TextureFormat.D16S8:
|
|
|
|
|
return 3;
|
|
|
|
|
case TextureFormat.R8G8B8A8:
|
|
|
|
|
case TextureFormat.B8G8R8A8:
|
|
|
|
|
case TextureFormat.R32_SFLOAT:
|
|
|
|
|
case TextureFormat.R16G16:
|
|
|
|
|
case TextureFormat.R16G16_SFLOAT:
|
|
|
|
|
case TextureFormat.R8G8B8A8_SNORM:
|
|
|
|
|
case TextureFormat.A2R10G10B10:
|
|
|
|
|
case TextureFormat.R8G8B8A8_UINT:
|
|
|
|
|
case TextureFormat.R16G16_UINT:
|
|
|
|
|
case TextureFormat.D32:
|
|
|
|
|
return 4;
|
|
|
|
|
case TextureFormat.D32S8:
|
|
|
|
|
return 5;
|
|
|
|
|
case TextureFormat.R16G16B16A16_SFLOAT:
|
|
|
|
|
case TextureFormat.R16G16B16A16:
|
|
|
|
|
case TextureFormat.R32G32_SFLOAT:
|
|
|
|
|
case TextureFormat.R16G16B16A16_UINT:
|
|
|
|
|
case TextureFormat.BC1:
|
|
|
|
|
return 8;
|
|
|
|
|
case TextureFormat.R32G32B32A32_SFLOAT:
|
|
|
|
|
case TextureFormat.BC2:
|
|
|
|
|
case TextureFormat.BC3:
|
|
|
|
|
case TextureFormat.BC7:
|
|
|
|
|
return 16;
|
|
|
|
|
default:
|
|
|
|
|
Logger.LogError("Texture format not recognized!");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-23 19:59:33 +00:00
|
|
|
|
public static uint TexelSize(TextureFormat format)
|
|
|
|
|
{
|
|
|
|
|
switch (format)
|
|
|
|
|
{
|
|
|
|
|
case TextureFormat.BC2:
|
|
|
|
|
case TextureFormat.BC3:
|
|
|
|
|
case TextureFormat.BC7:
|
|
|
|
|
return 16;
|
|
|
|
|
case TextureFormat.BC1:
|
|
|
|
|
return 8;
|
|
|
|
|
default:
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-16 06:19:59 +00:00
|
|
|
|
public static uint BlockSizeSquared(TextureFormat format)
|
|
|
|
|
{
|
|
|
|
|
switch (format)
|
|
|
|
|
{
|
|
|
|
|
case TextureFormat.BC1:
|
|
|
|
|
case TextureFormat.BC2:
|
|
|
|
|
case TextureFormat.BC3:
|
|
|
|
|
case TextureFormat.BC7:
|
|
|
|
|
return 16;
|
|
|
|
|
case TextureFormat.R8G8B8A8:
|
|
|
|
|
case TextureFormat.B8G8R8A8:
|
|
|
|
|
case TextureFormat.R5G6B5:
|
|
|
|
|
case TextureFormat.A1R5G5B5:
|
|
|
|
|
case TextureFormat.B4G4R4A4:
|
|
|
|
|
case TextureFormat.A2R10G10B10:
|
|
|
|
|
case TextureFormat.R16G16:
|
|
|
|
|
case TextureFormat.R16G16B16A16:
|
|
|
|
|
case TextureFormat.R8:
|
|
|
|
|
case TextureFormat.R8G8_SNORM:
|
|
|
|
|
case TextureFormat.R8G8B8A8_SNORM:
|
|
|
|
|
case TextureFormat.R16_SFLOAT:
|
|
|
|
|
case TextureFormat.R16G16_SFLOAT:
|
|
|
|
|
case TextureFormat.R16G16B16A16_SFLOAT:
|
|
|
|
|
case TextureFormat.R32_SFLOAT:
|
|
|
|
|
case TextureFormat.R32G32_SFLOAT:
|
|
|
|
|
case TextureFormat.R32G32B32A32_SFLOAT:
|
|
|
|
|
case TextureFormat.R8_UINT:
|
|
|
|
|
case TextureFormat.R8G8_UINT:
|
|
|
|
|
case TextureFormat.R8G8B8A8_UINT:
|
|
|
|
|
case TextureFormat.R16_UINT:
|
|
|
|
|
case TextureFormat.R16G16_UINT:
|
|
|
|
|
case TextureFormat.R16G16B16A16_UINT:
|
|
|
|
|
case TextureFormat.D16:
|
|
|
|
|
case TextureFormat.D32:
|
|
|
|
|
case TextureFormat.D16S8:
|
|
|
|
|
case TextureFormat.D32S8:
|
|
|
|
|
return 1;
|
|
|
|
|
default:
|
|
|
|
|
Logger.LogError("Texture format not recognized!");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-02-23 05:14:32 +00:00
|
|
|
|
}
|
2021-01-20 03:33:27 +00:00
|
|
|
|
}
|