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

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;
} }