language feature: Extension Members: Ryujinx.Graphics.GAL.Format

This commit is contained in:
GreemDev 2025-07-02 02:58:30 -05:00
parent 00b784e046
commit 6c5f21e4e9
24 changed files with 235 additions and 630 deletions

View file

@ -158,559 +158,132 @@ namespace Ryujinx.Graphics.GAL
/// </summary> /// </summary>
public const int MaxBufferFormatScalarSize = 4; public const int MaxBufferFormatScalarSize = 4;
extension(Format fmt)
{
/// <summary> /// <summary>
/// Gets the byte size for a single component of this format, or its packed size. /// Gets the byte size for a single component of this format, or its packed size.
/// </summary> /// </summary>
/// <param name="format">Texture format</param> public int ScalarSize => fmt switch
/// <returns>Byte size for a single component, or packed size</returns>
public static int GetScalarSize(this Format format)
{ {
switch (format) Format.R8Unorm or Format.R8Snorm or Format.R8Uint or Format.R8Sint or Format.R8G8Unorm
{ or Format.R8G8Snorm or Format.R8G8Uint or Format.R8G8Sint or Format.R8G8B8Unorm
case Format.R8Unorm: or Format.R8G8B8Snorm or Format.R8G8B8Uint or Format.R8G8B8Sint or Format.R8G8B8A8Unorm
case Format.R8Snorm: or Format.R8G8B8A8Snorm or Format.R8G8B8A8Uint or Format.R8G8B8A8Sint or Format.R8G8B8A8Srgb
case Format.R8Uint: or Format.R4G4Unorm or Format.R8Uscaled or Format.R8Sscaled or Format.R8G8Uscaled
case Format.R8Sint: or Format.R8G8Sscaled or Format.R8G8B8Uscaled or Format.R8G8B8Sscaled or Format.R8G8B8A8Uscaled
case Format.R8G8Unorm: or Format.R8G8B8A8Sscaled or Format.B8G8R8A8Unorm or Format.B8G8R8A8Srgb => 1,
case Format.R8G8Snorm: Format.R16Float or Format.R16Unorm or Format.R16Snorm or Format.R16Uint or Format.R16Sint
case Format.R8G8Uint: or Format.R16G16Float or Format.R16G16Unorm or Format.R16G16Snorm or Format.R16G16Uint
case Format.R8G8Sint: or Format.R16G16Sint or Format.R16G16B16Float or Format.R16G16B16Unorm or Format.R16G16B16Snorm
case Format.R8G8B8Unorm: or Format.R16G16B16Uint or Format.R16G16B16Sint or Format.R16G16B16A16Float
case Format.R8G8B8Snorm: or Format.R16G16B16A16Unorm or Format.R16G16B16A16Snorm or Format.R16G16B16A16Uint
case Format.R8G8B8Uint: or Format.R16G16B16A16Sint or Format.R4G4B4A4Unorm or Format.R5G5B5X1Unorm or Format.R5G5B5A1Unorm
case Format.R8G8B8Sint: or Format.R5G6B5Unorm or Format.R16Uscaled or Format.R16Sscaled or Format.R16G16Uscaled
case Format.R8G8B8A8Unorm: or Format.R16G16Sscaled or Format.R16G16B16Uscaled or Format.R16G16B16Sscaled
case Format.R8G8B8A8Snorm: or Format.R16G16B16A16Uscaled or Format.R16G16B16A16Sscaled or Format.B5G6R5Unorm
case Format.R8G8B8A8Uint: or Format.B5G5R5A1Unorm or Format.A1B5G5R5Unorm => 2,
case Format.R8G8B8A8Sint: Format.R32Float or Format.R32Uint or Format.R32Sint or Format.R32G32Float or Format.R32G32Uint
case Format.R8G8B8A8Srgb: or Format.R32G32Sint or Format.R32G32B32Float or Format.R32G32B32Uint or Format.R32G32B32Sint
case Format.R4G4Unorm: or Format.R32G32B32A32Float or Format.R32G32B32A32Uint or Format.R32G32B32A32Sint
case Format.R8Uscaled: or Format.R10G10B10A2Unorm or Format.R10G10B10A2Uint or Format.R11G11B10Float
case Format.R8Sscaled: or Format.R9G9B9E5Float or Format.R32Uscaled or Format.R32Sscaled or Format.R32G32Uscaled
case Format.R8G8Uscaled: or Format.R32G32Sscaled or Format.R32G32B32Uscaled or Format.R32G32B32Sscaled
case Format.R8G8Sscaled: or Format.R32G32B32A32Uscaled or Format.R32G32B32A32Sscaled or Format.R10G10B10A2Snorm
case Format.R8G8B8Uscaled: or Format.R10G10B10A2Sint or Format.R10G10B10A2Uscaled or Format.R10G10B10A2Sscaled
case Format.R8G8B8Sscaled: or Format.B10G10R10A2Unorm => 4,
case Format.R8G8B8A8Uscaled: Format.S8Uint => 1,
case Format.R8G8B8A8Sscaled: Format.D16Unorm => 2,
case Format.B8G8R8A8Unorm: Format.S8UintD24Unorm or Format.X8UintD24Unorm or Format.D32Float or Format.D24UnormS8Uint => 4,
case Format.B8G8R8A8Srgb: Format.D32FloatS8Uint => 8,
return 1; Format.Bc1RgbaUnorm or Format.Bc1RgbaSrgb => 8,
Format.Bc2Unorm or Format.Bc3Unorm or Format.Bc2Srgb or Format.Bc3Srgb or Format.Bc4Unorm
case Format.R16Float: or Format.Bc4Snorm or Format.Bc5Unorm or Format.Bc5Snorm or Format.Bc7Unorm or Format.Bc7Srgb
case Format.R16Unorm: or Format.Bc6HSfloat or Format.Bc6HUfloat => 16,
case Format.R16Snorm: Format.Etc2RgbUnorm or Format.Etc2RgbPtaUnorm or Format.Etc2RgbSrgb or Format.Etc2RgbPtaSrgb => 8,
case Format.R16Uint: Format.Etc2RgbaUnorm or Format.Etc2RgbaSrgb => 16,
case Format.R16Sint: Format.Astc4x4Unorm or Format.Astc5x4Unorm or Format.Astc5x5Unorm or Format.Astc6x5Unorm
case Format.R16G16Float: or Format.Astc6x6Unorm or Format.Astc8x5Unorm or Format.Astc8x6Unorm or Format.Astc8x8Unorm
case Format.R16G16Unorm: or Format.Astc10x5Unorm or Format.Astc10x6Unorm or Format.Astc10x8Unorm or Format.Astc10x10Unorm
case Format.R16G16Snorm: or Format.Astc12x10Unorm or Format.Astc12x12Unorm or Format.Astc4x4Srgb or Format.Astc5x4Srgb
case Format.R16G16Uint: or Format.Astc5x5Srgb or Format.Astc6x5Srgb or Format.Astc6x6Srgb or Format.Astc8x5Srgb
case Format.R16G16Sint: or Format.Astc8x6Srgb or Format.Astc8x8Srgb or Format.Astc10x5Srgb or Format.Astc10x6Srgb
case Format.R16G16B16Float: or Format.Astc10x8Srgb or Format.Astc10x10Srgb or Format.Astc12x10Srgb
case Format.R16G16B16Unorm: or Format.Astc12x12Srgb => 16,
case Format.R16G16B16Snorm: _ => 1
case Format.R16G16B16Uint: };
case Format.R16G16B16Sint:
case Format.R16G16B16A16Float:
case Format.R16G16B16A16Unorm:
case Format.R16G16B16A16Snorm:
case Format.R16G16B16A16Uint:
case Format.R16G16B16A16Sint:
case Format.R4G4B4A4Unorm:
case Format.R5G5B5X1Unorm:
case Format.R5G5B5A1Unorm:
case Format.R5G6B5Unorm:
case Format.R16Uscaled:
case Format.R16Sscaled:
case Format.R16G16Uscaled:
case Format.R16G16Sscaled:
case Format.R16G16B16Uscaled:
case Format.R16G16B16Sscaled:
case Format.R16G16B16A16Uscaled:
case Format.R16G16B16A16Sscaled:
case Format.B5G6R5Unorm:
case Format.B5G5R5A1Unorm:
case Format.A1B5G5R5Unorm:
return 2;
case Format.R32Float:
case Format.R32Uint:
case Format.R32Sint:
case Format.R32G32Float:
case Format.R32G32Uint:
case Format.R32G32Sint:
case Format.R32G32B32Float:
case Format.R32G32B32Uint:
case Format.R32G32B32Sint:
case Format.R32G32B32A32Float:
case Format.R32G32B32A32Uint:
case Format.R32G32B32A32Sint:
case Format.R10G10B10A2Unorm:
case Format.R10G10B10A2Uint:
case Format.R11G11B10Float:
case Format.R9G9B9E5Float:
case Format.R32Uscaled:
case Format.R32Sscaled:
case Format.R32G32Uscaled:
case Format.R32G32Sscaled:
case Format.R32G32B32Uscaled:
case Format.R32G32B32Sscaled:
case Format.R32G32B32A32Uscaled:
case Format.R32G32B32A32Sscaled:
case Format.R10G10B10A2Snorm:
case Format.R10G10B10A2Sint:
case Format.R10G10B10A2Uscaled:
case Format.R10G10B10A2Sscaled:
case Format.B10G10R10A2Unorm:
return 4;
case Format.S8Uint:
return 1;
case Format.D16Unorm:
return 2;
case Format.S8UintD24Unorm:
case Format.X8UintD24Unorm:
case Format.D32Float:
case Format.D24UnormS8Uint:
return 4;
case Format.D32FloatS8Uint:
return 8;
case Format.Bc1RgbaUnorm:
case Format.Bc1RgbaSrgb:
return 8;
case Format.Bc2Unorm:
case Format.Bc3Unorm:
case Format.Bc2Srgb:
case Format.Bc3Srgb:
case Format.Bc4Unorm:
case Format.Bc4Snorm:
case Format.Bc5Unorm:
case Format.Bc5Snorm:
case Format.Bc7Unorm:
case Format.Bc7Srgb:
case Format.Bc6HSfloat:
case Format.Bc6HUfloat:
return 16;
case Format.Etc2RgbUnorm:
case Format.Etc2RgbPtaUnorm:
case Format.Etc2RgbSrgb:
case Format.Etc2RgbPtaSrgb:
return 8;
case Format.Etc2RgbaUnorm:
case Format.Etc2RgbaSrgb:
return 16;
case Format.Astc4x4Unorm:
case Format.Astc5x4Unorm:
case Format.Astc5x5Unorm:
case Format.Astc6x5Unorm:
case Format.Astc6x6Unorm:
case Format.Astc8x5Unorm:
case Format.Astc8x6Unorm:
case Format.Astc8x8Unorm:
case Format.Astc10x5Unorm:
case Format.Astc10x6Unorm:
case Format.Astc10x8Unorm:
case Format.Astc10x10Unorm:
case Format.Astc12x10Unorm:
case Format.Astc12x12Unorm:
case Format.Astc4x4Srgb:
case Format.Astc5x4Srgb:
case Format.Astc5x5Srgb:
case Format.Astc6x5Srgb:
case Format.Astc6x6Srgb:
case Format.Astc8x5Srgb:
case Format.Astc8x6Srgb:
case Format.Astc8x8Srgb:
case Format.Astc10x5Srgb:
case Format.Astc10x6Srgb:
case Format.Astc10x8Srgb:
case Format.Astc10x10Srgb:
case Format.Astc12x10Srgb:
case Format.Astc12x12Srgb:
return 16;
}
return 1;
}
/// <summary> /// <summary>
/// Checks if the texture format is a depth or depth-stencil format. /// Checks if the texture format is a depth or depth-stencil format.
/// </summary> /// </summary>
/// <param name="format">Texture format</param> public bool HasDepth => fmt is
/// <returns>True if the format is a depth or depth-stencil format, false otherwise</returns> Format.D16Unorm or Format.D24UnormS8Uint or Format.S8UintD24Unorm or Format.X8UintD24Unorm
public static bool HasDepth(this Format format) or Format.D32Float or Format.D32FloatS8Uint;
{
switch (format)
{
case Format.D16Unorm:
case Format.D24UnormS8Uint:
case Format.S8UintD24Unorm:
case Format.X8UintD24Unorm:
case Format.D32Float:
case Format.D32FloatS8Uint:
return true;
}
return false;
}
/// <summary> /// <summary>
/// Checks if the texture format is a stencil or depth-stencil format. /// Checks if the texture format is a stencil or depth-stencil format.
/// </summary> /// </summary>
/// <param name="format">Texture format</param> public bool HasStencil => fmt is
/// <returns>True if the format is a stencil or depth-stencil format, false otherwise</returns> Format.D24UnormS8Uint or Format.S8UintD24Unorm or Format.D32FloatS8Uint or Format.S8Uint;
public static bool HasStencil(this Format format)
{
switch (format)
{
case Format.D24UnormS8Uint:
case Format.S8UintD24Unorm:
case Format.D32FloatS8Uint:
case Format.S8Uint:
return true;
}
return false;
}
/// <summary> /// <summary>
/// Checks if the texture format is valid to use as image format. /// Checks if the texture format is valid to use as image format.
/// </summary> /// </summary>
/// <param name="format">Texture format</param> public bool IsImageCompatible => fmt is
/// <returns>True if the texture can be used as image, false otherwise</returns> Format.R8Unorm or Format.R8Snorm or Format.R8Uint or Format.R8Sint or Format.R16Float or Format.R16Unorm
public static bool IsImageCompatible(this Format format) or Format.R16Snorm or Format.R16Uint or Format.R16Sint or Format.R32Float or Format.R32Uint
{ or Format.R32Sint or Format.R8G8Unorm or Format.R8G8Snorm or Format.R8G8Uint or Format.R8G8Sint
switch (format) or Format.R16G16Float or Format.R16G16Unorm or Format.R16G16Snorm or Format.R16G16Uint
{ or Format.R16G16Sint or Format.R32G32Float or Format.R32G32Uint or Format.R32G32Sint
case Format.R8Unorm: or Format.R8G8B8A8Unorm or Format.R8G8B8A8Snorm or Format.R8G8B8A8Uint or Format.R8G8B8A8Sint
case Format.R8Snorm: or Format.R16G16B16A16Float or Format.R16G16B16A16Unorm or Format.R16G16B16A16Snorm
case Format.R8Uint: or Format.R16G16B16A16Uint or Format.R16G16B16A16Sint or Format.R32G32B32A32Float
case Format.R8Sint: or Format.R32G32B32A32Uint or Format.R32G32B32A32Sint or Format.R10G10B10A2Unorm
case Format.R16Float: or Format.R10G10B10A2Uint or Format.R11G11B10Float or Format.B8G8R8A8Unorm;
case Format.R16Unorm:
case Format.R16Snorm:
case Format.R16Uint:
case Format.R16Sint:
case Format.R32Float:
case Format.R32Uint:
case Format.R32Sint:
case Format.R8G8Unorm:
case Format.R8G8Snorm:
case Format.R8G8Uint:
case Format.R8G8Sint:
case Format.R16G16Float:
case Format.R16G16Unorm:
case Format.R16G16Snorm:
case Format.R16G16Uint:
case Format.R16G16Sint:
case Format.R32G32Float:
case Format.R32G32Uint:
case Format.R32G32Sint:
case Format.R8G8B8A8Unorm:
case Format.R8G8B8A8Snorm:
case Format.R8G8B8A8Uint:
case Format.R8G8B8A8Sint:
case Format.R16G16B16A16Float:
case Format.R16G16B16A16Unorm:
case Format.R16G16B16A16Snorm:
case Format.R16G16B16A16Uint:
case Format.R16G16B16A16Sint:
case Format.R32G32B32A32Float:
case Format.R32G32B32A32Uint:
case Format.R32G32B32A32Sint:
case Format.R10G10B10A2Unorm:
case Format.R10G10B10A2Uint:
case Format.R11G11B10Float:
case Format.B8G8R8A8Unorm:
return true;
}
return false;
}
/// <summary> /// <summary>
/// Checks if the texture format is valid to use as render target color format. /// Checks if the texture format is valid to use as render target color format.
/// </summary> /// </summary>
/// <param name="format">Texture format</param> public bool IsRtColorCompatible => fmt is
/// <returns>True if the texture can be used as render target, false otherwise</returns> Format.R32G32B32A32Float or Format.R32G32B32A32Sint or Format.R32G32B32A32Uint
public static bool IsRtColorCompatible(this Format format) or Format.R16G16B16A16Unorm or Format.R16G16B16A16Snorm or Format.R16G16B16A16Sint
{ or Format.R16G16B16A16Uint or Format.R16G16B16A16Float or Format.R32G32Float or Format.R32G32Sint
switch (format) or Format.R32G32Uint or Format.B8G8R8A8Unorm or Format.B8G8R8A8Srgb or Format.B10G10R10A2Unorm
{ or Format.R10G10B10A2Unorm or Format.R10G10B10A2Uint or Format.R8G8B8A8Unorm or Format.R8G8B8A8Srgb
case Format.R32G32B32A32Float: or Format.R8G8B8A8Snorm or Format.R8G8B8A8Sint or Format.R8G8B8A8Uint or Format.R16G16Unorm
case Format.R32G32B32A32Sint: or Format.R16G16Snorm or Format.R16G16Sint or Format.R16G16Uint or Format.R16G16Float
case Format.R32G32B32A32Uint: or Format.R11G11B10Float or Format.R32Sint or Format.R32Uint or Format.R32Float
case Format.R16G16B16A16Unorm: or Format.B5G6R5Unorm or Format.B5G5R5A1Unorm or Format.R8G8Unorm or Format.R8G8Snorm
case Format.R16G16B16A16Snorm: or Format.R8G8Sint or Format.R8G8Uint or Format.R16Unorm or Format.R16Snorm or Format.R16Sint
case Format.R16G16B16A16Sint: or Format.R16Uint or Format.R16Float or Format.R8Unorm or Format.R8Snorm or Format.R8Sint
case Format.R16G16B16A16Uint: or Format.R8Uint;
case Format.R16G16B16A16Float:
case Format.R32G32Float:
case Format.R32G32Sint:
case Format.R32G32Uint:
case Format.B8G8R8A8Unorm:
case Format.B8G8R8A8Srgb:
case Format.B10G10R10A2Unorm:
case Format.R10G10B10A2Unorm:
case Format.R10G10B10A2Uint:
case Format.R8G8B8A8Unorm:
case Format.R8G8B8A8Srgb:
case Format.R8G8B8A8Snorm:
case Format.R8G8B8A8Sint:
case Format.R8G8B8A8Uint:
case Format.R16G16Unorm:
case Format.R16G16Snorm:
case Format.R16G16Sint:
case Format.R16G16Uint:
case Format.R16G16Float:
case Format.R11G11B10Float:
case Format.R32Sint:
case Format.R32Uint:
case Format.R32Float:
case Format.B5G6R5Unorm:
case Format.B5G5R5A1Unorm:
case Format.R8G8Unorm:
case Format.R8G8Snorm:
case Format.R8G8Sint:
case Format.R8G8Uint:
case Format.R16Unorm:
case Format.R16Snorm:
case Format.R16Sint:
case Format.R16Uint:
case Format.R16Float:
case Format.R8Unorm:
case Format.R8Snorm:
case Format.R8Sint:
case Format.R8Uint:
return true;
}
return false;
}
/// <summary> /// <summary>
/// Checks if the texture format is 16 bit packed. /// Checks if the texture format is 16 bit packed.
/// </summary> /// </summary>
/// <param name="format">Texture format</param> public bool Is16BitPacked => fmt is
/// <returns>True if the texture format is 16 bit packed, false otherwise</returns> Format.B5G6R5Unorm or Format.B5G5R5A1Unorm or Format.R5G5B5X1Unorm or Format.R5G5B5A1Unorm
public static bool Is16BitPacked(this Format format) or Format.R5G6B5Unorm or Format.R4G4B4A4Unorm;
{
switch (format)
{
case Format.B5G6R5Unorm:
case Format.B5G5R5A1Unorm:
case Format.R5G5B5X1Unorm:
case Format.R5G5B5A1Unorm:
case Format.R5G6B5Unorm:
case Format.R4G4B4A4Unorm:
return true;
}
return false;
}
/// <summary>
/// Checks if the texture format is an ASTC format.
/// </summary>
/// <param name="format">Texture format</param>
/// <returns>True if the texture format is an ASTC format, false otherwise</returns>
public static bool IsAstc(this Format format)
{
return format.IsAstcUnorm() || format.IsAstcSrgb();
}
/// <summary>
/// Checks if the texture format is an ASTC Unorm format.
/// </summary>
/// <param name="format">Texture format</param>
/// <returns>True if the texture format is an ASTC Unorm format, false otherwise</returns>
public static bool IsAstcUnorm(this Format format)
{
switch (format)
{
case Format.Astc4x4Unorm:
case Format.Astc5x4Unorm:
case Format.Astc5x5Unorm:
case Format.Astc6x5Unorm:
case Format.Astc6x6Unorm:
case Format.Astc8x5Unorm:
case Format.Astc8x6Unorm:
case Format.Astc8x8Unorm:
case Format.Astc10x5Unorm:
case Format.Astc10x6Unorm:
case Format.Astc10x8Unorm:
case Format.Astc10x10Unorm:
case Format.Astc12x10Unorm:
case Format.Astc12x12Unorm:
return true;
}
return false;
}
/// <summary>
/// Checks if the texture format is an ASTC SRGB format.
/// </summary>
/// <param name="format">Texture format</param>
/// <returns>True if the texture format is an ASTC SRGB format, false otherwise</returns>
public static bool IsAstcSrgb(this Format format)
{
switch (format)
{
case Format.Astc4x4Srgb:
case Format.Astc5x4Srgb:
case Format.Astc5x5Srgb:
case Format.Astc6x5Srgb:
case Format.Astc6x6Srgb:
case Format.Astc8x5Srgb:
case Format.Astc8x6Srgb:
case Format.Astc8x8Srgb:
case Format.Astc10x5Srgb:
case Format.Astc10x6Srgb:
case Format.Astc10x8Srgb:
case Format.Astc10x10Srgb:
case Format.Astc12x10Srgb:
case Format.Astc12x12Srgb:
return true;
}
return false;
}
/// <summary> /// <summary>
/// Checks if the texture format is an ETC2 format. /// Checks if the texture format is an ETC2 format.
/// </summary> /// </summary>
/// <param name="format">Texture format</param> public bool IsEtc2 => fmt is
/// <returns>True if the texture format is an ETC2 format, false otherwise</returns> Format.Etc2RgbaSrgb or Format.Etc2RgbaUnorm or Format.Etc2RgbPtaSrgb
public static bool IsEtc2(this Format format) or Format.Etc2RgbPtaUnorm or Format.Etc2RgbSrgb or Format.Etc2RgbUnorm;
{
switch (format)
{
case Format.Etc2RgbaSrgb:
case Format.Etc2RgbaUnorm:
case Format.Etc2RgbPtaSrgb:
case Format.Etc2RgbPtaUnorm:
case Format.Etc2RgbSrgb:
case Format.Etc2RgbUnorm:
return true;
}
return false;
}
/// <summary> /// <summary>
/// Checks if the texture format is a BGR format. /// Checks if the texture format is a BGR format.
/// </summary> /// </summary>
/// <param name="format">Texture format</param> public bool IsBgr => fmt is
/// <returns>True if the texture format is a BGR format, false otherwise</returns> Format.B5G6R5Unorm or Format.B5G5R5A1Unorm or Format.B8G8R8A8Unorm or Format.B8G8R8A8Srgb
public static bool IsBgr(this Format format) or Format.B10G10R10A2Unorm;
{
switch (format)
{
case Format.B5G6R5Unorm:
case Format.B5G5R5A1Unorm:
case Format.B8G8R8A8Unorm:
case Format.B8G8R8A8Srgb:
case Format.B10G10R10A2Unorm:
return true;
}
return false;
}
/// <summary> /// <summary>
/// Checks if the texture format is a depth, stencil or depth-stencil format. /// Checks if the texture format is a depth, stencil or depth-stencil format.
/// </summary> /// </summary>
/// <param name="format">Texture format</param> public bool IsDepthOrStencil => fmt is
/// <returns>True if the format is a depth, stencil or depth-stencil format, false otherwise</returns> Format.D16Unorm or Format.D24UnormS8Uint or Format.S8UintD24Unorm or Format.X8UintD24Unorm
public static bool IsDepthOrStencil(this Format format) or Format.D32Float or Format.D32FloatS8Uint or Format.S8Uint;
{
switch (format)
{
case Format.D16Unorm:
case Format.D24UnormS8Uint:
case Format.S8UintD24Unorm:
case Format.X8UintD24Unorm:
case Format.D32Float:
case Format.D32FloatS8Uint:
case Format.S8Uint:
return true;
}
return false;
}
/// <summary>
/// Checks if the texture format is an unsigned integer color format.
/// </summary>
/// <param name="format">Texture format</param>
/// <returns>True if the texture format is an unsigned integer color format, false otherwise</returns>
public static bool IsUint(this Format format)
{
switch (format)
{
case Format.R8Uint:
case Format.R16Uint:
case Format.R32Uint:
case Format.R8G8Uint:
case Format.R16G16Uint:
case Format.R32G32Uint:
case Format.R8G8B8Uint:
case Format.R16G16B16Uint:
case Format.R32G32B32Uint:
case Format.R8G8B8A8Uint:
case Format.R16G16B16A16Uint:
case Format.R32G32B32A32Uint:
case Format.R10G10B10A2Uint:
return true;
}
return false;
}
/// <summary>
/// Checks if the texture format is a signed integer color format.
/// </summary>
/// <param name="format">Texture format</param>
/// <returns>True if the texture format is a signed integer color format, false otherwise</returns>
public static bool IsSint(this Format format)
{
switch (format)
{
case Format.R8Sint:
case Format.R16Sint:
case Format.R32Sint:
case Format.R8G8Sint:
case Format.R16G16Sint:
case Format.R32G32Sint:
case Format.R8G8B8Sint:
case Format.R16G16B16Sint:
case Format.R32G32B32Sint:
case Format.R8G8B8A8Sint:
case Format.R16G16B16A16Sint:
case Format.R32G32B32A32Sint:
case Format.R10G10B10A2Sint:
return true;
}
return false;
}
/// <summary>
/// Checks if the texture format is an integer color format.
/// </summary>
/// <param name="format">Texture format</param>
/// <returns>True if the texture format is an integer color format, false otherwise</returns>
public static bool IsInteger(this Format format)
{
return format.IsUint() || format.IsSint();
}
/// <summary> /// <summary>
/// Checks if the texture format is a float or sRGB color format. /// Checks if the texture format is a float or sRGB color format.
@ -719,28 +292,57 @@ namespace Ryujinx.Graphics.GAL
/// Does not include normalized, compressed or depth formats. /// Does not include normalized, compressed or depth formats.
/// Float and sRGB formats do not participate in logical operations. /// Float and sRGB formats do not participate in logical operations.
/// </remarks> /// </remarks>
/// <param name="format">Texture format</param> public bool IsFloatOrSrgb => fmt is
/// <returns>True if the format is a float or sRGB color format, false otherwise</returns> Format.R8G8B8A8Srgb or Format.B8G8R8A8Srgb or Format.R16Float or Format.R16G16Float
public static bool IsFloatOrSrgb(this Format format) or Format.R16G16B16Float or Format.R16G16B16A16Float or Format.R32Float or Format.R32G32Float
{ or Format.R32G32B32Float or Format.R32G32B32A32Float or Format.R11G11B10Float
switch (format) or Format.R9G9B9E5Float;
{
case Format.R8G8B8A8Srgb:
case Format.B8G8R8A8Srgb:
case Format.R16Float:
case Format.R16G16Float:
case Format.R16G16B16Float:
case Format.R16G16B16A16Float:
case Format.R32Float:
case Format.R32G32Float:
case Format.R32G32B32Float:
case Format.R32G32B32A32Float:
case Format.R11G11B10Float:
case Format.R9G9B9E5Float:
return true;
}
return false; /// <summary>
/// Checks if the texture format is an ASTC Unorm format.
/// </summary>
public bool IsAstcUnorm => fmt is
Format.Astc4x4Unorm or Format.Astc5x4Unorm or Format.Astc5x5Unorm or Format.Astc6x5Unorm
or Format.Astc6x6Unorm or Format.Astc8x5Unorm or Format.Astc8x6Unorm or Format.Astc8x8Unorm
or Format.Astc10x5Unorm or Format.Astc10x6Unorm or Format.Astc10x8Unorm or Format.Astc10x10Unorm
or Format.Astc12x10Unorm or Format.Astc12x12Unorm;
/// <summary>
/// Checks if the texture format is an ASTC SRGB format.
/// </summary>
public bool IsAstcSrgb => fmt is
Format.Astc4x4Srgb or Format.Astc5x4Srgb or Format.Astc5x5Srgb or Format.Astc6x5Srgb
or Format.Astc6x6Srgb or Format.Astc8x5Srgb or Format.Astc8x6Srgb or Format.Astc8x8Srgb
or Format.Astc10x5Srgb or Format.Astc10x6Srgb or Format.Astc10x8Srgb or Format.Astc10x10Srgb
or Format.Astc12x10Srgb or Format.Astc12x12Srgb;
/// <summary>
/// Checks if the texture format is an ASTC format.
/// </summary>
public bool IsAstc => fmt.IsAstcUnorm || fmt.IsAstcSrgb;
/// <summary>
/// Checks if the texture format is an unsigned integer color format.
/// </summary>
public bool IsUnsignedInt => fmt is
Format.R8Uint or Format.R16Uint or Format.R32Uint or Format.R8G8Uint or Format.R16G16Uint
or Format.R32G32Uint or Format.R8G8B8Uint or Format.R16G16B16Uint or Format.R32G32B32Uint
or Format.R8G8B8A8Uint or Format.R16G16B16A16Uint or Format.R32G32B32A32Uint
or Format.R10G10B10A2Uint;
/// <summary>
/// Checks if the texture format is a signed integer color format.
/// </summary>
public bool IsSignedInt => fmt is
Format.R8Sint or Format.R16Sint or Format.R32Sint or Format.R8G8Sint or Format.R16G16Sint
or Format.R32G32Sint or Format.R8G8B8Sint or Format.R16G16B16Sint or Format.R32G32B32Sint
or Format.R8G8B8A8Sint or Format.R16G16B16A16Sint or Format.R32G32B32A32Sint
or Format.R10G10B10A2Sint;
/// <summary>
/// Checks if the texture format is an integer color format.
/// </summary>
public bool IsInt => fmt.IsUnsignedInt || fmt.IsSignedInt;
} }
} }
} }

View file

@ -171,7 +171,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
ulong vbSize = GetVertexBufferSize(address, endAddress.Pack(), vbStride, _indexed, instanced, _firstVertex, _count); ulong vbSize = GetVertexBufferSize(address, endAddress.Pack(), vbStride, _indexed, instanced, _firstVertex, _count);
ulong attributeOffset = (ulong)vertexAttrib.UnpackOffset(); ulong attributeOffset = (ulong)vertexAttrib.UnpackOffset();
int componentSize = format.GetScalarSize(); int componentSize = format.ScalarSize;
address += attributeOffset; address += attributeOffset;

View file

@ -847,8 +847,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
FormatInfo dsFormat = _state.State.RtDepthStencilState.Format.Convert(); FormatInfo dsFormat = _state.State.RtDepthStencilState.Format.Convert();
bool hasDepth = dsFormat.Format.HasDepth(); bool hasDepth = dsFormat.Format.HasDepth;
bool hasStencil = dsFormat.Format.HasStencil(); bool hasStencil = dsFormat.Format.HasStencil;
if (hasStencil && (!clearStencil || (clearAffectedByStencilMask && _state.State.StencilTestState.FrontMask != 0xff))) if (hasStencil && (!clearStencil || (clearAffectedByStencilMask && _state.State.StencilTestState.FrontMask != 0xff)))
{ {

View file

@ -294,7 +294,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
{ {
Format format = colorState.Format.Convert().Format; Format format = colorState.Format.Convert().Format;
AttributeType type = format.IsInteger() ? (format.IsSint() ? AttributeType.Sint : AttributeType.Uint) : AttributeType.Float; AttributeType type = format.IsInt
? (format.IsSignedInt ? AttributeType.Sint : AttributeType.Uint)
: AttributeType.Float;
if (type != _graphics.FragmentOutputTypes[index]) if (type != _graphics.FragmentOutputTypes[index])
{ {

View file

@ -530,7 +530,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
if (!_context.Capabilities.SupportsBgraFormat) if (!_context.Capabilities.SupportsBgraFormat)
{ {
_context.SupportBufferUpdater.SetRenderTargetIsBgra(index, color.Format.IsBgr()); _context.SupportBufferUpdater.SetRenderTargetIsBgra(index, color.Format.IsBgr);
} }
} }
} }

View file

@ -333,7 +333,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
// as copies between depth and color formats are not allowed. // as copies between depth and color formats are not allowed.
// For depth blit, the destination texture format should always match exactly. // For depth blit, the destination texture format should always match exactly.
if (srcTexture.Format.IsDepthOrStencil()) if (srcTexture.Format.IsDepthOrStencil)
{ {
dstCopyTextureFormat = srcTexture.Info.FormatInfo; dstCopyTextureFormat = srcTexture.Info.FormatInfo;
} }

View file

@ -661,7 +661,7 @@ namespace Ryujinx.Graphics.Gpu.Image
bool found = _textureFormats.TryGetValue((TextureFormat)encoded, out format); bool found = _textureFormats.TryGetValue((TextureFormat)encoded, out format);
if (found && isPacked && !format.Format.IsDepthOrStencil()) if (found && isPacked && !format.Format.IsDepthOrStencil)
{ {
// If the packed flag is set, then the components of the pixel are tightly packed into the // If the packed flag is set, then the components of the pixel are tightly packed into the
// GPU registers on the shader. // GPU registers on the shader.

View file

@ -643,7 +643,7 @@ namespace Ryujinx.Graphics.Gpu.Image
// The decompression is slow, so we want to avoid it as much as possible. // The decompression is slow, so we want to avoid it as much as possible.
// This does a byte-by-byte check and skips the update if the data is equal in this case. // This does a byte-by-byte check and skips the update if the data is equal in this case.
// This improves the speed on applications that overwrites ASTC data without changing anything. // This improves the speed on applications that overwrites ASTC data without changing anything.
if (Info.FormatInfo.Format.IsAstc() && !_context.Capabilities.SupportsAstcCompression) if (Info.FormatInfo.Format.IsAstc && !_context.Capabilities.SupportsAstcCompression)
{ {
if (_updateCount < ByteComparisonSwitchThreshold) if (_updateCount < ByteComparisonSwitchThreshold)
{ {
@ -792,7 +792,7 @@ namespace Ryujinx.Graphics.Gpu.Image
// Handle compressed cases not supported by the host: // Handle compressed cases not supported by the host:
// - ASTC is usually not supported on desktop cards. // - ASTC is usually not supported on desktop cards.
// - BC4/BC5 is not supported on 3D textures. // - BC4/BC5 is not supported on 3D textures.
if (!_context.Capabilities.SupportsAstcCompression && Format.IsAstc()) if (!_context.Capabilities.SupportsAstcCompression && Format.IsAstc)
{ {
using (result) using (result)
{ {
@ -823,7 +823,7 @@ namespace Ryujinx.Graphics.Gpu.Image
return decoded; return decoded;
} }
} }
else if (!_context.Capabilities.SupportsEtc2Compression && Format.IsEtc2()) else if (!_context.Capabilities.SupportsEtc2Compression && Format.IsEtc2)
{ {
switch (Format) switch (Format)
{ {
@ -924,7 +924,7 @@ namespace Ryujinx.Graphics.Gpu.Image
} }
} }
} }
else if (!_context.Capabilities.Supports5BitComponentFormat && Format.Is16BitPacked()) else if (!_context.Capabilities.Supports5BitComponentFormat && Format.Is16BitPacked)
{ {
switch (Format) switch (Format)
{ {

View file

@ -180,7 +180,7 @@ namespace Ryujinx.Graphics.Gpu.Image
int widthAlignment = (info.IsLinear ? Constants.StrideAlignment : Constants.GobAlignment) / info.FormatInfo.BytesPerPixel; int widthAlignment = (info.IsLinear ? Constants.StrideAlignment : Constants.GobAlignment) / info.FormatInfo.BytesPerPixel;
if (!(info.FormatInfo.Format.IsDepthOrStencil() || info.FormatInfo.Components == 1)) if (!(info.FormatInfo.Format.IsDepthOrStencil || info.FormatInfo.Components == 1))
{ {
// Discount square textures that aren't depth-stencil like. (excludes game textures, cubemap faces, most 3D texture LUT, texture atlas) // Discount square textures that aren't depth-stencil like. (excludes game textures, cubemap faces, most 3D texture LUT, texture atlas)
// Detect if the texture is possibly square. Widths may be aligned, so to remove the uncertainty we align both the width and height. // Detect if the texture is possibly square. Widths may be aligned, so to remove the uncertainty we align both the width and height.

View file

@ -75,13 +75,14 @@ namespace Ryujinx.Graphics.Gpu.Image
if (!caps.SupportsAstcCompression) if (!caps.SupportsAstcCompression)
{ {
if (info.FormatInfo.Format.IsAstcUnorm()) if (info.FormatInfo.Format.IsAstcUnorm)
{ {
return GraphicsConfig.EnableTextureRecompression return GraphicsConfig.EnableTextureRecompression
? new FormatInfo(Format.Bc7Unorm, 4, 4, 16, 4) ? new FormatInfo(Format.Bc7Unorm, 4, 4, 16, 4)
: new FormatInfo(Format.R8G8B8A8Unorm, 1, 1, 4, 4); : new FormatInfo(Format.R8G8B8A8Unorm, 1, 1, 4, 4);
} }
else if (info.FormatInfo.Format.IsAstcSrgb())
if (info.FormatInfo.Format.IsAstcSrgb)
{ {
return GraphicsConfig.EnableTextureRecompression return GraphicsConfig.EnableTextureRecompression
? new FormatInfo(Format.Bc7Srgb, 4, 4, 16, 4) ? new FormatInfo(Format.Bc7Srgb, 4, 4, 16, 4)
@ -151,9 +152,9 @@ namespace Ryujinx.Graphics.Gpu.Image
return new FormatInfo(Format.R8G8B8A8Unorm, 1, 1, 4, 4); return new FormatInfo(Format.R8G8B8A8Unorm, 1, 1, 4, 4);
} }
} }
else if (!caps.Supports5BitComponentFormat && info.FormatInfo.Format.Is16BitPacked()) else if (!caps.Supports5BitComponentFormat && info.FormatInfo.Format.Is16BitPacked)
{ {
return new FormatInfo(info.FormatInfo.Format.IsBgr() ? Format.B8G8R8A8Unorm : Format.R8G8B8A8Unorm, 1, 1, 4, 4); return new FormatInfo(info.FormatInfo.Format.IsBgr ? Format.B8G8R8A8Unorm : Format.R8G8B8A8Unorm, 1, 1, 4, 4);
} }
return info.FormatInfo; return info.FormatInfo;
@ -644,7 +645,7 @@ namespace Ryujinx.Graphics.Gpu.Image
FormatInfo lhsFormat = lhs.FormatInfo; FormatInfo lhsFormat = lhs.FormatInfo;
FormatInfo rhsFormat = rhs.FormatInfo; FormatInfo rhsFormat = rhs.FormatInfo;
if (lhsFormat.Format.IsDepthOrStencil() || rhsFormat.Format.IsDepthOrStencil()) if (lhsFormat.Format.IsDepthOrStencil || rhsFormat.Format.IsDepthOrStencil)
{ {
bool forSampler = flags.HasFlag(TextureSearchFlags.ForSampler); bool forSampler = flags.HasFlag(TextureSearchFlags.ForSampler);
bool depthAlias = flags.HasFlag(TextureSearchFlags.DepthAlias); bool depthAlias = flags.HasFlag(TextureSearchFlags.DepthAlias);

View file

@ -649,7 +649,7 @@ namespace Ryujinx.Graphics.Gpu.Image
swizzleB, swizzleB,
swizzleA); swizzleA);
if (formatInfo.Format.IsDepthOrStencil()) if (formatInfo.Format.IsDepthOrStencil)
{ {
swizzleR = SwizzleComponent.Red; swizzleR = SwizzleComponent.Red;
swizzleG = SwizzleComponent.Red; swizzleG = SwizzleComponent.Red;

View file

@ -53,7 +53,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
int layers, int layers,
int levels) int levels)
{ {
TextureView srcConverted = src.Format.IsBgr() != dst.Format.IsBgr() ? BgraSwap(src) : src; TextureView srcConverted = src.Format.IsBgr != dst.Format.IsBgr ? BgraSwap(src) : src;
(int oldDrawFramebufferHandle, int oldReadFramebufferHandle) = ((Pipeline)_renderer.Pipeline).GetBoundFramebuffers(); (int oldDrawFramebufferHandle, int oldReadFramebufferHandle) = ((Pipeline)_renderer.Pipeline).GetBoundFramebuffers();
@ -87,7 +87,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
ClearBufferMask mask = GetMask(src.Format); ClearBufferMask mask = GetMask(src.Format);
if ((mask & (ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit)) != 0 || src.Format.IsInteger()) if ((mask & (ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit)) != 0 || src.Format.IsInt)
{ {
linearFilter = false; linearFilter = false;
} }

View file

@ -84,7 +84,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
swizzleRgba[2] = temp2; swizzleRgba[2] = temp2;
swizzleRgba[3] = temp; swizzleRgba[3] = temp;
} }
else if (Info.Format.IsBgr()) else if (Info.Format.IsBgr)
{ {
// Swap B <-> R for BGRA formats, as OpenGL has no support for them // Swap B <-> R for BGRA formats, as OpenGL has no support for them
// and we need to manually swap the components on read/write on the GPU. // and we need to manually swap the components on read/write on the GPU.
@ -119,7 +119,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
bool srcIsMultisample = Target.IsMultisample; bool srcIsMultisample = Target.IsMultisample;
bool dstIsMultisample = destinationView.Target.IsMultisample; bool dstIsMultisample = destinationView.Target.IsMultisample;
if (dstIsMultisample != srcIsMultisample && Info.Format.IsDepthOrStencil()) if (dstIsMultisample != srcIsMultisample && Info.Format.IsDepthOrStencil)
{ {
int layers = Math.Min(Info.GetLayers(), destinationView.Info.GetLayers() - firstLayer); int layers = Math.Min(Info.GetLayers(), destinationView.Info.GetLayers() - firstLayer);
CopyWithBlitForDepthMultisample(destinationView, 0, firstLayer, layers); CopyWithBlitForDepthMultisample(destinationView, 0, firstLayer, layers);
@ -140,7 +140,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
int levels = Math.Min(Info.Levels, destinationView.Info.Levels - firstLevel); int levels = Math.Min(Info.Levels, destinationView.Info.Levels - firstLevel);
_renderer.TextureCopyIncompatible.CopyIncompatibleFormats(this, destinationView, 0, firstLayer, 0, firstLevel, layers, levels); _renderer.TextureCopyIncompatible.CopyIncompatibleFormats(this, destinationView, 0, firstLayer, 0, firstLevel, layers, levels);
} }
else if (destinationView.Format.IsDepthOrStencil() != Format.IsDepthOrStencil()) else if (destinationView.Format.IsDepthOrStencil != Format.IsDepthOrStencil)
{ {
int layers = Math.Min(Info.GetLayers(), destinationView.Info.GetLayers() - firstLayer); int layers = Math.Min(Info.GetLayers(), destinationView.Info.GetLayers() - firstLayer);
int levels = Math.Min(Info.Levels, destinationView.Info.Levels - firstLevel); int levels = Math.Min(Info.Levels, destinationView.Info.Levels - firstLevel);
@ -175,7 +175,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
bool srcIsMultisample = Target.IsMultisample; bool srcIsMultisample = Target.IsMultisample;
bool dstIsMultisample = destinationView.Target.IsMultisample; bool dstIsMultisample = destinationView.Target.IsMultisample;
if (dstIsMultisample != srcIsMultisample && Info.Format.IsDepthOrStencil()) if (dstIsMultisample != srcIsMultisample && Info.Format.IsDepthOrStencil)
{ {
CopyWithBlitForDepthMultisample(destinationView, srcLayer, dstLayer, 1); CopyWithBlitForDepthMultisample(destinationView, srcLayer, dstLayer, 1);
} }
@ -191,7 +191,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
{ {
_renderer.TextureCopyIncompatible.CopyIncompatibleFormats(this, destinationView, srcLayer, dstLayer, srcLevel, dstLevel, 1, 1); _renderer.TextureCopyIncompatible.CopyIncompatibleFormats(this, destinationView, srcLayer, dstLayer, srcLevel, dstLevel, 1, 1);
} }
else if (destinationView.Format.IsDepthOrStencil() != Format.IsDepthOrStencil()) else if (destinationView.Format.IsDepthOrStencil != Format.IsDepthOrStencil)
{ {
int minWidth = Math.Min(Width, destinationView.Width); int minWidth = Math.Min(Width, destinationView.Width);
int minHeight = Math.Min(Height, destinationView.Height); int minHeight = Math.Min(Height, destinationView.Height);

View file

@ -1178,7 +1178,7 @@ namespace Ryujinx.Graphics.OpenGL
if (color != null) if (color != null)
{ {
int isBgra = color.Format.IsBgr() ? 1 : 0; int isBgra = color.Format.IsBgr ? 1 : 0;
if (_fpIsBgra[index].X != isBgra) if (_fpIsBgra[index].X != isBgra)
{ {

View file

@ -70,7 +70,7 @@ namespace Ryujinx.Graphics.OpenGL
GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, drawFramebuffer); GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, drawFramebuffer);
GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, readFramebuffer); GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, readFramebuffer);
TextureView viewConverted = view.Format.IsBgr() ? _renderer.TextureCopy.BgraSwap(view) : view; TextureView viewConverted = view.Format.IsBgr ? _renderer.TextureCopy.BgraSwap(view) : view;
UpdateEffect(); UpdateEffect();
@ -80,7 +80,7 @@ namespace Ryujinx.Graphics.OpenGL
viewConverted = _antiAliasing.Run(viewConverted, _width, _height); viewConverted = _antiAliasing.Run(viewConverted, _width, _height);
if (viewConverted.Format.IsBgr()) if (viewConverted.Format.IsBgr)
{ {
TextureView swappedView = _renderer.TextureCopy.BgraSwap(viewConverted); TextureView swappedView = _renderer.TextureCopy.BgraSwap(viewConverted);
@ -152,14 +152,14 @@ namespace Ryujinx.Graphics.OpenGL
if (ScreenCaptureRequested) if (ScreenCaptureRequested)
{ {
CaptureFrame(srcX0, srcY0, srcX1, srcY1, view.Format.IsBgr(), crop.FlipX, crop.FlipY); CaptureFrame(srcX0, srcY0, srcX1, srcY1, view.Format.IsBgr, crop.FlipX, crop.FlipY);
ScreenCaptureRequested = false; ScreenCaptureRequested = false;
} }
if (_scalingFilter != null) if (_scalingFilter != null)
{ {
if (viewConverted.Format.IsBgr() && !_isBgra) if (viewConverted.Format.IsBgr && !_isBgra)
{ {
RecreateUpscalingTexture(true); RecreateUpscalingTexture(true);
} }

View file

@ -158,16 +158,16 @@ namespace Ryujinx.Graphics.Vulkan
FormatFeatureFlags.TransferSrcBit | FormatFeatureFlags.TransferSrcBit |
FormatFeatureFlags.TransferDstBit; FormatFeatureFlags.TransferDstBit;
if (srcFormat.IsDepthOrStencil()) if (srcFormat.IsDepthOrStencil)
{ {
requiredFeatures |= FormatFeatureFlags.DepthStencilAttachmentBit; requiredFeatures |= FormatFeatureFlags.DepthStencilAttachmentBit;
} }
else if (srcFormat.IsRtColorCompatible()) else if (srcFormat.IsRtColorCompatible)
{ {
requiredFeatures |= FormatFeatureFlags.ColorAttachmentBit; requiredFeatures |= FormatFeatureFlags.ColorAttachmentBit;
} }
if (srcFormat.IsImageCompatible() && storageFeatureFlagRequired) if (srcFormat.IsImageCompatible && storageFeatureFlagRequired)
{ {
requiredFeatures |= FormatFeatureFlags.StorageImageBit; requiredFeatures |= FormatFeatureFlags.StorageImageBit;
} }

View file

@ -36,7 +36,7 @@ namespace Ryujinx.Graphics.Vulkan
{ {
Format format = view.Info.Format; Format format = view.Info.Format;
bool isDepthStencil = format.IsDepthOrStencil(); bool isDepthStencil = format.IsDepthOrStencil;
_device = device; _device = device;
_attachments = [view.GetImageViewForAttachment()]; _attachments = [view.GetImageViewForAttachment()];
@ -60,8 +60,8 @@ namespace Ryujinx.Graphics.Vulkan
AttachmentSamples = [(uint)view.Info.Samples]; AttachmentSamples = [(uint)view.Info.Samples];
AttachmentFormats = [view.VkFormat]; AttachmentFormats = [view.VkFormat];
AttachmentIndices = isDepthStencil ? [] : [0]; AttachmentIndices = isDepthStencil ? [] : [0];
AttachmentIntegerFormatMask = format.IsInteger() ? 1u : 0u; AttachmentIntegerFormatMask = format.IsInt ? 1u : 0u;
LogicOpsAllowed = !format.IsFloatOrSrgb(); LogicOpsAllowed = !format.IsFloatOrSrgb;
AttachmentsCount = 1; AttachmentsCount = 1;
@ -110,12 +110,12 @@ namespace Ryujinx.Graphics.Vulkan
Format format = texture.Info.Format; Format format = texture.Info.Format;
if (format.IsInteger()) if (format.IsInt)
{ {
attachmentIntegerFormatMask |= 1u << bindIndex; attachmentIntegerFormatMask |= 1u << bindIndex;
} }
allFormatsFloatOrSrgb &= format.IsFloatOrSrgb(); allFormatsFloatOrSrgb &= format.IsFloatOrSrgb;
width = Math.Min(width, (uint)texture.Width); width = Math.Min(width, (uint)texture.Width);
height = Math.Min(height, (uint)texture.Height); height = Math.Min(height, (uint)texture.Height);
@ -187,12 +187,12 @@ namespace Ryujinx.Graphics.Vulkan
{ {
Format format = _colors[index].Info.Format; Format format = _colors[index].Info.Format;
if (format.IsSint()) if (format.IsSignedInt)
{ {
return ComponentType.SignedInteger; return ComponentType.SignedInteger;
} }
if (format.IsUint()) if (format.IsUnsignedInt)
{ {
return ComponentType.UnsignedInteger; return ComponentType.UnsignedInteger;
} }

View file

@ -403,7 +403,7 @@ namespace Ryujinx.Graphics.Vulkan
0f, 0f,
1f); 1f);
bool dstIsDepthOrStencil = dst.Info.Format.IsDepthOrStencil(); bool dstIsDepthOrStencil = dst.Info.Format.IsDepthOrStencil;
if (dstIsDepthOrStencil) if (dstIsDepthOrStencil)
{ {
@ -1048,7 +1048,7 @@ namespace Ryujinx.Graphics.Vulkan
Span<int> shaderParams = stackalloc int[ParamsBufferSize / sizeof(int)]; Span<int> shaderParams = stackalloc int[ParamsBufferSize / sizeof(int)];
int samples = src.Info.Samples; int samples = src.Info.Samples;
bool isDepthOrStencil = src.Info.Format.IsDepthOrStencil(); bool isDepthOrStencil = src.Info.Format.IsDepthOrStencil;
ImageAspectFlags aspectFlags = src.Info.Format.ConvertAspectFlags(); ImageAspectFlags aspectFlags = src.Info.Format.ConvertAspectFlags();
// X and Y are the expected texture samples. // X and Y are the expected texture samples.
@ -1174,7 +1174,7 @@ namespace Ryujinx.Graphics.Vulkan
Span<int> shaderParams = stackalloc int[ParamsBufferSize / sizeof(int)]; Span<int> shaderParams = stackalloc int[ParamsBufferSize / sizeof(int)];
int samples = dst.Info.Samples; int samples = dst.Info.Samples;
bool isDepthOrStencil = src.Info.Format.IsDepthOrStencil(); bool isDepthOrStencil = src.Info.Format.IsDepthOrStencil;
ImageAspectFlags aspectFlags = src.Info.Format.ConvertAspectFlags(); ImageAspectFlags aspectFlags = src.Info.Format.ConvertAspectFlags();
// X and Y are the expected texture samples. // X and Y are the expected texture samples.

View file

@ -1175,7 +1175,7 @@ namespace Ryujinx.Graphics.Vulkan
if (!attribute.IsZero) if (!attribute.IsZero)
{ {
newVbScalarSizes[rawIndex] = Math.Max(newVbScalarSizes[rawIndex], attribute.Format.GetScalarSize()); newVbScalarSizes[rawIndex] = Math.Max(newVbScalarSizes[rawIndex], attribute.Format.ScalarSize);
dirtyVbSizes |= 1u << rawIndex; dirtyVbSizes |= 1u << rawIndex;
} }
@ -1564,7 +1564,7 @@ namespace Ryujinx.Graphics.Vulkan
// May need to enforce feedback loop layout here in the future. // May need to enforce feedback loop layout here in the future.
// Though technically, it should always work with the general layout. // Though technically, it should always work with the general layout.
if (view.Info.Format.IsDepthOrStencil()) if (view.Info.Format.IsDepthOrStencil)
{ {
if (_passWritesDepthStencil) if (_passWritesDepthStencil)
{ {

View file

@ -30,14 +30,14 @@ namespace Ryujinx.Graphics.Vulkan
int maxColorAttachmentIndex = -1; int maxColorAttachmentIndex = -1;
bool isNotMsOrSupportsStorage = gd.Capabilities.SupportsShaderStorageImageMultisample || bool isNotMsOrSupportsStorage = gd.Capabilities.SupportsShaderStorageImageMultisample ||
!state.DepthStencilFormat.IsImageCompatible(); !state.DepthStencilFormat.IsImageCompatible;
for (int i = 0; i < state.AttachmentEnable.Length; i++) for (int i = 0; i < state.AttachmentEnable.Length; i++)
{ {
if (state.AttachmentEnable[i]) if (state.AttachmentEnable[i])
{ {
bool isNotMsOrSupportsStorageAttachments = gd.Capabilities.SupportsShaderStorageImageMultisample || bool isNotMsOrSupportsStorageAttachments = gd.Capabilities.SupportsShaderStorageImageMultisample ||
!state.AttachmentFormats[i].IsImageCompatible(); !state.AttachmentFormats[i].IsImageCompatible;
attachmentFormats[attachmentCount] = gd.FormatCapabilities.ConvertToVkFormat(state.AttachmentFormats[i], isNotMsOrSupportsStorageAttachments); attachmentFormats[attachmentCount] = gd.FormatCapabilities.ConvertToVkFormat(state.AttachmentFormats[i], isNotMsOrSupportsStorageAttachments);
@ -236,7 +236,7 @@ namespace Ryujinx.Graphics.Vulkan
if (!attribute.IsZero && bufferIndex < vbCount) if (!attribute.IsZero && bufferIndex < vbCount)
{ {
vbScalarSizes[bufferIndex - 1] = Math.Max(attribute.Format.GetScalarSize(), vbScalarSizes[bufferIndex - 1]); vbScalarSizes[bufferIndex - 1] = Math.Max(attribute.Format.ScalarSize, vbScalarSizes[bufferIndex - 1]);
} }
} }
@ -303,23 +303,23 @@ namespace Ryujinx.Graphics.Vulkan
if (state.AttachmentEnable[i]) if (state.AttachmentEnable[i])
{ {
bool isNotMsOrSupportsStorage = gd.Capabilities.SupportsShaderStorageImageMultisample || bool isNotMsOrSupportsStorage = gd.Capabilities.SupportsShaderStorageImageMultisample ||
!state.AttachmentFormats[i].IsImageCompatible(); !state.AttachmentFormats[i].IsImageCompatible;
pipeline.Internal.AttachmentFormats[attachmentCount++] = gd.FormatCapabilities.ConvertToVkFormat(state.AttachmentFormats[i], isNotMsOrSupportsStorage); pipeline.Internal.AttachmentFormats[attachmentCount++] = gd.FormatCapabilities.ConvertToVkFormat(state.AttachmentFormats[i], isNotMsOrSupportsStorage);
maxColorAttachmentIndex = i; maxColorAttachmentIndex = i;
if (state.AttachmentFormats[i].IsInteger()) if (state.AttachmentFormats[i].IsInt)
{ {
attachmentIntegerFormatMask |= 1u << i; attachmentIntegerFormatMask |= 1u << i;
} }
allFormatsFloatOrSrgb &= state.AttachmentFormats[i].IsFloatOrSrgb(); allFormatsFloatOrSrgb &= state.AttachmentFormats[i].IsFloatOrSrgb;
} }
} }
if (state.DepthStencilEnable) if (state.DepthStencilEnable)
{ {
bool isNotMsOrSupportsStorage = !state.DepthStencilFormat.IsImageCompatible() || bool isNotMsOrSupportsStorage = !state.DepthStencilFormat.IsImageCompatible ||
gd.Capabilities.SupportsShaderStorageImageMultisample; gd.Capabilities.SupportsShaderStorageImageMultisample;
pipeline.Internal.AttachmentFormats[attachmentCount++] = gd.FormatCapabilities.ConvertToVkFormat(state.DepthStencilFormat, isNotMsOrSupportsStorage); pipeline.Internal.AttachmentFormats[attachmentCount++] = gd.FormatCapabilities.ConvertToVkFormat(state.DepthStencilFormat, isNotMsOrSupportsStorage);

View file

@ -53,7 +53,7 @@ namespace Ryujinx.Graphics.Vulkan
ImageBlit.SrcOffsetsBuffer srcOffsets = new(); ImageBlit.SrcOffsetsBuffer srcOffsets = new();
ImageBlit.DstOffsetsBuffer dstOffsets = new(); ImageBlit.DstOffsetsBuffer dstOffsets = new();
Filter filter = linearFilter && !dstInfo.Format.IsDepthOrStencil() ? Filter.Linear : Filter.Nearest; Filter filter = linearFilter && !dstInfo.Format.IsDepthOrStencil ? Filter.Linear : Filter.Nearest;
TextureView.InsertImageBarrier( TextureView.InsertImageBarrier(
api, api,

View file

@ -311,16 +311,16 @@ namespace Ryujinx.Graphics.Vulkan
{ {
ImageUsageFlags usage = DefaultUsageFlags; ImageUsageFlags usage = DefaultUsageFlags;
if (format.IsDepthOrStencil()) if (format.IsDepthOrStencil)
{ {
usage |= ImageUsageFlags.DepthStencilAttachmentBit; usage |= ImageUsageFlags.DepthStencilAttachmentBit;
} }
else if (format.IsRtColorCompatible()) else if (format.IsRtColorCompatible)
{ {
usage |= ImageUsageFlags.ColorAttachmentBit; usage |= ImageUsageFlags.ColorAttachmentBit;
} }
if ((format.IsImageCompatible() && isMsImageStorageSupported) || extendedUsage) if ((format.IsImageCompatible && isMsImageStorageSupported) || extendedUsage)
{ {
usage |= ImageUsageFlags.StorageBit; usage |= ImageUsageFlags.StorageBit;
} }

View file

@ -128,7 +128,7 @@ namespace Ryujinx.Graphics.Vulkan
ImageUsageFlags shaderUsage = ImageUsageFlags.SampledBit; ImageUsageFlags shaderUsage = ImageUsageFlags.SampledBit;
if (info.Format.IsImageCompatible() && (_gd.Capabilities.SupportsShaderStorageImageMultisample || !info.Target.IsMultisample)) if (info.Format.IsImageCompatible && (_gd.Capabilities.SupportsShaderStorageImageMultisample || !info.Target.IsMultisample))
{ {
shaderUsage |= ImageUsageFlags.StorageBit; shaderUsage |= ImageUsageFlags.StorageBit;
} }
@ -150,7 +150,7 @@ namespace Ryujinx.Graphics.Vulkan
{ {
if (gd.Capabilities.PortabilitySubset.HasFlag(PortabilitySubsetFlags.No3DImageView)) if (gd.Capabilities.PortabilitySubset.HasFlag(PortabilitySubsetFlags.No3DImageView))
{ {
if (levels == 1 && (info.Format.IsRtColorCompatible() || info.Format.IsDepthOrStencil())) if (levels == 1 && (info.Format.IsRtColorCompatible || info.Format.IsDepthOrStencil))
{ {
subresourceRange = new ImageSubresourceRange(aspectFlags, (uint)firstLevel, levels, (uint)firstLayer, 1); subresourceRange = new ImageSubresourceRange(aspectFlags, (uint)firstLevel, levels, (uint)firstLayer, 1);
@ -241,7 +241,7 @@ namespace Ryujinx.Graphics.Vulkan
int levels = Math.Min(Info.Levels, dst.Info.Levels - firstLevel); int levels = Math.Min(Info.Levels, dst.Info.Levels - firstLevel);
_gd.HelperShader.CopyIncompatibleFormats(_gd, cbs, src, dst, 0, firstLayer, 0, firstLevel, layers, levels); _gd.HelperShader.CopyIncompatibleFormats(_gd, cbs, src, dst, 0, firstLayer, 0, firstLevel, layers, levels);
} }
else if (src.Info.Format.IsDepthOrStencil() != dst.Info.Format.IsDepthOrStencil()) else if (src.Info.Format.IsDepthOrStencil != dst.Info.Format.IsDepthOrStencil)
{ {
int layers = Math.Min(Info.GetLayers(), dst.Info.GetLayers() - firstLayer); int layers = Math.Min(Info.GetLayers(), dst.Info.GetLayers() - firstLayer);
int levels = Math.Min(Info.Levels, dst.Info.Levels - firstLevel); int levels = Math.Min(Info.Levels, dst.Info.Levels - firstLevel);
@ -297,7 +297,7 @@ namespace Ryujinx.Graphics.Vulkan
{ {
_gd.HelperShader.CopyIncompatibleFormats(_gd, cbs, src, dst, srcLayer, dstLayer, srcLevel, dstLevel, 1, 1); _gd.HelperShader.CopyIncompatibleFormats(_gd, cbs, src, dst, srcLayer, dstLayer, srcLevel, dstLevel, 1, 1);
} }
else if (src.Info.Format.IsDepthOrStencil() != dst.Info.Format.IsDepthOrStencil()) else if (src.Info.Format.IsDepthOrStencil != dst.Info.Format.IsDepthOrStencil)
{ {
_gd.HelperShader.CopyColor(_gd, cbs, src, dst, srcLayer, dstLayer, srcLevel, dstLevel, 1, 1); _gd.HelperShader.CopyColor(_gd, cbs, src, dst, srcLayer, dstLayer, srcLevel, dstLevel, 1, 1);
} }
@ -370,7 +370,7 @@ namespace Ryujinx.Graphics.Vulkan
src.Height == dst.Height && src.Height == dst.Height &&
src.VkFormat == dst.VkFormat) src.VkFormat == dst.VkFormat)
{ {
if (src.Info.Samples > 1 && src.Info.Samples != dst.Info.Samples && src.Info.Format.IsDepthOrStencil()) if (src.Info.Samples > 1 && src.Info.Samples != dst.Info.Samples && src.Info.Format.IsDepthOrStencil)
{ {
// CmdResolveImage does not support depth-stencil resolve, so we need to use an alternative path // CmdResolveImage does not support depth-stencil resolve, so we need to use an alternative path
// for those textures. // for those textures.
@ -424,7 +424,7 @@ namespace Ryujinx.Graphics.Vulkan
} }
} }
bool isDepthOrStencil = dst.Info.Format.IsDepthOrStencil(); bool isDepthOrStencil = dst.Info.Format.IsDepthOrStencil;
if (!VulkanConfiguration.UseUnsafeBlit || (_gd.Vendor != Vendor.Nvidia && _gd.Vendor != Vendor.Intel)) if (!VulkanConfiguration.UseUnsafeBlit || (_gd.Vendor != Vendor.Nvidia && _gd.Vendor != Vendor.Intel))
{ {

View file

@ -401,7 +401,7 @@ namespace Ryujinx.Graphics.Vulkan
cbs = _gd.CommandBufferPool.Rent(); cbs = _gd.CommandBufferPool.Rent();
} }
CaptureFrame(view, srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0, view.Info.Format.IsBgr(), crop.FlipX, crop.FlipY); CaptureFrame(view, srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0, view.Info.Format.IsBgr, crop.FlipX, crop.FlipY);
ScreenCaptureRequested = false; ScreenCaptureRequested = false;
} }