diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2024-05-26 13:30:19 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-05-26 13:30:19 -0300 |
| commit | 53d096e392d85106a41d8edad1dcda5cce7446a2 (patch) | |
| tree | 38fcf4a50e666c96c5c0ea133201f0b390bd14eb /src/Ryujinx.Graphics.Gpu/Image | |
| parent | 4cc00bb4b1b777734151cab5570d622fbfefa49f (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.cs | 13 | ||||
| -rw-r--r-- | src/Ryujinx.Graphics.Gpu/Image/TextureBindingsArrayCache.cs | 70 |
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) |
