mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2026-05-16 18:25:47 +00:00
Compare commits
8 Commits
Canary-1.3
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3473044c6e | ||
|
|
e756ad4556 | ||
|
|
58bd19a2f3 | ||
|
|
48888bd014 | ||
|
|
d307afc454 | ||
|
|
134453e62b | ||
|
|
298b6c3959 | ||
|
|
c96433eb13 |
@@ -8,7 +8,7 @@
|
|||||||
<PackageVersion Include="Avalonia.Desktop" Version="11.3.15" />
|
<PackageVersion Include="Avalonia.Desktop" Version="11.3.15" />
|
||||||
<PackageVersion Include="Avalonia.Diagnostics" Version="11.3.15" />
|
<PackageVersion Include="Avalonia.Diagnostics" Version="11.3.15" />
|
||||||
<PackageVersion Include="Avalonia.Markup.Xaml.Loader" Version="11.3.15" />
|
<PackageVersion Include="Avalonia.Markup.Xaml.Loader" Version="11.3.15" />
|
||||||
<PackageVersion Include="SharpCompress" Version="0.48.0" />
|
<PackageVersion Include="SharpCompress" Version="0.48.1" />
|
||||||
<PackageVersion Include="Svg.Controls.Avalonia" Version="11.3.9.5" />
|
<PackageVersion Include="Svg.Controls.Avalonia" Version="11.3.9.5" />
|
||||||
<PackageVersion Include="Svg.Controls.Skia.Avalonia" Version="11.3.9.5" />
|
<PackageVersion Include="Svg.Controls.Skia.Avalonia" Version="11.3.9.5" />
|
||||||
<PackageVersion Include="Microsoft.Build.Framework" Version="17.11.4" />
|
<PackageVersion Include="Microsoft.Build.Framework" Version="17.11.4" />
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
<PackageVersion Include="Ryujinx.Systems.Update.Common" Version="2.0.6" />
|
<PackageVersion Include="Ryujinx.Systems.Update.Common" Version="2.0.6" />
|
||||||
<PackageVersion Include="Gommon" Version="2.8.1.2" />
|
<PackageVersion Include="Gommon" Version="2.8.1.2" />
|
||||||
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
|
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
|
||||||
<PackageVersion Include="Sep" Version="0.13.0" />
|
<PackageVersion Include="Sep" Version="0.14.1" />
|
||||||
<PackageVersion Include="shaderc.net" Version="0.1.0" />
|
<PackageVersion Include="shaderc.net" Version="0.1.0" />
|
||||||
<PackageVersion Include="Silk.NET.Vulkan" Version="2.22.0" />
|
<PackageVersion Include="Silk.NET.Vulkan" Version="2.22.0" />
|
||||||
<PackageVersion Include="Silk.NET.Vulkan.Extensions.EXT" Version="2.22.0" />
|
<PackageVersion Include="Silk.NET.Vulkan.Extensions.EXT" Version="2.22.0" />
|
||||||
|
|||||||
@@ -596,7 +596,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "重启模拟",
|
||||||
"zh_TW": "重新啟動模擬"
|
"zh_TW": "重新啟動模擬"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -6107,8 +6107,8 @@
|
|||||||
"de_DE": "",
|
"de_DE": "",
|
||||||
"el_GR": "",
|
"el_GR": "",
|
||||||
"en_US": "Enable Net Logs",
|
"en_US": "Enable Net Logs",
|
||||||
"es_ES": "Habilitar registros de red.",
|
"es_ES": "Habilitar Registros de Red.",
|
||||||
"fr_FR": "",
|
"fr_FR": "Activer les Journaux Réseau.",
|
||||||
"he_IL": "",
|
"he_IL": "",
|
||||||
"it_IT": "",
|
"it_IT": "",
|
||||||
"ja_JP": "",
|
"ja_JP": "",
|
||||||
@@ -6121,7 +6121,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "开启网络日志",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -11371,7 +11371,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "保存",
|
||||||
"zh_TW": "儲存"
|
"zh_TW": "儲存"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -17108,7 +17108,7 @@
|
|||||||
"el_GR": "",
|
"el_GR": "",
|
||||||
"en_US": "Prints network log messages in the console.",
|
"en_US": "Prints network log messages in the console.",
|
||||||
"es_ES": "Imprimir registros de red en la consola.",
|
"es_ES": "Imprimir registros de red en la consola.",
|
||||||
"fr_FR": "",
|
"fr_FR": "Affiche les journaux réseau dans la console.",
|
||||||
"he_IL": "",
|
"he_IL": "",
|
||||||
"it_IT": "",
|
"it_IT": "",
|
||||||
"ja_JP": "",
|
"ja_JP": "",
|
||||||
@@ -17121,7 +17121,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "在控制台中显示网络日志",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -21496,7 +21496,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "控制台将会在下次启动 Ryujinx 时可用。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
public bool IsMainFunction { get; private set; }
|
public bool IsMainFunction { get; private set; }
|
||||||
public bool MayHaveReturned { get; set; }
|
public bool MayHaveReturned { get; set; }
|
||||||
|
public bool WasNonUniformAccessDeclared { get; set; }
|
||||||
|
|
||||||
public CodeGenContext(
|
public CodeGenContext(
|
||||||
StructuredProgramInfo info,
|
StructuredProgramInfo info,
|
||||||
@@ -89,6 +90,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
GeneratorPool<Instruction> instPool,
|
GeneratorPool<Instruction> instPool,
|
||||||
GeneratorPool<LiteralInteger> integerPool) : base(SpirvVersionPacked, instPool, integerPool)
|
GeneratorPool<LiteralInteger> integerPool) : base(SpirvVersionPacked, instPool, integerPool)
|
||||||
{
|
{
|
||||||
|
WasNonUniformAccessDeclared = false;
|
||||||
|
|
||||||
Info = info;
|
Info = info;
|
||||||
AttributeUsage = parameters.AttributeUsage;
|
AttributeUsage = parameters.AttributeUsage;
|
||||||
Definitions = parameters.Definitions;
|
Definitions = parameters.Definitions;
|
||||||
|
|||||||
@@ -591,7 +591,16 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
{
|
{
|
||||||
if (context.HostCapabilities.SupportsShaderNonUniformIndexing)
|
if (context.HostCapabilities.SupportsShaderNonUniformIndexing)
|
||||||
{
|
{
|
||||||
|
if (!context.WasNonUniformAccessDeclared)
|
||||||
|
{
|
||||||
|
context.AddExtension("SPV_EXT_descriptor_indexing");
|
||||||
|
context.AddCapability(Capability.ShaderNonUniform);
|
||||||
|
context.AddCapability(Capability.SampledImageArrayNonUniformIndexing);
|
||||||
|
context.AddCapability(Capability.StorageImageArrayNonUniformIndexing);
|
||||||
|
}
|
||||||
|
|
||||||
context.Decorate(inst, Decoration.NonUniform);
|
context.Decorate(inst, Decoration.NonUniform);
|
||||||
|
context.WasNonUniformAccessDeclared = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -60,14 +60,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
context.AddCapability(Capability.Float64);
|
context.AddCapability(Capability.Float64);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parameters.HostCapabilities.SupportsShaderNonUniformIndexing)
|
|
||||||
{
|
|
||||||
context.AddExtension("SPV_EXT_descriptor_indexing");
|
|
||||||
context.AddCapability(Capability.ShaderNonUniform);
|
|
||||||
context.AddCapability(Capability.SampledImageArrayNonUniformIndexing);
|
|
||||||
context.AddCapability(Capability.StorageImageArrayNonUniformIndexing);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parameters.Definitions.TransformFeedbackEnabled && parameters.Definitions.LastInVertexPipeline)
|
if (parameters.Definitions.TransformFeedbackEnabled && parameters.Definitions.LastInVertexPipeline)
|
||||||
{
|
{
|
||||||
context.AddCapability(Capability.TransformFeedback);
|
context.AddCapability(Capability.TransformFeedback);
|
||||||
|
|||||||
@@ -46,7 +46,14 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public static (AccessFlags Access, PipelineStageFlags Stages) GetSubpassAccessSuperset(VulkanRenderer gd)
|
public static (AccessFlags Access, PipelineStageFlags Stages) GetSubpassAccessSuperset(VulkanRenderer gd)
|
||||||
{
|
{
|
||||||
AccessFlags access = BufferAccess;
|
AccessFlags access = BufferAccess |
|
||||||
|
AccessFlags.ShaderReadBit |
|
||||||
|
AccessFlags.ShaderWriteBit |
|
||||||
|
AccessFlags.ColorAttachmentReadBit |
|
||||||
|
AccessFlags.ColorAttachmentWriteBit |
|
||||||
|
AccessFlags.DepthStencilAttachmentReadBit |
|
||||||
|
AccessFlags.DepthStencilAttachmentWriteBit;
|
||||||
|
|
||||||
PipelineStageFlags stages = PipelineStageFlags.AllGraphicsBit;
|
PipelineStageFlags stages = PipelineStageFlags.AllGraphicsBit;
|
||||||
|
|
||||||
if (gd.TransformFeedbackApi != null)
|
if (gd.TransformFeedbackApi != null)
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
Image dstImage,
|
Image dstImage,
|
||||||
TextureCreateInfo srcInfo,
|
TextureCreateInfo srcInfo,
|
||||||
TextureCreateInfo dstInfo,
|
TextureCreateInfo dstInfo,
|
||||||
|
TextureCreateInfo srcStorageInfo,
|
||||||
|
TextureCreateInfo dstStorageInfo,
|
||||||
Extents2D srcRegion,
|
Extents2D srcRegion,
|
||||||
Extents2D dstRegion,
|
Extents2D dstRegion,
|
||||||
int srcLayer,
|
int srcLayer,
|
||||||
@@ -40,6 +42,13 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
return (xy1, xy2);
|
return (xy1, xy2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static (Offset3D, Offset3D) ClampOffsetsToMip(Offset3D xy1, Offset3D xy2, int mipW, int mipH)
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
new Offset3D(Math.Min(xy1.X, mipW), Math.Min(xy1.Y, mipH), xy1.Z),
|
||||||
|
new Offset3D(Math.Min(xy2.X, mipW), Math.Min(xy2.Y, mipH), xy2.Z));
|
||||||
|
}
|
||||||
|
|
||||||
if (srcAspectFlags == 0)
|
if (srcAspectFlags == 0)
|
||||||
{
|
{
|
||||||
srcAspectFlags = srcInfo.Format.ConvertAspectFlags();
|
srcAspectFlags = srcInfo.Format.ConvertAspectFlags();
|
||||||
@@ -80,6 +89,14 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
(srcOffsets.Element0, srcOffsets.Element1) = ExtentsToOffset3D(srcRegion, srcInfo.Width, srcInfo.Height, level);
|
(srcOffsets.Element0, srcOffsets.Element1) = ExtentsToOffset3D(srcRegion, srcInfo.Width, srcInfo.Height, level);
|
||||||
(dstOffsets.Element0, dstOffsets.Element1) = ExtentsToOffset3D(dstRegion, dstInfo.Width, dstInfo.Height, level);
|
(dstOffsets.Element0, dstOffsets.Element1) = ExtentsToOffset3D(dstRegion, dstInfo.Width, dstInfo.Height, level);
|
||||||
|
|
||||||
|
int srcMipW = Math.Max(1, srcStorageInfo.Width >> (int)copySrcLevel);
|
||||||
|
int srcMipH = Math.Max(1, srcStorageInfo.Height >> (int)copySrcLevel);
|
||||||
|
int dstMipW = Math.Max(1, dstStorageInfo.Width >> (int)copyDstLevel);
|
||||||
|
int dstMipH = Math.Max(1, dstStorageInfo.Height >> (int)copyDstLevel);
|
||||||
|
|
||||||
|
(srcOffsets.Element0, srcOffsets.Element1) = ClampOffsetsToMip(srcOffsets.Element0, srcOffsets.Element1, srcMipW, srcMipH);
|
||||||
|
(dstOffsets.Element0, dstOffsets.Element1) = ClampOffsetsToMip(dstOffsets.Element0, dstOffsets.Element1, dstMipW, dstMipH);
|
||||||
|
|
||||||
ImageBlit region = new()
|
ImageBlit region = new()
|
||||||
{
|
{
|
||||||
SrcSubresource = srcSl,
|
SrcSubresource = srcSl,
|
||||||
@@ -121,6 +138,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
Image dstImage,
|
Image dstImage,
|
||||||
TextureCreateInfo srcInfo,
|
TextureCreateInfo srcInfo,
|
||||||
TextureCreateInfo dstInfo,
|
TextureCreateInfo dstInfo,
|
||||||
|
TextureCreateInfo srcStorageInfo,
|
||||||
|
TextureCreateInfo dstStorageInfo,
|
||||||
int srcViewLayer,
|
int srcViewLayer,
|
||||||
int dstViewLayer,
|
int dstViewLayer,
|
||||||
int srcViewLevel,
|
int srcViewLevel,
|
||||||
@@ -151,6 +170,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
dstImage,
|
dstImage,
|
||||||
srcInfo,
|
srcInfo,
|
||||||
dstInfo,
|
dstInfo,
|
||||||
|
srcStorageInfo,
|
||||||
|
dstStorageInfo,
|
||||||
srcViewLayer,
|
srcViewLayer,
|
||||||
dstViewLayer,
|
dstViewLayer,
|
||||||
srcViewLevel,
|
srcViewLevel,
|
||||||
@@ -186,6 +207,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
Image dstImage,
|
Image dstImage,
|
||||||
TextureCreateInfo srcInfo,
|
TextureCreateInfo srcInfo,
|
||||||
TextureCreateInfo dstInfo,
|
TextureCreateInfo dstInfo,
|
||||||
|
TextureCreateInfo srcStorageInfo,
|
||||||
|
TextureCreateInfo dstStorageInfo,
|
||||||
int srcViewLayer,
|
int srcViewLayer,
|
||||||
int dstViewLayer,
|
int dstViewLayer,
|
||||||
int srcViewLevel,
|
int srcViewLevel,
|
||||||
@@ -314,6 +337,14 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
int copyWidth = sizeInBlocks ? BitUtils.DivRoundUp(width, blockWidth) : width;
|
int copyWidth = sizeInBlocks ? BitUtils.DivRoundUp(width, blockWidth) : width;
|
||||||
int copyHeight = sizeInBlocks ? BitUtils.DivRoundUp(height, blockHeight) : height;
|
int copyHeight = sizeInBlocks ? BitUtils.DivRoundUp(height, blockHeight) : height;
|
||||||
|
|
||||||
|
int srcMipW = Math.Max(1, srcStorageInfo.Width >> (srcViewLevel + srcLevel + level));
|
||||||
|
int srcMipH = Math.Max(1, srcStorageInfo.Height >> (srcViewLevel + srcLevel + level));
|
||||||
|
int dstMipW = Math.Max(1, dstStorageInfo.Width >> (dstViewLevel + dstLevel + level));
|
||||||
|
int dstMipH = Math.Max(1, dstStorageInfo.Height >> (dstViewLevel + dstLevel + level));
|
||||||
|
|
||||||
|
copyWidth = Math.Min(copyWidth, Math.Min(srcMipW, dstMipW));
|
||||||
|
copyHeight = Math.Min(copyHeight, Math.Min(srcMipH, dstMipH));
|
||||||
|
|
||||||
Extent3D extent = new((uint)copyWidth, (uint)copyHeight, (uint)srcDepth);
|
Extent3D extent = new((uint)copyWidth, (uint)copyHeight, (uint)srcDepth);
|
||||||
|
|
||||||
if (srcInfo.Samples > 1 && srcInfo.Samples != dstInfo.Samples)
|
if (srcInfo.Samples > 1 && srcInfo.Samples != dstInfo.Samples)
|
||||||
|
|||||||
@@ -67,6 +67,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public VkFormat VkFormat { get; }
|
public VkFormat VkFormat { get; }
|
||||||
|
|
||||||
|
public ImageUsageFlags UsageFlags { get; }
|
||||||
|
|
||||||
public unsafe TextureStorage(
|
public unsafe TextureStorage(
|
||||||
VulkanRenderer gd,
|
VulkanRenderer gd,
|
||||||
Device device,
|
Device device,
|
||||||
@@ -93,7 +95,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
SampleCountFlags sampleCountFlags = ConvertToSampleCountFlags(gd.Capabilities.SupportedSampleCounts, (uint)info.Samples);
|
SampleCountFlags sampleCountFlags = ConvertToSampleCountFlags(gd.Capabilities.SupportedSampleCounts, (uint)info.Samples);
|
||||||
|
|
||||||
ImageUsageFlags usage = GetImageUsage(info.Format, gd.Capabilities, isMsImageStorageSupported, true);
|
ImageUsageFlags usage = GetImageUsage(info.Format, gd.Capabilities, isMsImageStorageSupported);
|
||||||
|
UsageFlags = usage;
|
||||||
|
|
||||||
ImageCreateFlags flags = ImageCreateFlags.CreateMutableFormatBit | ImageCreateFlags.CreateExtendedUsageBit;
|
ImageCreateFlags flags = ImageCreateFlags.CreateMutableFormatBit | ImageCreateFlags.CreateExtendedUsageBit;
|
||||||
|
|
||||||
@@ -159,7 +162,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
_imageAuto = new Auto<DisposableImage>(new DisposableImage(_gd.Api, device, _image));
|
_imageAuto = new Auto<DisposableImage>(new DisposableImage(_gd.Api, device, _image));
|
||||||
|
|
||||||
InitialTransition(ImageLayout.Preinitialized, ImageLayout.General);
|
InitialTransition(ImageLayout.Undefined, ImageLayout.General);
|
||||||
}
|
}
|
||||||
|
|
||||||
_slices = new TextureSliceInfo[levels * _depthOrLayers];
|
_slices = new TextureSliceInfo[levels * _depthOrLayers];
|
||||||
@@ -307,7 +310,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ImageUsageFlags GetImageUsage(Format format, in HardwareCapabilities capabilities, bool isMsImageStorageSupported, bool extendedUsage)
|
public static ImageUsageFlags GetImageUsage(Format format, in HardwareCapabilities capabilities, bool isMsImageStorageSupported)
|
||||||
{
|
{
|
||||||
ImageUsageFlags usage = DefaultUsageFlags;
|
ImageUsageFlags usage = DefaultUsageFlags;
|
||||||
|
|
||||||
@@ -320,7 +323,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
usage |= ImageUsageFlags.ColorAttachmentBit;
|
usage |= ImageUsageFlags.ColorAttachmentBit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((format.IsImageCompatible && isMsImageStorageSupported) || extendedUsage)
|
if (format.IsImageCompatible && isMsImageStorageSupported)
|
||||||
{
|
{
|
||||||
usage |= ImageUsageFlags.StorageBit;
|
usage |= ImageUsageFlags.StorageBit;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
bool isMsImageStorageSupported = gd.Capabilities.SupportsShaderStorageImageMultisample || !info.Target.IsMultisample;
|
bool isMsImageStorageSupported = gd.Capabilities.SupportsShaderStorageImageMultisample || !info.Target.IsMultisample;
|
||||||
|
|
||||||
VkFormat format = _gd.FormatCapabilities.ConvertToVkFormat(info.Format, isMsImageStorageSupported);
|
VkFormat format = _gd.FormatCapabilities.ConvertToVkFormat(info.Format, isMsImageStorageSupported);
|
||||||
ImageUsageFlags usage = TextureStorage.GetImageUsage(info.Format, gd.Capabilities, isMsImageStorageSupported, false);
|
ImageUsageFlags usage = TextureStorage.GetImageUsage(info.Format, gd.Capabilities, isMsImageStorageSupported) & storage.UsageFlags;
|
||||||
|
|
||||||
uint levels = (uint)info.Levels;
|
uint levels = (uint)info.Levels;
|
||||||
uint layers = (uint)info.GetLayers();
|
uint layers = (uint)info.GetLayers();
|
||||||
@@ -133,6 +133,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
shaderUsage |= ImageUsageFlags.StorageBit;
|
shaderUsage |= ImageUsageFlags.StorageBit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shaderUsage &= storage.UsageFlags;
|
||||||
|
|
||||||
_imageView = CreateImageView(componentMapping, subresourceRange, type, shaderUsage);
|
_imageView = CreateImageView(componentMapping, subresourceRange, type, shaderUsage);
|
||||||
|
|
||||||
// Framebuffer attachments and storage images requires a identity component mapping.
|
// Framebuffer attachments and storage images requires a identity component mapping.
|
||||||
@@ -257,6 +259,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
dstImage,
|
dstImage,
|
||||||
src.Info,
|
src.Info,
|
||||||
dst.Info,
|
dst.Info,
|
||||||
|
src.Storage.Info,
|
||||||
|
dst.Storage.Info,
|
||||||
src.FirstLayer,
|
src.FirstLayer,
|
||||||
dst.FirstLayer,
|
dst.FirstLayer,
|
||||||
src.FirstLevel,
|
src.FirstLevel,
|
||||||
@@ -310,6 +314,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
dstImage,
|
dstImage,
|
||||||
src.Info,
|
src.Info,
|
||||||
dst.Info,
|
dst.Info,
|
||||||
|
src.Storage.Info,
|
||||||
|
dst.Storage.Info,
|
||||||
src.FirstLayer,
|
src.FirstLayer,
|
||||||
dst.FirstLayer,
|
dst.FirstLayer,
|
||||||
src.FirstLevel,
|
src.FirstLevel,
|
||||||
@@ -385,6 +391,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
dst.GetImage().Get(cbs).Value,
|
dst.GetImage().Get(cbs).Value,
|
||||||
src.Info,
|
src.Info,
|
||||||
dst.Info,
|
dst.Info,
|
||||||
|
src.Storage.Info,
|
||||||
|
dst.Storage.Info,
|
||||||
src.FirstLayer,
|
src.FirstLayer,
|
||||||
dst.FirstLayer,
|
dst.FirstLayer,
|
||||||
src.FirstLevel,
|
src.FirstLevel,
|
||||||
@@ -410,6 +418,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
dst.GetImage().Get(cbs).Value,
|
dst.GetImage().Get(cbs).Value,
|
||||||
src.Info,
|
src.Info,
|
||||||
dst.Info,
|
dst.Info,
|
||||||
|
src.Storage.Info,
|
||||||
|
dst.Storage.Info,
|
||||||
srcRegion,
|
srcRegion,
|
||||||
dstRegion,
|
dstRegion,
|
||||||
src.FirstLayer,
|
src.FirstLayer,
|
||||||
@@ -463,6 +473,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
dstImage.Get(cbs).Value,
|
dstImage.Get(cbs).Value,
|
||||||
src.Info,
|
src.Info,
|
||||||
dst.Info,
|
dst.Info,
|
||||||
|
src.Storage.Info,
|
||||||
|
dst.Storage.Info,
|
||||||
srcRegion,
|
srcRegion,
|
||||||
dstRegion,
|
dstRegion,
|
||||||
src.FirstLayer,
|
src.FirstLayer,
|
||||||
|
|||||||
@@ -68,9 +68,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
int stride = (_stride + (alignment - 1)) & -alignment;
|
int stride = (_stride + (alignment - 1)) & -alignment;
|
||||||
int newSize = (_size / _stride) * stride;
|
int newSize = (_size / _stride) * stride;
|
||||||
|
|
||||||
Buffer buffer = autoBuffer.Get(cbs, 0, newSize).Value;
|
updater.BindVertexBuffer(cbs, binding, autoBuffer, 0, newSize, (ulong)stride);
|
||||||
|
|
||||||
updater.BindVertexBuffer(cbs, binding, buffer, 0, (ulong)newSize, (ulong)stride);
|
|
||||||
|
|
||||||
_buffer = autoBuffer;
|
_buffer = autoBuffer;
|
||||||
|
|
||||||
@@ -93,11 +91,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
if (autoBuffer != null)
|
if (autoBuffer != null)
|
||||||
{
|
{
|
||||||
int offset = _offset;
|
updater.BindVertexBuffer(cbs, binding, autoBuffer, _offset, _size, (ulong)_stride);
|
||||||
bool mirrorable = _size <= VertexBufferMaxMirrorable;
|
|
||||||
Buffer buffer = mirrorable ? autoBuffer.GetMirrorable(cbs, ref offset, _size, out _).Value : autoBuffer.Get(cbs, offset, _size).Value;
|
|
||||||
|
|
||||||
updater.BindVertexBuffer(cbs, binding, buffer, (ulong)offset, (ulong)_size, (ulong)_stride);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,10 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
private readonly NativeArray<ulong> _sizes;
|
private readonly NativeArray<ulong> _sizes;
|
||||||
private readonly NativeArray<ulong> _strides;
|
private readonly NativeArray<ulong> _strides;
|
||||||
|
|
||||||
|
private readonly Auto<DisposableBuffer>[] _bufferAutos;
|
||||||
|
private readonly int[] _bufferOffsetsForGet;
|
||||||
|
private readonly int[] _bufferSizesForGet;
|
||||||
|
|
||||||
public VertexBufferUpdater(VulkanRenderer gd)
|
public VertexBufferUpdater(VulkanRenderer gd)
|
||||||
{
|
{
|
||||||
_gd = gd;
|
_gd = gd;
|
||||||
@@ -23,9 +27,13 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
_offsets = new NativeArray<ulong>(Constants.MaxVertexBuffers);
|
_offsets = new NativeArray<ulong>(Constants.MaxVertexBuffers);
|
||||||
_sizes = new NativeArray<ulong>(Constants.MaxVertexBuffers);
|
_sizes = new NativeArray<ulong>(Constants.MaxVertexBuffers);
|
||||||
_strides = new NativeArray<ulong>(Constants.MaxVertexBuffers);
|
_strides = new NativeArray<ulong>(Constants.MaxVertexBuffers);
|
||||||
|
|
||||||
|
_bufferAutos = new Auto<DisposableBuffer>[Constants.MaxVertexBuffers];
|
||||||
|
_bufferOffsetsForGet = new int[Constants.MaxVertexBuffers];
|
||||||
|
_bufferSizesForGet = new int[Constants.MaxVertexBuffers];
|
||||||
}
|
}
|
||||||
|
|
||||||
public void BindVertexBuffer(CommandBufferScoped cbs, uint binding, VkBuffer buffer, ulong offset, ulong size, ulong stride)
|
public void BindVertexBuffer(CommandBufferScoped cbs, uint binding, Auto<DisposableBuffer> autoBuffer, int offset, int size, ulong stride)
|
||||||
{
|
{
|
||||||
if (_count == 0)
|
if (_count == 0)
|
||||||
{
|
{
|
||||||
@@ -39,9 +47,11 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
int index = (int)_count;
|
int index = (int)_count;
|
||||||
|
|
||||||
_buffers[index] = buffer;
|
_bufferAutos[index] = autoBuffer;
|
||||||
_offsets[index] = offset;
|
_bufferOffsetsForGet[index] = offset;
|
||||||
_sizes[index] = size;
|
_bufferSizesForGet[index] = size;
|
||||||
|
_offsets[index] = (ulong)offset;
|
||||||
|
_sizes[index] = (ulong)size;
|
||||||
_strides[index] = stride;
|
_strides[index] = stride;
|
||||||
|
|
||||||
_count++;
|
_count++;
|
||||||
@@ -51,6 +61,12 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
if (_count != 0)
|
if (_count != 0)
|
||||||
{
|
{
|
||||||
|
for (int i = 0; i < _count; i++)
|
||||||
|
{
|
||||||
|
_buffers[i] = _bufferAutos[i].Get(cbs, _bufferOffsetsForGet[i], _bufferSizesForGet[i]).Value;
|
||||||
|
_bufferAutos[i] = null;
|
||||||
|
}
|
||||||
|
|
||||||
if (_gd.Capabilities.SupportsExtendedDynamicState)
|
if (_gd.Capabilities.SupportsExtendedDynamicState)
|
||||||
{
|
{
|
||||||
_gd.ExtendedDynamicStateApi.CmdBindVertexBuffers2(
|
_gd.ExtendedDynamicStateApi.CmdBindVertexBuffers2(
|
||||||
|
|||||||
@@ -391,12 +391,12 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
if (_effect != null)
|
if (_effect != null)
|
||||||
{
|
{
|
||||||
|
_gd.FlushAllCommands();
|
||||||
_gd.CommandBufferPool.Return(
|
_gd.CommandBufferPool.Return(
|
||||||
cbs,
|
cbs,
|
||||||
null,
|
null,
|
||||||
[PipelineStageFlags.ColorAttachmentOutputBit],
|
[PipelineStageFlags.ColorAttachmentOutputBit],
|
||||||
null);
|
null);
|
||||||
_gd.FlushAllCommands();
|
|
||||||
cbs.GetFence().Wait();
|
cbs.GetFence().Wait();
|
||||||
cbs = _gd.CommandBufferPool.Rent();
|
cbs = _gd.CommandBufferPool.Rent();
|
||||||
}
|
}
|
||||||
@@ -455,6 +455,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
ImageLayout.General,
|
ImageLayout.General,
|
||||||
ImageLayout.PresentSrcKhr);
|
ImageLayout.PresentSrcKhr);
|
||||||
|
|
||||||
|
_gd.FlushAllCommands();
|
||||||
|
|
||||||
_gd.CommandBufferPool.Return(
|
_gd.CommandBufferPool.Return(
|
||||||
cbs,
|
cbs,
|
||||||
[_imageAvailableSemaphores[semaphoreIndex]],
|
[_imageAvailableSemaphores[semaphoreIndex]],
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
|
using Ryujinx.Common.Logging;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.LibraryAppletProxy
|
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.LibraryAppletProxy
|
||||||
@@ -60,6 +61,19 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Lib
|
|||||||
|
|
||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[CommandCmif(10)]
|
||||||
|
// ExitProcessAndReturn -> nn::am::service::LibraryAppletInfo
|
||||||
|
public ResultCode ExitProcessAndReturn(ServiceCtx context)
|
||||||
|
{
|
||||||
|
// Exits the LibraryApplet and returns to running the title which launched this LibraryApplet (qlaunch for example).
|
||||||
|
// On success, official sw will enter an infinite loop with sleep-thread value 86400000000000.
|
||||||
|
// Since we don't currently support qlaunch, it's fine to stub it.
|
||||||
|
|
||||||
|
Logger.Stub?.PrintStub(LogClass.Service);
|
||||||
|
return ResultCode.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[CommandCmif(11)]
|
[CommandCmif(11)]
|
||||||
// GetLibraryAppletInfo() -> nn::am::service::LibraryAppletInfo
|
// GetLibraryAppletInfo() -> nn::am::service::LibraryAppletInfo
|
||||||
@@ -83,7 +97,8 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Lib
|
|||||||
AppletIdentifyInfo appletIdentifyInfo = new()
|
AppletIdentifyInfo appletIdentifyInfo = new()
|
||||||
{
|
{
|
||||||
AppletId = AppletId.QLaunch,
|
AppletId = AppletId.QLaunch,
|
||||||
TitleId = 0x0100000000001000,
|
// 0x4 padding
|
||||||
|
TitleId = 0x0100000000001000, // qlaunch systemAppletMenu title ID
|
||||||
};
|
};
|
||||||
|
|
||||||
context.ResponseData.WriteStruct(appletIdentifyInfo);
|
context.ResponseData.WriteStruct(appletIdentifyInfo);
|
||||||
|
|||||||
@@ -28,21 +28,61 @@ namespace Ryujinx.HLE.Loaders.Processes
|
|||||||
|
|
||||||
private ulong _latestPid;
|
private ulong _latestPid;
|
||||||
|
|
||||||
|
private readonly object _pidLock = new();
|
||||||
|
|
||||||
#nullable enable
|
#nullable enable
|
||||||
public ProcessResult? ActiveApplication
|
public ProcessResult? ActiveApplication
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return _processesByPid.GetValueOrDefault(_latestPid);
|
lock (_pidLock)
|
||||||
|
{
|
||||||
// Using this if statement locks up the UI and prevents a new game from loading.
|
// Check if _latestPid is still valid
|
||||||
// Haven't quite deduced why yet.
|
if (_latestPid == 0)
|
||||||
|
{
|
||||||
if (!_processesByPid.TryGetValue(_latestPid, out ProcessResult value))
|
return null;
|
||||||
throw new RyujinxException(
|
}
|
||||||
$"The HLE Process map did not have a process with ID {_latestPid}. Are you missing firmware?");
|
|
||||||
|
|
||||||
return value;
|
// Verify process still exists in kernel (authoritative source)
|
||||||
|
if (!_device.System.KernelContext.Processes.TryGetValue(_latestPid, out HOS.Kernel.Process.KProcess? kernelProcess))
|
||||||
|
{
|
||||||
|
// Process no longer exists in kernel, clear stale state
|
||||||
|
Logger.Warning?.Print(LogClass.Loader,
|
||||||
|
$"ActiveApplication PID {_latestPid} no longer exists in kernel, clearing stale state");
|
||||||
|
|
||||||
|
_processesByPid.TryRemove(_latestPid, out _);
|
||||||
|
_latestPid = 0;
|
||||||
|
TitleIDs.CurrentApplication.Value = null;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify process still exists in ProcessLoader's dictionary
|
||||||
|
if (_processesByPid.TryGetValue(_latestPid, out ProcessResult? processResult))
|
||||||
|
{
|
||||||
|
// Additional check: verify process state
|
||||||
|
if (kernelProcess.State == HOS.Kernel.Process.ProcessState.Exited ||
|
||||||
|
kernelProcess.State == HOS.Kernel.Process.ProcessState.Exiting)
|
||||||
|
{
|
||||||
|
Logger.Warning?.Print(LogClass.Loader,
|
||||||
|
$"ActiveApplication PID {_latestPid} is in state {kernelProcess.State}, clearing");
|
||||||
|
|
||||||
|
_processesByPid.TryRemove(_latestPid, out _);
|
||||||
|
_latestPid = 0;
|
||||||
|
TitleIDs.CurrentApplication.Value = null;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return processResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback: clear stale PID if not in our dictionary
|
||||||
|
Logger.Warning?.Print(LogClass.Loader,
|
||||||
|
$"ActiveApplication PID {_latestPid} not in ProcessLoader dictionary, clearing");
|
||||||
|
_latestPid = 0;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#nullable disable
|
#nullable disable
|
||||||
@@ -285,5 +325,39 @@ namespace Ryujinx.HLE.Loaders.Processes
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clears a specific process from the ProcessLoader's tracking.
|
||||||
|
/// This should be called when a process exits or is terminated.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pid">The process ID to clear</param>
|
||||||
|
public void ClearProcess(ulong pid)
|
||||||
|
{
|
||||||
|
lock (_pidLock)
|
||||||
|
{
|
||||||
|
if (_processesByPid.TryRemove(pid, out _))
|
||||||
|
{
|
||||||
|
if (_latestPid == pid)
|
||||||
|
{
|
||||||
|
_latestPid = 0;
|
||||||
|
TitleIDs.CurrentApplication.Value = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clears all processes from the ProcessLoader's tracking.
|
||||||
|
/// This should be called during system shutdown.
|
||||||
|
/// </summary>
|
||||||
|
public void ClearAllProcesses()
|
||||||
|
{
|
||||||
|
lock (_pidLock)
|
||||||
|
{
|
||||||
|
_processesByPid.Clear();
|
||||||
|
_latestPid = 0;
|
||||||
|
TitleIDs.CurrentApplication.Value = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -183,6 +183,7 @@ namespace Ryujinx.HLE
|
|||||||
{
|
{
|
||||||
if (disposing)
|
if (disposing)
|
||||||
{
|
{
|
||||||
|
Processes.ClearAllProcesses();
|
||||||
System.Dispose();
|
System.Dispose();
|
||||||
AudioDeviceDriver.Dispose();
|
AudioDeviceDriver.Dispose();
|
||||||
FileSystem.Dispose();
|
FileSystem.Dispose();
|
||||||
|
|||||||
Reference in New Issue
Block a user