Compare commits

...

5 commits

Author SHA1 Message Date
Isaac Marovitz
f6f4c3829a
Merge e194f91245 into 6ce49a2dc7 2024-07-27 11:38:28 +00:00
Isaac Marovitz
e194f91245
Bind TextureBuffers 2024-07-27 11:32:45 +01:00
Isaac Marovitz
564e82edd7
Remove ClearSegments for now
Currently unimplemented and issues are arising with building BindingSegments in general.
2024-07-27 11:31:29 +01:00
Isaac Marovitz
6ce49a2dc7
Ava UI: Handle updates containing non numeric characters (#7043)
* Handle updates containing non numeric characters

Smh

Dont be stupid

* Use Berry’s method

* Thanks gdk

* Remove using
2024-07-25 16:44:33 -03:00
riperiperi
ccd330ba0f
Vulkan: Add missing barriers for texture to buffer copy (#7092)
This barrier has always been missing, but it only became apparent when #7012 merged.

I also added some barriers in case the target buffer used here is used by other commands, though right now it isn't.

Fixes a regression where water would turn white on AMD GPUs with the proprietary driver. May fix other issues on this driver.
2024-07-25 16:34:30 -03:00
6 changed files with 119 additions and 168 deletions

View file

@ -54,10 +54,10 @@ namespace Ryujinx.Graphics.Metal
record struct TextureRef
{
public ShaderStage Stage;
public Texture Storage;
public TextureBase Storage;
public Sampler Sampler;
public TextureRef(ShaderStage stage, Texture storage, Sampler sampler)
public TextureRef(ShaderStage stage, TextureBase storage, Sampler sampler)
{
Stage = stage;
Storage = storage;

View file

@ -805,13 +805,9 @@ namespace Ryujinx.Graphics.Metal
public readonly void UpdateTextureAndSampler(ShaderStage stage, ulong binding, TextureBase texture, Sampler sampler)
{
if (texture is TextureBuffer)
if (texture != null)
{
// TODO: Texture buffers
}
else if (texture is Texture view)
{
_currentState.TextureRefs[binding] = new(stage, view, sampler);
_currentState.TextureRefs[binding] = new(stage, texture, sampler);
}
else
{
@ -1124,59 +1120,52 @@ namespace Ryujinx.Graphics.Metal
case MetalRenderer.TextureSetIndex:
if (!segment.IsArray)
{
if (segment.Type != ResourceType.BufferTexture)
for (int i = 0; i < count; i++)
{
for (int i = 0; i < count; i++)
int index = binding + i;
ref var texture = ref _currentState.TextureRefs[index];
var storage = texture.Storage;
if (storage == null)
{
int index = binding + i;
ref var texture = ref _currentState.TextureRefs[index];
var storage = texture.Storage;
if (storage == null)
{
continue;
}
var mtlTexture = storage.GetHandle();
MTLRenderStages renderStages = 0;
if ((segment.Stages & ResourceStages.Vertex) != 0)
{
vertResourceIds[vertResourceIdIndex] = mtlTexture.GpuResourceID._impl;
vertResourceIdIndex++;
if (texture.Sampler != null)
{
vertResourceIds[vertResourceIdIndex] = texture.Sampler.GetSampler().GpuResourceID._impl;
vertResourceIdIndex++;
}
renderStages |= MTLRenderStages.RenderStageVertex;
}
if ((segment.Stages & ResourceStages.Fragment) != 0)
{
fragResourceIds[fragResourceIdIndex] = mtlTexture.GpuResourceID._impl;
fragResourceIdIndex++;
if (texture.Sampler != null)
{
fragResourceIds[fragResourceIdIndex] = texture.Sampler.GetSampler().GpuResourceID._impl;
fragResourceIdIndex++;
}
renderStages |= MTLRenderStages.RenderStageFragment;
}
renderCommandEncoder.UseResource(new MTLResource(mtlTexture.NativePtr), MTLResourceUsage.Read, renderStages);
continue;
}
}
else
{
// TODO: Buffer textures
var mtlTexture = storage.GetHandle();
MTLRenderStages renderStages = 0;
if ((segment.Stages & ResourceStages.Vertex) != 0)
{
vertResourceIds[vertResourceIdIndex] = mtlTexture.GpuResourceID._impl;
vertResourceIdIndex++;
if (texture.Sampler != null)
{
vertResourceIds[vertResourceIdIndex] = texture.Sampler.GetSampler().GpuResourceID._impl;
vertResourceIdIndex++;
}
renderStages |= MTLRenderStages.RenderStageVertex;
}
if ((segment.Stages & ResourceStages.Fragment) != 0)
{
fragResourceIds[fragResourceIdIndex] = mtlTexture.GpuResourceID._impl;
fragResourceIdIndex++;
if (texture.Sampler != null)
{
fragResourceIds[fragResourceIdIndex] = texture.Sampler.GetSampler().GpuResourceID._impl;
fragResourceIdIndex++;
}
renderStages |= MTLRenderStages.RenderStageFragment;
}
renderCommandEncoder.UseResource(new MTLResource(mtlTexture.NativePtr), MTLResourceUsage.Read, renderStages);
}
}
else
@ -1343,41 +1332,34 @@ namespace Ryujinx.Graphics.Metal
case MetalRenderer.TextureSetIndex:
if (!segment.IsArray)
{
if (segment.Type != ResourceType.BufferTexture)
for (int i = 0; i < count; i++)
{
for (int i = 0; i < count; i++)
int index = binding + i;
ref var texture = ref _currentState.TextureRefs[index];
var storage = texture.Storage;
if (storage == null)
{
int index = binding + i;
continue;
}
ref var texture = ref _currentState.TextureRefs[index];
var mtlTexture = storage.GetHandle();
var storage = texture.Storage;
if (segment.Stages.HasFlag(ResourceStages.Compute))
{
computeCommandEncoder.UseResource(new MTLResource(mtlTexture.NativePtr), MTLResourceUsage.Read);
resourceIds[resourceIdIndex] = mtlTexture.GpuResourceID._impl;
resourceIdIndex++;
if (storage == null)
if (texture.Sampler != null)
{
continue;
}
var mtlTexture = storage.GetHandle();
if (segment.Stages.HasFlag(ResourceStages.Compute))
{
computeCommandEncoder.UseResource(new MTLResource(mtlTexture.NativePtr), MTLResourceUsage.Read);
resourceIds[resourceIdIndex] = mtlTexture.GpuResourceID._impl;
resourceIds[resourceIdIndex] = texture.Sampler.GetSampler().GpuResourceID._impl;
resourceIdIndex++;
if (texture.Sampler != null)
{
resourceIds[resourceIdIndex] = texture.Sampler.GetSampler().GpuResourceID._impl;
resourceIdIndex++;
}
}
}
}
else
{
// TODO: Buffer textures
}
}
else
{

View file

@ -28,7 +28,6 @@ namespace Ryujinx.Graphics.Metal
private MTLComputePipelineState? _computePipelineCache;
private bool _firstBackgroundUse;
public ResourceBindingSegment[][] ClearSegments { get; }
public ResourceBindingSegment[][] BindingSegments { get; }
// Argument buffer sizes for Vertex or Compute stages
public int[] ArgumentBufferSizes { get; }
@ -53,7 +52,6 @@ namespace Ryujinx.Graphics.Metal
_handles[i] = device.NewLibrary(StringHelper.NSString(shader.Code), compileOptions, (library, error) => CompilationResultHandler(library, error, index));
}
ClearSegments = BuildClearSegments(resourceLayout.Sets);
(BindingSegments, ArgumentBufferSizes, FragArgumentBufferSizes) = BuildBindingSegments(resourceLayout.SetUsages);
}
@ -98,62 +96,6 @@ namespace Ryujinx.Graphics.Metal
}
}
private static ResourceBindingSegment[][] BuildClearSegments(ReadOnlyCollection<ResourceDescriptorCollection> sets)
{
ResourceBindingSegment[][] segments = new ResourceBindingSegment[sets.Count][];
for (int setIndex = 0; setIndex < sets.Count; setIndex++)
{
List<ResourceBindingSegment> currentSegments = new();
ResourceDescriptor currentDescriptor = default;
int currentCount = 0;
for (int index = 0; index < sets[setIndex].Descriptors.Count; index++)
{
ResourceDescriptor descriptor = sets[setIndex].Descriptors[index];
if (currentDescriptor.Binding + currentCount != descriptor.Binding ||
currentDescriptor.Type != descriptor.Type ||
currentDescriptor.Stages != descriptor.Stages ||
currentDescriptor.Count > 1 ||
descriptor.Count > 1)
{
if (currentCount != 0)
{
currentSegments.Add(new ResourceBindingSegment(
currentDescriptor.Binding,
currentCount,
currentDescriptor.Type,
currentDescriptor.Stages,
currentDescriptor.Count > 1));
}
currentDescriptor = descriptor;
currentCount = descriptor.Count;
}
else
{
currentCount += descriptor.Count;
}
}
if (currentCount != 0)
{
currentSegments.Add(new ResourceBindingSegment(
currentDescriptor.Binding,
currentCount,
currentDescriptor.Type,
currentDescriptor.Stages,
currentDescriptor.Count > 1));
}
segments[setIndex] = currentSegments.ToArray();
}
return segments;
}
private static (ResourceBindingSegment[][], int[], int[]) BuildBindingSegments(ReadOnlyCollection<ResourceUsageCollection> setUsages)
{
ResourceBindingSegment[][] segments = new ResourceBindingSegment[setUsages.Count][];

View file

@ -667,8 +667,36 @@ namespace Ryujinx.Graphics.Vulkan
if (PrepareOutputBuffer(cbs, hostSize, buffer, out VkBuffer copyToBuffer, out BufferHolder tempCopyHolder))
{
// No barrier necessary, as this is a temporary copy buffer.
offset = 0;
}
else
{
BufferHolder.InsertBufferBarrier(
_gd,
cbs.CommandBuffer,
copyToBuffer,
BufferHolder.DefaultAccessFlags,
AccessFlags.TransferWriteBit,
PipelineStageFlags.AllCommandsBit,
PipelineStageFlags.TransferBit,
offset,
outSize);
}
InsertImageBarrier(
_gd.Api,
cbs.CommandBuffer,
image,
TextureStorage.DefaultAccessMask,
AccessFlags.TransferReadBit,
PipelineStageFlags.AllCommandsBit,
PipelineStageFlags.TransferBit,
Info.Format.ConvertAspectFlags(),
FirstLayer + layer,
FirstLevel + level,
1,
1);
CopyFromOrToBuffer(cbs.CommandBuffer, copyToBuffer, image, hostSize, true, layer, level, 1, 1, singleSlice: true, offset, stride);
@ -677,6 +705,19 @@ namespace Ryujinx.Graphics.Vulkan
CopyDataToOutputBuffer(cbs, tempCopyHolder, autoBuffer, hostSize, range.Offset);
tempCopyHolder.Dispose();
}
else
{
BufferHolder.InsertBufferBarrier(
_gd,
cbs.CommandBuffer,
copyToBuffer,
AccessFlags.TransferWriteBit,
BufferHolder.DefaultAccessFlags,
PipelineStageFlags.TransferBit,
PipelineStageFlags.AllCommandsBit,
offset,
outSize);
}
}
private ReadOnlySpan<byte> GetData(CommandBufferPool cbp, PersistentFlushBuffer flushBuffer)

View file

@ -1,21 +1,20 @@
using LibHac.Ns;
using Ryujinx.Ava.Common.Locale;
namespace Ryujinx.Ava.UI.Models
{
public class TitleUpdateModel
{
public ApplicationControlProperty Control { get; }
public uint Version { get; }
public string Path { get; }
public string Label { get; }
public string Label => LocaleManager.Instance.UpdateAndGetDynamicValue(
System.IO.Path.GetExtension(Path)?.ToLower() == ".xci" ? LocaleKeys.TitleBundledUpdateVersionLabel : LocaleKeys.TitleUpdateVersionLabel,
Control.DisplayVersionString.ToString()
);
public TitleUpdateModel(ApplicationControlProperty control, string path)
public TitleUpdateModel(uint version, string displayVersion, string path)
{
Control = control;
Version = version;
Label = LocaleManager.Instance.UpdateAndGetDynamicValue(
System.IO.Path.GetExtension(path)?.ToLower() == ".xci" ? LocaleKeys.TitleBundledUpdateVersionLabel : LocaleKeys.TitleUpdateVersionLabel,
displayVersion
);
Path = path;
}
}

View file

@ -131,26 +131,11 @@ namespace Ryujinx.Ava.UI.ViewModels
public void SortUpdates()
{
var list = TitleUpdates.ToList();
list.Sort((first, second) =>
{
if (string.IsNullOrEmpty(first.Control.DisplayVersionString.ToString()))
{
return -1;
}
if (string.IsNullOrEmpty(second.Control.DisplayVersionString.ToString()))
{
return 1;
}
return Version.Parse(first.Control.DisplayVersionString.ToString()).CompareTo(Version.Parse(second.Control.DisplayVersionString.ToString())) * -1;
});
var sortedUpdates = TitleUpdates.OrderByDescending(update => update.Version);
Views.Clear();
Views.Add(new BaseModel());
Views.AddRange(list);
Views.AddRange(sortedUpdates);
if (SelectedUpdate == null)
{
@ -204,7 +189,9 @@ namespace Ryujinx.Ava.UI.ViewModels
controlNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None).OpenFile(ref nacpFile.Ref, "/control.nacp".ToU8Span(), OpenMode.Read).ThrowIfFailure();
nacpFile.Get.Read(out _, 0, SpanHelpers.AsByteSpan(ref controlData), ReadOption.None).ThrowIfFailure();
var update = new TitleUpdateModel(controlData, path);
var displayVersion = controlData.DisplayVersionString.ToString();
var update = new TitleUpdateModel(content.Version.Version, displayVersion, path);
TitleUpdates.Add(update);
if (selected)