Backport some fixes from part 2

This commit is contained in:
Gabriel A 2024-03-31 07:58:49 -03:00
parent 5961486346
commit fa5b40441d
8 changed files with 107 additions and 13 deletions

View file

@ -463,7 +463,7 @@ namespace Ryujinx.Graphics.Gpu.Image
bindingInfo,
isImage,
ref textureBufferBounds,
out bool isNewEnry);
out bool isNewEntry);
bool poolsModified = entry.PoolsModified();
bool isStore = bindingInfo.Flags.HasFlag(TextureUsageFlags.ImageStore);
@ -471,7 +471,7 @@ namespace Ryujinx.Graphics.Gpu.Image
ReadOnlySpan<int> cachedTextureBuffer;
ReadOnlySpan<int> cachedSamplerBuffer;
if (!poolsModified && !isNewEnry && entry.ValidateTextures())
if (!poolsModified && !isNewEntry && entry.ValidateTextures())
{
if (entry.MatchesSequenceNumber(_context.SequenceNumber))
{
@ -532,7 +532,7 @@ namespace Ryujinx.Graphics.Gpu.Image
}
}
if (!isNewEnry)
if (!isNewEntry)
{
entry.Reset();
}

View file

@ -35,6 +35,36 @@ namespace Ryujinx.Graphics.Shader
};
}
public static string ToShortSamplerType(this SamplerType type)
{
string typeName = (type & SamplerType.Mask) switch
{
SamplerType.Texture1D => "1d",
SamplerType.TextureBuffer => "b",
SamplerType.Texture2D => "2d",
SamplerType.Texture3D => "3d",
SamplerType.TextureCube => "cube",
_ => throw new ArgumentException($"Invalid sampler type \"{type}\"."),
};
if ((type & SamplerType.Multisample) != 0)
{
typeName += "ms";
}
if ((type & SamplerType.Array) != 0)
{
typeName += "a";
}
if ((type & SamplerType.Shadow) != 0)
{
typeName += "s";
}
return typeName;
}
public static string ToGlslSamplerType(this SamplerType type)
{
string typeName = (type & SamplerType.Mask) switch

View file

@ -319,16 +319,22 @@ namespace Ryujinx.Graphics.Shader.Translation
}
string nameSuffix;
string prefix = isImage ? "i" : "t";
if (arrayLength != 1 && type != SamplerType.None)
{
prefix += type.ToShortSamplerType();
}
if (isImage)
{
nameSuffix = cbufSlot < 0
? $"i_tcb_{handle:X}_{format.ToGlslFormat()}"
: $"i_cb{cbufSlot}_{handle:X}_{format.ToGlslFormat()}";
? $"{prefix}_tcb_{handle:X}_{format.ToGlslFormat()}"
: $"{prefix}_cb{cbufSlot}_{handle:X}_{format.ToGlslFormat()}";
}
else
{
nameSuffix = cbufSlot < 0 ? $"t_tcb_{handle:X}" : $"t_cb{cbufSlot}_{handle:X}";
nameSuffix = cbufSlot < 0 ? $"{prefix}_tcb_{handle:X}" : $"{prefix}_cb{cbufSlot}_{handle:X}";
}
var definition = new TextureDefinition(

View file

@ -501,8 +501,18 @@ namespace Ryujinx.Graphics.Vulkan
if (_textureArrayRefs[binding].Stage != stage || _textureArrayRefs[binding].Array != array)
{
if (_textureArrayRefs[binding].Array != null)
{
_textureArrayRefs[binding].Array.Bound = false;
}
if (array is TextureArray textureArray)
{
textureArray.Bound = true;
textureArray.QueueWriteToReadBarriers(cbs, stage.ConvertToPipelineStageFlags());
}
_textureArrayRefs[binding] = new ArrayRef<TextureArray>(stage, array as TextureArray);
_textureArrayRefs[binding].Array?.QueueWriteToReadBarriers(cbs, stage.ConvertToPipelineStageFlags());
SignalDirty(DirtyFlags.Texture);
}
@ -517,8 +527,18 @@ namespace Ryujinx.Graphics.Vulkan
if (_imageArrayRefs[binding].Stage != stage || _imageArrayRefs[binding].Array != array)
{
if (_imageArrayRefs[binding].Array != null)
{
_imageArrayRefs[binding].Array.Bound = false;
}
if (array is ImageArray imageArray)
{
imageArray.Bound = true;
imageArray.QueueWriteToReadBarriers(cbs, stage.ConvertToPipelineStageFlags());
}
_imageArrayRefs[binding] = new ArrayRef<ImageArray>(stage, array as ImageArray);
_imageArrayRefs[binding].Array?.QueueWriteToReadBarriers(cbs, stage.ConvertToPipelineStageFlags());
SignalDirty(DirtyFlags.Image);
}
@ -922,6 +942,16 @@ namespace Ryujinx.Graphics.Vulkan
AdvancePdSequence();
}
public void ForceTextureDirty()
{
SignalDirty(DirtyFlags.Texture);
}
public void ForceImageDirty()
{
SignalDirty(DirtyFlags.Image);
}
private static void SwapBuffer(BufferRef[] list, Auto<DisposableBuffer> from, Auto<DisposableBuffer> to)
{
for (int i = 0; i < list.Length; i++)

View file

@ -7,6 +7,8 @@ namespace Ryujinx.Graphics.Vulkan
{
class ImageArray : IImageArray
{
private readonly VulkanRenderer _gd;
private record struct TextureRef
{
public TextureStorage Storage;
@ -27,8 +29,14 @@ namespace Ryujinx.Graphics.Vulkan
private readonly bool _isBuffer;
public ImageArray(int size, bool isBuffer)
public bool Bound;
public bool IsDirty => _storages == null;
public ImageArray(VulkanRenderer gd, int size, bool isBuffer)
{
_gd = gd;
if (isBuffer)
{
_bufferTextureRefs = new TextureBuffer[size];
@ -91,6 +99,8 @@ namespace Ryujinx.Graphics.Vulkan
{
_cachedCommandBufferIndex = -1;
_storages = null;
_gd.PipelineInternal.ForceImageDirty();
}
public void QueueWriteToReadBarriers(CommandBufferScoped cbs, PipelineStageFlags stageFlags)

View file

@ -1385,6 +1385,16 @@ namespace Ryujinx.Graphics.Vulkan
SignalCommandBufferChange();
}
public void ForceTextureDirty()
{
_descriptorSetUpdater.ForceTextureDirty();
}
public void ForceImageDirty()
{
_descriptorSetUpdater.ForceImageDirty();
}
public unsafe void TextureBarrier()
{
MemoryBarrier memoryBarrier = new()

View file

@ -7,7 +7,9 @@ namespace Ryujinx.Graphics.Vulkan
{
class TextureArray : ITextureArray
{
private record struct TextureRef
private readonly VulkanRenderer _gd;
private struct TextureRef
{
public TextureStorage Storage;
public Auto<DisposableImageView> View;
@ -27,8 +29,12 @@ namespace Ryujinx.Graphics.Vulkan
private readonly bool _isBuffer;
public TextureArray(int size, bool isBuffer)
public bool Bound;
public TextureArray(VulkanRenderer gd, int size, bool isBuffer)
{
_gd = gd;
if (isBuffer)
{
_bufferTextureRefs = new TextureBuffer[size];
@ -100,6 +106,8 @@ namespace Ryujinx.Graphics.Vulkan
{
_cachedCommandBufferIndex = -1;
_storages = null;
_gd.PipelineInternal.ForceTextureDirty();
}
public void QueueWriteToReadBarriers(CommandBufferScoped cbs, PipelineStageFlags stageFlags)

View file

@ -506,7 +506,7 @@ namespace Ryujinx.Graphics.Vulkan
public IImageArray CreateImageArray(int size, bool isBuffer)
{
return new ImageArray(size, isBuffer);
return new ImageArray(this, size, isBuffer);
}
public IProgram CreateProgram(ShaderSource[] sources, ShaderInfo info)
@ -543,7 +543,7 @@ namespace Ryujinx.Graphics.Vulkan
public ITextureArray CreateTextureArray(int size, bool isBuffer)
{
return new TextureArray(size, isBuffer);
return new TextureArray(this, size, isBuffer);
}
internal TextureView CreateTextureView(TextureCreateInfo info)