GetForBinding now takes FormatInfo
This commit is contained in:
parent
04545ec814
commit
4ccada3fb5
8 changed files with 69 additions and 188 deletions
|
@ -1,5 +1,6 @@
|
|||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.Gpu.Image;
|
||||
using Ryujinx.Graphics.Shader;
|
||||
|
||||
namespace Ryujinx.Graphics.Gpu.Engine
|
||||
|
@ -61,51 +62,51 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
/// </summary>
|
||||
/// <param name="format">Shader image format</param>
|
||||
/// <returns>Texture format</returns>
|
||||
public static Format GetFormat(TextureFormat format)
|
||||
public static FormatInfo GetFormatInfo(TextureFormat format)
|
||||
{
|
||||
return format switch
|
||||
{
|
||||
#pragma warning disable IDE0055 // Disable formatting
|
||||
TextureFormat.R8Unorm => Format.R8Unorm,
|
||||
TextureFormat.R8Snorm => Format.R8Snorm,
|
||||
TextureFormat.R8Uint => Format.R8Uint,
|
||||
TextureFormat.R8Sint => Format.R8Sint,
|
||||
TextureFormat.R16Float => Format.R16Float,
|
||||
TextureFormat.R16Unorm => Format.R16Unorm,
|
||||
TextureFormat.R16Snorm => Format.R16Snorm,
|
||||
TextureFormat.R16Uint => Format.R16Uint,
|
||||
TextureFormat.R16Sint => Format.R16Sint,
|
||||
TextureFormat.R32Float => Format.R32Float,
|
||||
TextureFormat.R32Uint => Format.R32Uint,
|
||||
TextureFormat.R32Sint => Format.R32Sint,
|
||||
TextureFormat.R8G8Unorm => Format.R8G8Unorm,
|
||||
TextureFormat.R8G8Snorm => Format.R8G8Snorm,
|
||||
TextureFormat.R8G8Uint => Format.R8G8Uint,
|
||||
TextureFormat.R8G8Sint => Format.R8G8Sint,
|
||||
TextureFormat.R16G16Float => Format.R16G16Float,
|
||||
TextureFormat.R16G16Unorm => Format.R16G16Unorm,
|
||||
TextureFormat.R16G16Snorm => Format.R16G16Snorm,
|
||||
TextureFormat.R16G16Uint => Format.R16G16Uint,
|
||||
TextureFormat.R16G16Sint => Format.R16G16Sint,
|
||||
TextureFormat.R32G32Float => Format.R32G32Float,
|
||||
TextureFormat.R32G32Uint => Format.R32G32Uint,
|
||||
TextureFormat.R32G32Sint => Format.R32G32Sint,
|
||||
TextureFormat.R8G8B8A8Unorm => Format.R8G8B8A8Unorm,
|
||||
TextureFormat.R8G8B8A8Snorm => Format.R8G8B8A8Snorm,
|
||||
TextureFormat.R8G8B8A8Uint => Format.R8G8B8A8Uint,
|
||||
TextureFormat.R8G8B8A8Sint => Format.R8G8B8A8Sint,
|
||||
TextureFormat.R16G16B16A16Float => Format.R16G16B16A16Float,
|
||||
TextureFormat.R16G16B16A16Unorm => Format.R16G16B16A16Unorm,
|
||||
TextureFormat.R16G16B16A16Snorm => Format.R16G16B16A16Snorm,
|
||||
TextureFormat.R16G16B16A16Uint => Format.R16G16B16A16Uint,
|
||||
TextureFormat.R16G16B16A16Sint => Format.R16G16B16A16Sint,
|
||||
TextureFormat.R32G32B32A32Float => Format.R32G32B32A32Float,
|
||||
TextureFormat.R32G32B32A32Uint => Format.R32G32B32A32Uint,
|
||||
TextureFormat.R32G32B32A32Sint => Format.R32G32B32A32Sint,
|
||||
TextureFormat.R10G10B10A2Unorm => Format.R10G10B10A2Unorm,
|
||||
TextureFormat.R10G10B10A2Uint => Format.R10G10B10A2Uint,
|
||||
TextureFormat.R11G11B10Float => Format.R11G11B10Float,
|
||||
_ => 0,
|
||||
TextureFormat.R8Unorm => new(Format.R8Unorm, 1, 1, 1, 1),
|
||||
TextureFormat.R8Snorm => new(Format.R8Snorm, 1, 1, 1, 1),
|
||||
TextureFormat.R8Uint => new(Format.R8Uint, 1, 1, 1, 1),
|
||||
TextureFormat.R8Sint => new(Format.R8Sint, 1, 1, 1, 1),
|
||||
TextureFormat.R16Float => new(Format.R16Float, 1, 1, 2, 1),
|
||||
TextureFormat.R16Unorm => new(Format.R16Unorm, 1, 1, 2, 1),
|
||||
TextureFormat.R16Snorm => new(Format.R16Snorm, 1, 1, 2, 1),
|
||||
TextureFormat.R16Uint => new(Format.R16Uint, 1, 1, 2, 1),
|
||||
TextureFormat.R16Sint => new(Format.R16Sint, 1, 1, 2, 1),
|
||||
TextureFormat.R32Float => new(Format.R32Float, 1, 1, 4, 1),
|
||||
TextureFormat.R32Uint => new(Format.R32Uint, 1, 1, 4, 1),
|
||||
TextureFormat.R32Sint => new(Format.R32Sint, 1, 1, 4, 1),
|
||||
TextureFormat.R8G8Unorm => new(Format.R8G8Unorm, 1, 1, 2, 2),
|
||||
TextureFormat.R8G8Snorm => new(Format.R8G8Snorm, 1, 1, 2, 2),
|
||||
TextureFormat.R8G8Uint => new(Format.R8G8Uint, 1, 1, 2, 2),
|
||||
TextureFormat.R8G8Sint => new(Format.R8G8Sint, 1, 1, 2, 2),
|
||||
TextureFormat.R16G16Float => new(Format.R16G16Float, 1, 1, 4, 2),
|
||||
TextureFormat.R16G16Unorm => new(Format.R16G16Unorm, 1, 1, 4, 2),
|
||||
TextureFormat.R16G16Snorm => new(Format.R16G16Snorm, 1, 1, 4, 2),
|
||||
TextureFormat.R16G16Uint => new(Format.R16G16Uint, 1, 1, 4, 2),
|
||||
TextureFormat.R16G16Sint => new(Format.R16G16Sint, 1, 1, 4, 2),
|
||||
TextureFormat.R32G32Float => new(Format.R32G32Float, 1, 1, 8, 2),
|
||||
TextureFormat.R32G32Uint => new(Format.R32G32Uint, 1, 1, 8, 2),
|
||||
TextureFormat.R32G32Sint => new(Format.R32G32Sint, 1, 1, 8, 2),
|
||||
TextureFormat.R8G8B8A8Unorm => new(Format.R8G8B8A8Unorm, 1, 1, 4, 4),
|
||||
TextureFormat.R8G8B8A8Snorm => new(Format.R8G8B8A8Snorm, 1, 1, 4, 4),
|
||||
TextureFormat.R8G8B8A8Uint => new(Format.R8G8B8A8Uint, 1, 1, 4, 4),
|
||||
TextureFormat.R8G8B8A8Sint => new(Format.R8G8B8A8Sint, 1, 1, 4, 4),
|
||||
TextureFormat.R16G16B16A16Float => new(Format.R16G16B16A16Float, 1, 1, 8, 4),
|
||||
TextureFormat.R16G16B16A16Unorm => new(Format.R16G16B16A16Unorm, 1, 1, 8, 4),
|
||||
TextureFormat.R16G16B16A16Snorm => new(Format.R16G16B16A16Snorm, 1, 1, 8, 4),
|
||||
TextureFormat.R16G16B16A16Uint => new(Format.R16G16B16A16Uint, 1, 1, 8, 4),
|
||||
TextureFormat.R16G16B16A16Sint => new(Format.R16G16B16A16Sint, 1, 1, 8, 4),
|
||||
TextureFormat.R32G32B32A32Float => new(Format.R32G32B32A32Float, 1, 1, 16, 4),
|
||||
TextureFormat.R32G32B32A32Uint => new(Format.R32G32B32A32Uint, 1, 1, 16, 4),
|
||||
TextureFormat.R32G32B32A32Sint => new(Format.R32G32B32A32Sint, 1, 1, 16, 4),
|
||||
TextureFormat.R10G10B10A2Unorm => new(Format.R10G10B10A2Unorm, 1, 1, 4, 4),
|
||||
TextureFormat.R10G10B10A2Uint => new(Format.R10G10B10A2Uint, 1, 1, 4, 4),
|
||||
TextureFormat.R11G11B10Float => new(Format.R11G11B10Float, 1, 1, 4, 3),
|
||||
_ => FormatInfo.Invalid,
|
||||
#pragma warning restore IDE0055
|
||||
};
|
||||
}
|
||||
|
|
|
@ -7,6 +7,11 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||
/// </summary>
|
||||
readonly struct FormatInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// An invalid texture format.
|
||||
/// </summary>
|
||||
public static FormatInfo Invalid { get; } = new(0, 0, 0, 0, 0);
|
||||
|
||||
/// <summary>
|
||||
/// A default, generic RGBA8 texture format.
|
||||
/// </summary>
|
||||
|
|
|
@ -711,120 +711,5 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the bytes per pixel for a image compatible format.
|
||||
/// </summary>
|
||||
/// <param name="format">Format</param>
|
||||
/// <returns>Bytes per pixel, or zero if the format is not a image compatible format</returns>
|
||||
public static int GetImageFormatBytesPerPixel(Format format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case Format.R8Unorm:
|
||||
case Format.R8Snorm:
|
||||
case Format.R8Uint:
|
||||
case Format.R8Sint:
|
||||
return 1;
|
||||
case Format.R16Float:
|
||||
case Format.R16Unorm:
|
||||
case Format.R16Snorm:
|
||||
case Format.R16Uint:
|
||||
case Format.R16Sint:
|
||||
case Format.R8G8Unorm:
|
||||
case Format.R8G8Snorm:
|
||||
case Format.R8G8Uint:
|
||||
case Format.R8G8Sint:
|
||||
return 2;
|
||||
case Format.R32Float:
|
||||
case Format.R32Uint:
|
||||
case Format.R32Sint:
|
||||
case Format.R16G16Float:
|
||||
case Format.R16G16Unorm:
|
||||
case Format.R16G16Snorm:
|
||||
case Format.R16G16Uint:
|
||||
case Format.R16G16Sint:
|
||||
case Format.R8G8B8A8Unorm:
|
||||
case Format.R8G8B8A8Snorm:
|
||||
case Format.R8G8B8A8Uint:
|
||||
case Format.R8G8B8A8Sint:
|
||||
case Format.R10G10B10A2Unorm:
|
||||
case Format.R10G10B10A2Uint:
|
||||
case Format.R11G11B10Float:
|
||||
return 4;
|
||||
case Format.R32G32Float:
|
||||
case Format.R32G32Uint:
|
||||
case Format.R32G32Sint:
|
||||
case Format.R16G16B16A16Float:
|
||||
case Format.R16G16B16A16Unorm:
|
||||
case Format.R16G16B16A16Snorm:
|
||||
case Format.R16G16B16A16Uint:
|
||||
case Format.R16G16B16A16Sint:
|
||||
return 8;
|
||||
case Format.R32G32B32A32Float:
|
||||
case Format.R32G32B32A32Uint:
|
||||
case Format.R32G32B32A32Sint:
|
||||
return 16;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the amount of components (RGBA) for a image compatible format.
|
||||
/// </summary>
|
||||
/// <param name="format">Format</param>
|
||||
/// <returns>Number of components (from 1 to 4), or zero if the format is not a image compatible format</returns>
|
||||
public static int GetImageFormatComponents(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:
|
||||
return 1;
|
||||
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:
|
||||
return 2;
|
||||
case Format.R11G11B10Float:
|
||||
return 3;
|
||||
case Format.R8G8B8A8Unorm:
|
||||
case Format.R8G8B8A8Snorm:
|
||||
case Format.R8G8B8A8Uint:
|
||||
case Format.R8G8B8A8Sint:
|
||||
case Format.R10G10B10A2Unorm:
|
||||
case Format.R10G10B10A2Uint:
|
||||
case Format.R16G16B16A16Float:
|
||||
case Format.R16G16B16A16Unorm:
|
||||
case Format.R16G16B16A16Snorm:
|
||||
case Format.R16G16B16A16Uint:
|
||||
case Format.R16G16B16A16Sint:
|
||||
case Format.R32G32B32A32Float:
|
||||
case Format.R32G32B32A32Uint:
|
||||
case Format.R32G32B32A32Sint:
|
||||
return 4;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||
/// <summary>
|
||||
/// For images, indicates the format specified on the shader.
|
||||
/// </summary>
|
||||
public Format Format { get; }
|
||||
public FormatInfo FormatInfo { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Shader texture host set index.
|
||||
|
@ -58,17 +58,17 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||
/// Constructs the texture binding information structure.
|
||||
/// </summary>
|
||||
/// <param name="target">The shader sampler target type</param>
|
||||
/// <param name="format">Format of the image as declared on the shader</param>
|
||||
/// <param name="formatInfo">Format of the image as declared on the shader</param>
|
||||
/// <param name="set">Shader texture host set index</param>
|
||||
/// <param name="binding">The shader texture binding point</param>
|
||||
/// <param name="arrayLength">For array of textures, this indicates the length of the array. A value of one indicates it is not an array</param>
|
||||
/// <param name="cbufSlot">Constant buffer slot where the texture handle is located</param>
|
||||
/// <param name="handle">The shader texture handle (read index into the texture constant buffer)</param>
|
||||
/// <param name="flags">The texture's usage flags, indicating how it is used in the shader</param>
|
||||
public TextureBindingInfo(Target target, Format format, int set, int binding, int arrayLength, int cbufSlot, int handle, TextureUsageFlags flags)
|
||||
public TextureBindingInfo(Target target, FormatInfo formatInfo, int set, int binding, int arrayLength, int cbufSlot, int handle, TextureUsageFlags flags)
|
||||
{
|
||||
Target = target;
|
||||
Format = format;
|
||||
FormatInfo = formatInfo;
|
||||
Set = set;
|
||||
Binding = binding;
|
||||
ArrayLength = arrayLength;
|
||||
|
@ -96,7 +96,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||
int cbufSlot,
|
||||
int handle,
|
||||
TextureUsageFlags flags,
|
||||
bool isSamplerOnly) : this(target, 0, set, binding, arrayLength, cbufSlot, handle, flags)
|
||||
bool isSamplerOnly) : this(target, FormatInfo.Invalid, set, binding, arrayLength, cbufSlot, handle, flags)
|
||||
{
|
||||
IsSamplerOnly = isSamplerOnly;
|
||||
}
|
||||
|
|
|
@ -673,7 +673,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||
}
|
||||
else
|
||||
{
|
||||
ref readonly TextureDescriptor descriptor = ref texturePool.GetForBinding(index, bindingInfo.Format, out texture);
|
||||
ref readonly TextureDescriptor descriptor = ref texturePool.GetForBinding(index, bindingInfo.FormatInfo, out texture);
|
||||
|
||||
if (texture != null)
|
||||
{
|
||||
|
@ -867,7 +867,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||
samplerId = TextureHandle.UnpackSamplerId(packedId);
|
||||
}
|
||||
|
||||
ref readonly TextureDescriptor descriptor = ref texturePool.GetForBinding(textureId, bindingInfo.Format, out Texture texture);
|
||||
ref readonly TextureDescriptor descriptor = ref texturePool.GetForBinding(textureId, bindingInfo.FormatInfo, out Texture texture);
|
||||
|
||||
if (texture != null)
|
||||
{
|
||||
|
|
|
@ -616,7 +616,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||
|
||||
if (!poolModified &&
|
||||
state.TextureHandle == textureId &&
|
||||
state.ImageFormat == bindingInfo.Format &&
|
||||
state.ImageFormat == bindingInfo.FormatInfo.Format &&
|
||||
state.CachedTexture != null &&
|
||||
state.CachedTexture.InvalidatedSequence == state.InvalidatedSequence)
|
||||
{
|
||||
|
@ -643,9 +643,9 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||
}
|
||||
|
||||
state.TextureHandle = textureId;
|
||||
state.ImageFormat = bindingInfo.Format;
|
||||
state.ImageFormat = bindingInfo.FormatInfo.Format;
|
||||
|
||||
ref readonly TextureDescriptor descriptor = ref pool.GetForBinding(textureId, bindingInfo.Format, out Texture texture);
|
||||
ref readonly TextureDescriptor descriptor = ref pool.GetForBinding(textureId, bindingInfo.FormatInfo, out Texture texture);
|
||||
|
||||
specStateMatches &= specState.MatchesImage(stage, index, descriptor);
|
||||
|
||||
|
|
|
@ -274,9 +274,10 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||
/// This method assumes that the pool has been manually synchronized before doing binding.
|
||||
/// </remarks>
|
||||
/// <param name="id">ID of the texture. This is effectively a zero-based index</param>
|
||||
/// <param name="formatInfo">Texture format information</param>
|
||||
/// <param name="texture">The texture with the given ID</param>
|
||||
/// <returns>The texture descriptor with the given ID</returns>
|
||||
public ref readonly TextureDescriptor GetForBinding(int id, Format format, out Texture texture)
|
||||
public ref readonly TextureDescriptor GetForBinding(int id, FormatInfo formatInfo, out Texture texture)
|
||||
{
|
||||
if ((uint)id >= Items.Length)
|
||||
{
|
||||
|
@ -286,24 +287,24 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||
|
||||
ref readonly TextureDescriptor descriptor = ref GetInternal(id, out texture);
|
||||
|
||||
if (texture != null && format != 0 && texture.Format != format)
|
||||
if (texture != null && formatInfo.Format != 0 && texture.Format != formatInfo.Format)
|
||||
{
|
||||
if (!_aliasLists.TryGetValue(texture, out TextureAliasList aliasList))
|
||||
{
|
||||
_aliasLists.Add(texture, aliasList = new TextureAliasList());
|
||||
}
|
||||
|
||||
texture = aliasList.Find(format);
|
||||
texture = aliasList.Find(formatInfo.Format);
|
||||
|
||||
if (texture == null)
|
||||
{
|
||||
TextureInfo info = GetInfo(descriptor, out int layerSize);
|
||||
info = ChangeFormat(info, format);
|
||||
info = ChangeFormat(info, formatInfo);
|
||||
texture = PhysicalMemory.TextureCache.FindOrCreateTexture(_channel.MemoryManager, TextureSearchFlags.ForSampler, info, layerSize);
|
||||
|
||||
if (texture != null)
|
||||
{
|
||||
aliasList.Add(format, texture);
|
||||
aliasList.Add(formatInfo.Format, texture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -746,25 +747,14 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||
/// <param name="info">Texture information</param>
|
||||
/// <param name="dstFormat">New format</param>
|
||||
/// <returns>Texture information with the new format</returns>
|
||||
private static TextureInfo ChangeFormat(in TextureInfo info, Format dstFormat)
|
||||
private static TextureInfo ChangeFormat(in TextureInfo info, FormatInfo dstFormat)
|
||||
{
|
||||
int dstBpp = FormatTable.GetImageFormatBytesPerPixel(dstFormat);
|
||||
|
||||
if (dstBpp == 0)
|
||||
{
|
||||
// We don't support the format. Should never happen in practice.
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
FormatInfo dstFormatInfo = new FormatInfo(dstFormat, 1, 1, dstBpp, FormatTable.GetImageFormatComponents(dstFormat));
|
||||
|
||||
int width = info.Width;
|
||||
|
||||
if (info.FormatInfo.BytesPerPixel != dstBpp)
|
||||
if (info.FormatInfo.BytesPerPixel != dstFormat.BytesPerPixel)
|
||||
{
|
||||
int stride = width * info.FormatInfo.BytesPerPixel;
|
||||
width = stride / dstBpp;
|
||||
width = stride / dstFormat.BytesPerPixel;
|
||||
}
|
||||
|
||||
return new TextureInfo(
|
||||
|
@ -781,7 +771,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||
info.GobBlocksInZ,
|
||||
info.GobBlocksInTileX,
|
||||
info.Target,
|
||||
dstFormatInfo,
|
||||
dstFormat,
|
||||
info.DepthStencilMode,
|
||||
info.SwizzleR,
|
||||
info.SwizzleG,
|
||||
|
|
|
@ -86,11 +86,11 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
ImageBindings[i] = stage.Info.Images.Select(descriptor =>
|
||||
{
|
||||
Target target = ShaderTexture.GetTarget(descriptor.Type);
|
||||
Format format = ShaderTexture.GetFormat(descriptor.Format);
|
||||
FormatInfo formatInfo = ShaderTexture.GetFormatInfo(descriptor.Format);
|
||||
|
||||
var result = new TextureBindingInfo(
|
||||
target,
|
||||
format,
|
||||
formatInfo,
|
||||
descriptor.Set,
|
||||
descriptor.Binding,
|
||||
descriptor.ArrayLength,
|
||||
|
|
Loading…
Add table
Reference in a new issue