aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Graphics.Gpu/Image
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2024-05-26 13:30:19 -0300
committerGitHub <noreply@github.com>2024-05-26 13:30:19 -0300
commit53d096e392d85106a41d8edad1dcda5cce7446a2 (patch)
tree38fcf4a50e666c96c5c0ea133201f0b390bd14eb /src/Ryujinx.Graphics.Gpu/Image
parent4cc00bb4b1b777734151cab5570d622fbfefa49f (diff)
Allow texture arrays to use separate descriptor sets on Vulkan (#6870)
* Report base and extra sets from the backend * Pass texture set index everywhere * Key textures using set and binding (rather than just binding) * Start using extra sets for array textures * Shader cache version bump * Separate new commands, some PR feedback * Introduce new manual descriptor set reservation method that prevents it from being used by something else while owned by an array * Move bind extra sets logic to new method * Should only use separate array is MaximumExtraSets is not zero * Format whitespace
Diffstat (limited to 'src/Ryujinx.Graphics.Gpu/Image')
-rw-r--r--src/Ryujinx.Graphics.Gpu/Image/TextureBindingInfo.cs13
-rw-r--r--src/Ryujinx.Graphics.Gpu/Image/TextureBindingsArrayCache.cs70
2 files changed, 64 insertions, 19 deletions
diff --git a/src/Ryujinx.Graphics.Gpu/Image/TextureBindingInfo.cs b/src/Ryujinx.Graphics.Gpu/Image/TextureBindingInfo.cs
index ba895c60..31abc21e 100644
--- a/src/Ryujinx.Graphics.Gpu/Image/TextureBindingInfo.cs
+++ b/src/Ryujinx.Graphics.Gpu/Image/TextureBindingInfo.cs
@@ -20,6 +20,11 @@ namespace Ryujinx.Graphics.Gpu.Image
public Format Format { get; }
/// <summary>
+ /// Shader texture host set index.
+ /// </summary>
+ public int Set { get; }
+
+ /// <summary>
/// Shader texture host binding point.
/// </summary>
public int Binding { get; }
@@ -54,15 +59,17 @@ namespace Ryujinx.Graphics.Gpu.Image
/// </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="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 binding, int arrayLength, int cbufSlot, int handle, TextureUsageFlags flags)
+ public TextureBindingInfo(Target target, Format format, int set, int binding, int arrayLength, int cbufSlot, int handle, TextureUsageFlags flags)
{
Target = target;
Format = format;
+ Set = set;
Binding = binding;
ArrayLength = arrayLength;
CbufSlot = cbufSlot;
@@ -74,6 +81,7 @@ namespace Ryujinx.Graphics.Gpu.Image
/// Constructs the texture binding information structure.
/// </summary>
/// <param name="target">The shader sampler target type</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>
@@ -82,12 +90,13 @@ namespace Ryujinx.Graphics.Gpu.Image
/// <param name="isSamplerOnly">Indicates that the binding is for a sampler</param>
public TextureBindingInfo(
Target target,
+ int set,
int binding,
int arrayLength,
int cbufSlot,
int handle,
TextureUsageFlags flags,
- bool isSamplerOnly) : this(target, 0, binding, arrayLength, cbufSlot, handle, flags)
+ bool isSamplerOnly) : this(target, 0, set, binding, arrayLength, cbufSlot, handle, flags)
{
IsSamplerOnly = isSamplerOnly;
}
diff --git a/src/Ryujinx.Graphics.Gpu/Image/TextureBindingsArrayCache.cs b/src/Ryujinx.Graphics.Gpu/Image/TextureBindingsArrayCache.cs
index a54d0700..18e28b3d 100644
--- a/src/Ryujinx.Graphics.Gpu/Image/TextureBindingsArrayCache.cs
+++ b/src/Ryujinx.Graphics.Gpu/Image/TextureBindingsArrayCache.cs
@@ -566,7 +566,7 @@ namespace Ryujinx.Graphics.Gpu.Image
int stageIndex,
int textureBufferIndex,
SamplerIndex samplerIndex,
- TextureBindingInfo bindingInfo)
+ in TextureBindingInfo bindingInfo)
{
Update(texturePool, samplerPool, stage, stageIndex, textureBufferIndex, isImage: false, samplerIndex, bindingInfo);
}
@@ -579,7 +579,7 @@ namespace Ryujinx.Graphics.Gpu.Image
/// <param name="stageIndex">Shader stage index where the array is used</param>
/// <param name="textureBufferIndex">Texture constant buffer index</param>
/// <param name="bindingInfo">Array binding information</param>
- public void UpdateImageArray(TexturePool texturePool, ShaderStage stage, int stageIndex, int textureBufferIndex, TextureBindingInfo bindingInfo)
+ public void UpdateImageArray(TexturePool texturePool, ShaderStage stage, int stageIndex, int textureBufferIndex, in TextureBindingInfo bindingInfo)
{
Update(texturePool, null, stage, stageIndex, textureBufferIndex, isImage: true, SamplerIndex.ViaHeaderIndex, bindingInfo);
}
@@ -603,7 +603,7 @@ namespace Ryujinx.Graphics.Gpu.Image
int textureBufferIndex,
bool isImage,
SamplerIndex samplerIndex,
- TextureBindingInfo bindingInfo)
+ in TextureBindingInfo bindingInfo)
{
if (IsDirectHandleType(bindingInfo.Handle))
{
@@ -623,7 +623,7 @@ namespace Ryujinx.Graphics.Gpu.Image
/// <param name="stage">Shader stage where the array is used</param>
/// <param name="isImage">Whether the array is a image or texture array</param>
/// <param name="bindingInfo">Array binding information</param>
- private void UpdateFromPool(TexturePool texturePool, SamplerPool samplerPool, ShaderStage stage, bool isImage, TextureBindingInfo bindingInfo)
+ private void UpdateFromPool(TexturePool texturePool, SamplerPool samplerPool, ShaderStage stage, bool isImage, in TextureBindingInfo bindingInfo)
{
CacheEntry entry = GetOrAddEntry(texturePool, samplerPool, bindingInfo, isImage, out bool isNewEntry);
@@ -638,11 +638,11 @@ namespace Ryujinx.Graphics.Gpu.Image
if (isImage)
{
- _context.Renderer.Pipeline.SetImageArray(stage, bindingInfo.Binding, entry.ImageArray);
+ SetImageArray(stage, bindingInfo, entry.ImageArray);
}
else
{
- _context.Renderer.Pipeline.SetTextureArray(stage, bindingInfo.Binding, entry.TextureArray);
+ SetTextureArray(stage, bindingInfo, entry.TextureArray);
}
return;
@@ -737,14 +737,14 @@ namespace Ryujinx.Graphics.Gpu.Image
entry.ImageArray.SetFormats(0, formats);
entry.ImageArray.SetImages(0, textures);
- _context.Renderer.Pipeline.SetImageArray(stage, bindingInfo.Binding, entry.ImageArray);
+ SetImageArray(stage, bindingInfo, entry.ImageArray);
}
else
{
entry.TextureArray.SetSamplers(0, samplers);
entry.TextureArray.SetTextures(0, textures);
- _context.Renderer.Pipeline.SetTextureArray(stage, bindingInfo.Binding, entry.TextureArray);
+ SetTextureArray(stage, bindingInfo, entry.TextureArray);
}
}
@@ -767,7 +767,7 @@ namespace Ryujinx.Graphics.Gpu.Image
int textureBufferIndex,
bool isImage,
SamplerIndex samplerIndex,
- TextureBindingInfo bindingInfo)
+ in TextureBindingInfo bindingInfo)
{
(textureBufferIndex, int samplerBufferIndex) = TextureHandle.UnpackSlots(bindingInfo.CbufSlot, textureBufferIndex);
@@ -800,11 +800,11 @@ namespace Ryujinx.Graphics.Gpu.Image
if (isImage)
{
- _context.Renderer.Pipeline.SetImageArray(stage, bindingInfo.Binding, entry.ImageArray);
+ SetImageArray(stage, bindingInfo, entry.ImageArray);
}
else
{
- _context.Renderer.Pipeline.SetTextureArray(stage, bindingInfo.Binding, entry.TextureArray);
+ SetTextureArray(stage, bindingInfo, entry.TextureArray);
}
return;
@@ -829,11 +829,11 @@ namespace Ryujinx.Graphics.Gpu.Image
if (isImage)
{
- _context.Renderer.Pipeline.SetImageArray(stage, bindingInfo.Binding, entry.ImageArray);
+ SetImageArray(stage, bindingInfo, entry.ImageArray);
}
else
{
- _context.Renderer.Pipeline.SetTextureArray(stage, bindingInfo.Binding, entry.TextureArray);
+ SetTextureArray(stage, bindingInfo, entry.TextureArray);
}
return;
@@ -950,14 +950,50 @@ namespace Ryujinx.Graphics.Gpu.Image
entry.ImageArray.SetFormats(0, formats);
entry.ImageArray.SetImages(0, textures);
- _context.Renderer.Pipeline.SetImageArray(stage, bindingInfo.Binding, entry.ImageArray);
+ SetImageArray(stage, bindingInfo, entry.ImageArray);
}
else
{
entry.TextureArray.SetSamplers(0, samplers);
entry.TextureArray.SetTextures(0, textures);
- _context.Renderer.Pipeline.SetTextureArray(stage, bindingInfo.Binding, entry.TextureArray);
+ SetTextureArray(stage, bindingInfo, entry.TextureArray);
+ }
+ }
+
+ /// <summary>
+ /// Updates a texture array binding on the host.
+ /// </summary>
+ /// <param name="stage">Shader stage where the array is used</param>
+ /// <param name="bindingInfo">Array binding information</param>
+ /// <param name="array">Texture array</param>
+ private void SetTextureArray(ShaderStage stage, in TextureBindingInfo bindingInfo, ITextureArray array)
+ {
+ if (bindingInfo.Set >= _context.Capabilities.ExtraSetBaseIndex && _context.Capabilities.MaximumExtraSets != 0)
+ {
+ _context.Renderer.Pipeline.SetTextureArraySeparate(stage, bindingInfo.Set, array);
+ }
+ else
+ {
+ _context.Renderer.Pipeline.SetTextureArray(stage, bindingInfo.Binding, array);
+ }
+ }
+
+ /// <summary>
+ /// Updates a image array binding on the host.
+ /// </summary>
+ /// <param name="stage">Shader stage where the array is used</param>
+ /// <param name="bindingInfo">Array binding information</param>
+ /// <param name="array">Image array</param>
+ private void SetImageArray(ShaderStage stage, in TextureBindingInfo bindingInfo, IImageArray array)
+ {
+ if (bindingInfo.Set >= _context.Capabilities.ExtraSetBaseIndex && _context.Capabilities.MaximumExtraSets != 0)
+ {
+ _context.Renderer.Pipeline.SetImageArraySeparate(stage, bindingInfo.Set, array);
+ }
+ else
+ {
+ _context.Renderer.Pipeline.SetImageArray(stage, bindingInfo.Binding, array);
}
}
@@ -973,7 +1009,7 @@ namespace Ryujinx.Graphics.Gpu.Image
private CacheEntry GetOrAddEntry(
TexturePool texturePool,
SamplerPool samplerPool,
- TextureBindingInfo bindingInfo,
+ in TextureBindingInfo bindingInfo,
bool isImage,
out bool isNew)
{
@@ -1015,7 +1051,7 @@ namespace Ryujinx.Graphics.Gpu.Image
private CacheEntryFromBuffer GetOrAddEntry(
TexturePool texturePool,
SamplerPool samplerPool,
- TextureBindingInfo bindingInfo,
+ in TextureBindingInfo bindingInfo,
bool isImage,
ref BufferBounds textureBufferBounds,
out bool isNew)