Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
dca5b14493 | ||
|
4d2c8e2a44 |
@@ -14,6 +14,12 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
MemoryPropertyFlags.HostCoherentBit |
|
MemoryPropertyFlags.HostCoherentBit |
|
||||||
MemoryPropertyFlags.HostCachedBit;
|
MemoryPropertyFlags.HostCachedBit;
|
||||||
|
|
||||||
|
// Some drivers don't expose a "HostCached" memory type,
|
||||||
|
// so we need those alternative flags for the allocation to succeed there.
|
||||||
|
private const MemoryPropertyFlags DefaultBufferMemoryAltFlags =
|
||||||
|
MemoryPropertyFlags.HostVisibleBit |
|
||||||
|
MemoryPropertyFlags.HostCoherentBit;
|
||||||
|
|
||||||
private const MemoryPropertyFlags DeviceLocalBufferMemoryFlags =
|
private const MemoryPropertyFlags DeviceLocalBufferMemoryFlags =
|
||||||
MemoryPropertyFlags.DeviceLocalBit;
|
MemoryPropertyFlags.DeviceLocalBit;
|
||||||
|
|
||||||
@@ -94,9 +100,21 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
gd.Api.CreateBuffer(_device, in bufferCreateInfo, null, out var buffer).ThrowOnError();
|
gd.Api.CreateBuffer(_device, in bufferCreateInfo, null, out var buffer).ThrowOnError();
|
||||||
gd.Api.GetBufferMemoryRequirements(_device, buffer, out var requirements);
|
gd.Api.GetBufferMemoryRequirements(_device, buffer, out var requirements);
|
||||||
|
|
||||||
var allocateFlags = deviceLocal ? DeviceLocalBufferMemoryFlags : DefaultBufferMemoryFlags;
|
MemoryPropertyFlags allocateFlags;
|
||||||
|
MemoryPropertyFlags allocateFlagsAlt;
|
||||||
|
|
||||||
var allocation = gd.MemoryAllocator.AllocateDeviceMemory(_physicalDevice, requirements, allocateFlags);
|
if (deviceLocal)
|
||||||
|
{
|
||||||
|
allocateFlags = DeviceLocalBufferMemoryFlags;
|
||||||
|
allocateFlagsAlt = DeviceLocalBufferMemoryFlags;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
allocateFlags = DefaultBufferMemoryFlags;
|
||||||
|
allocateFlagsAlt = DefaultBufferMemoryAltFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
var allocation = gd.MemoryAllocator.AllocateDeviceMemory(_physicalDevice, requirements, allocateFlags, allocateFlagsAlt);
|
||||||
|
|
||||||
if (allocation.Memory.Handle == 0UL)
|
if (allocation.Memory.Handle == 0UL)
|
||||||
{
|
{
|
||||||
|
@@ -23,7 +23,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
public int[] AttachmentIndices { get; }
|
public int[] AttachmentIndices { get; }
|
||||||
|
|
||||||
public int AttachmentsCount { get; }
|
public int AttachmentsCount { get; }
|
||||||
public int MaxColorAttachmentIndex { get; }
|
public int MaxColorAttachmentIndex => AttachmentIndices.Length > 0 ? AttachmentIndices[AttachmentIndices.Length - 1] : -1;
|
||||||
public bool HasDepthStencil { get; }
|
public bool HasDepthStencil { get; }
|
||||||
public int ColorAttachmentsCount => AttachmentsCount - (HasDepthStencil ? 1 : 0);
|
public int ColorAttachmentsCount => AttachmentsCount - (HasDepthStencil ? 1 : 0);
|
||||||
|
|
||||||
@@ -67,7 +67,6 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
AttachmentSamples = new uint[count];
|
AttachmentSamples = new uint[count];
|
||||||
AttachmentFormats = new VkFormat[count];
|
AttachmentFormats = new VkFormat[count];
|
||||||
AttachmentIndices = new int[count];
|
AttachmentIndices = new int[count];
|
||||||
MaxColorAttachmentIndex = colors.Length - 1;
|
|
||||||
|
|
||||||
uint width = uint.MaxValue;
|
uint width = uint.MaxValue;
|
||||||
uint height = uint.MaxValue;
|
uint height = uint.MaxValue;
|
||||||
|
@@ -27,7 +27,16 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
MemoryRequirements requirements,
|
MemoryRequirements requirements,
|
||||||
MemoryPropertyFlags flags = 0)
|
MemoryPropertyFlags flags = 0)
|
||||||
{
|
{
|
||||||
int memoryTypeIndex = FindSuitableMemoryTypeIndex(_api, physicalDevice, requirements.MemoryTypeBits, flags);
|
return AllocateDeviceMemory(physicalDevice, requirements, flags, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MemoryAllocation AllocateDeviceMemory(
|
||||||
|
PhysicalDevice physicalDevice,
|
||||||
|
MemoryRequirements requirements,
|
||||||
|
MemoryPropertyFlags flags,
|
||||||
|
MemoryPropertyFlags alternativeFlags)
|
||||||
|
{
|
||||||
|
int memoryTypeIndex = FindSuitableMemoryTypeIndex(_api, physicalDevice, requirements.MemoryTypeBits, flags, alternativeFlags);
|
||||||
if (memoryTypeIndex < 0)
|
if (memoryTypeIndex < 0)
|
||||||
{
|
{
|
||||||
return default;
|
return default;
|
||||||
@@ -56,21 +65,35 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
return newBl.Allocate(size, alignment, map);
|
return newBl.Allocate(size, alignment, map);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int FindSuitableMemoryTypeIndex(Vk api, PhysicalDevice physicalDevice, uint memoryTypeBits, MemoryPropertyFlags flags)
|
private static int FindSuitableMemoryTypeIndex(
|
||||||
|
Vk api,
|
||||||
|
PhysicalDevice physicalDevice,
|
||||||
|
uint memoryTypeBits,
|
||||||
|
MemoryPropertyFlags flags,
|
||||||
|
MemoryPropertyFlags alternativeFlags)
|
||||||
{
|
{
|
||||||
|
int bestCandidateIndex = -1;
|
||||||
|
|
||||||
api.GetPhysicalDeviceMemoryProperties(physicalDevice, out var properties);
|
api.GetPhysicalDeviceMemoryProperties(physicalDevice, out var properties);
|
||||||
|
|
||||||
for (int i = 0; i < properties.MemoryTypeCount; i++)
|
for (int i = 0; i < properties.MemoryTypeCount; i++)
|
||||||
{
|
{
|
||||||
var type = properties.MemoryTypes[i];
|
var type = properties.MemoryTypes[i];
|
||||||
|
|
||||||
if ((memoryTypeBits & (1 << i)) != 0 && type.PropertyFlags.HasFlag(flags))
|
if ((memoryTypeBits & (1 << i)) != 0)
|
||||||
{
|
{
|
||||||
return i;
|
if (type.PropertyFlags.HasFlag(flags))
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
else if (type.PropertyFlags.HasFlag(alternativeFlags))
|
||||||
|
{
|
||||||
|
bestCandidateIndex = i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return bestCandidateIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
@@ -1344,8 +1344,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
var dstAttachmentFormats = _newState.Internal.AttachmentFormats.AsSpan();
|
var dstAttachmentFormats = _newState.Internal.AttachmentFormats.AsSpan();
|
||||||
FramebufferParams.AttachmentFormats.CopyTo(dstAttachmentFormats);
|
FramebufferParams.AttachmentFormats.CopyTo(dstAttachmentFormats);
|
||||||
|
|
||||||
int maxAttachmentIndex = FramebufferParams.MaxColorAttachmentIndex + (FramebufferParams.HasDepthStencil ? 1 : 0);
|
for (int i = FramebufferParams.AttachmentFormats.Length; i < dstAttachmentFormats.Length; i++)
|
||||||
for (int i = FramebufferParams.AttachmentFormats.Length; i <= maxAttachmentIndex; i++)
|
|
||||||
{
|
{
|
||||||
dstAttachmentFormats[i] = 0;
|
dstAttachmentFormats[i] = 0;
|
||||||
}
|
}
|
||||||
|
@@ -9,6 +9,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
Intel,
|
Intel,
|
||||||
Nvidia,
|
Nvidia,
|
||||||
ARM,
|
ARM,
|
||||||
|
Broadcom,
|
||||||
Qualcomm,
|
Qualcomm,
|
||||||
Apple,
|
Apple,
|
||||||
Unknown
|
Unknown
|
||||||
@@ -28,6 +29,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
0x106B => Vendor.Apple,
|
0x106B => Vendor.Apple,
|
||||||
0x10DE => Vendor.Nvidia,
|
0x10DE => Vendor.Nvidia,
|
||||||
0x13B5 => Vendor.ARM,
|
0x13B5 => Vendor.ARM,
|
||||||
|
0x14E4 => Vendor.Broadcom,
|
||||||
0x8086 => Vendor.Intel,
|
0x8086 => Vendor.Intel,
|
||||||
0x5143 => Vendor.Qualcomm,
|
0x5143 => Vendor.Qualcomm,
|
||||||
_ => Vendor.Unknown
|
_ => Vendor.Unknown
|
||||||
@@ -43,6 +45,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
0x106B => "Apple",
|
0x106B => "Apple",
|
||||||
0x10DE => "NVIDIA",
|
0x10DE => "NVIDIA",
|
||||||
0x13B5 => "ARM",
|
0x13B5 => "ARM",
|
||||||
|
0x14E4 => "Broadcom",
|
||||||
0x1AE0 => "Google",
|
0x1AE0 => "Google",
|
||||||
0x5143 => "Qualcomm",
|
0x5143 => "Qualcomm",
|
||||||
0x8086 => "Intel",
|
0x8086 => "Intel",
|
||||||
|
@@ -162,7 +162,6 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
if (messageSeverity.HasFlag(DebugUtilsMessageSeverityFlagsEXT.ErrorBitExt))
|
if (messageSeverity.HasFlag(DebugUtilsMessageSeverityFlagsEXT.ErrorBitExt))
|
||||||
{
|
{
|
||||||
Logger.Error?.Print(LogClass.Gpu, msg);
|
Logger.Error?.Print(LogClass.Gpu, msg);
|
||||||
//throw new Exception(msg);
|
|
||||||
}
|
}
|
||||||
else if (messageSeverity.HasFlag(DebugUtilsMessageSeverityFlagsEXT.WarningBitExt))
|
else if (messageSeverity.HasFlag(DebugUtilsMessageSeverityFlagsEXT.WarningBitExt))
|
||||||
{
|
{
|
||||||
@@ -379,14 +378,34 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
SType = StructureType.PhysicalDeviceFeatures2
|
SType = StructureType.PhysicalDeviceFeatures2
|
||||||
};
|
};
|
||||||
|
|
||||||
PhysicalDeviceCustomBorderColorFeaturesEXT featuresCustomBorderColorSupported = new PhysicalDeviceCustomBorderColorFeaturesEXT()
|
PhysicalDeviceVulkan11Features supportedFeaturesVk11 = new PhysicalDeviceVulkan11Features()
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceCustomBorderColorFeaturesExt
|
SType = StructureType.PhysicalDeviceVulkan11Features,
|
||||||
|
PNext = features2.PNext
|
||||||
|
};
|
||||||
|
|
||||||
|
features2.PNext = &supportedFeaturesVk11;
|
||||||
|
|
||||||
|
PhysicalDeviceCustomBorderColorFeaturesEXT supportedFeaturesCustomBorderColor = new PhysicalDeviceCustomBorderColorFeaturesEXT()
|
||||||
|
{
|
||||||
|
SType = StructureType.PhysicalDeviceCustomBorderColorFeaturesExt,
|
||||||
|
PNext = features2.PNext
|
||||||
};
|
};
|
||||||
|
|
||||||
if (supportedExtensions.Contains("VK_EXT_custom_border_color"))
|
if (supportedExtensions.Contains("VK_EXT_custom_border_color"))
|
||||||
{
|
{
|
||||||
features2.PNext = &featuresCustomBorderColorSupported;
|
features2.PNext = &supportedFeaturesCustomBorderColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
PhysicalDeviceTransformFeedbackFeaturesEXT supportedFeaturesTransformFeedback = new PhysicalDeviceTransformFeedbackFeaturesEXT()
|
||||||
|
{
|
||||||
|
SType = StructureType.PhysicalDeviceTransformFeedbackFeaturesExt,
|
||||||
|
PNext = features2.PNext
|
||||||
|
};
|
||||||
|
|
||||||
|
if (supportedExtensions.Contains(ExtTransformFeedback.ExtensionName))
|
||||||
|
{
|
||||||
|
features2.PNext = &supportedFeaturesTransformFeedback;
|
||||||
}
|
}
|
||||||
|
|
||||||
PhysicalDeviceRobustness2FeaturesEXT supportedFeaturesRobustness2 = new PhysicalDeviceRobustness2FeaturesEXT()
|
PhysicalDeviceRobustness2FeaturesEXT supportedFeaturesRobustness2 = new PhysicalDeviceRobustness2FeaturesEXT()
|
||||||
@@ -408,41 +427,48 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
var features = new PhysicalDeviceFeatures()
|
var features = new PhysicalDeviceFeatures()
|
||||||
{
|
{
|
||||||
DepthBiasClamp = true,
|
DepthBiasClamp = true,
|
||||||
DepthClamp = true,
|
DepthClamp = supportedFeatures.DepthClamp,
|
||||||
DualSrcBlend = true,
|
DualSrcBlend = supportedFeatures.DualSrcBlend,
|
||||||
FragmentStoresAndAtomics = true,
|
FragmentStoresAndAtomics = true,
|
||||||
GeometryShader = supportedFeatures.GeometryShader,
|
GeometryShader = supportedFeatures.GeometryShader,
|
||||||
ImageCubeArray = true,
|
ImageCubeArray = true,
|
||||||
IndependentBlend = true,
|
IndependentBlend = true,
|
||||||
LogicOp = supportedFeatures.LogicOp,
|
LogicOp = supportedFeatures.LogicOp,
|
||||||
MultiViewport = true,
|
MultiViewport = supportedFeatures.MultiViewport,
|
||||||
PipelineStatisticsQuery = supportedFeatures.PipelineStatisticsQuery,
|
PipelineStatisticsQuery = supportedFeatures.PipelineStatisticsQuery,
|
||||||
SamplerAnisotropy = true,
|
SamplerAnisotropy = true,
|
||||||
ShaderClipDistance = true,
|
ShaderClipDistance = true,
|
||||||
ShaderFloat64 = supportedFeatures.ShaderFloat64,
|
ShaderFloat64 = supportedFeatures.ShaderFloat64,
|
||||||
ShaderImageGatherExtended = true,
|
ShaderImageGatherExtended = supportedFeatures.ShaderImageGatherExtended,
|
||||||
ShaderStorageImageMultisample = supportedFeatures.ShaderStorageImageMultisample,
|
ShaderStorageImageMultisample = supportedFeatures.ShaderStorageImageMultisample,
|
||||||
// ShaderStorageImageReadWithoutFormat = true,
|
// ShaderStorageImageReadWithoutFormat = true,
|
||||||
// ShaderStorageImageWriteWithoutFormat = true,
|
// ShaderStorageImageWriteWithoutFormat = true,
|
||||||
TessellationShader = true,
|
TessellationShader = supportedFeatures.TessellationShader,
|
||||||
VertexPipelineStoresAndAtomics = true,
|
VertexPipelineStoresAndAtomics = true,
|
||||||
RobustBufferAccess = useRobustBufferAccess
|
RobustBufferAccess = useRobustBufferAccess
|
||||||
};
|
};
|
||||||
|
|
||||||
void* pExtendedFeatures = null;
|
void* pExtendedFeatures = null;
|
||||||
|
|
||||||
var featuresTransformFeedback = new PhysicalDeviceTransformFeedbackFeaturesEXT()
|
PhysicalDeviceTransformFeedbackFeaturesEXT featuresTransformFeedback;
|
||||||
{
|
|
||||||
SType = StructureType.PhysicalDeviceTransformFeedbackFeaturesExt,
|
|
||||||
PNext = pExtendedFeatures,
|
|
||||||
TransformFeedback = true
|
|
||||||
};
|
|
||||||
|
|
||||||
pExtendedFeatures = &featuresTransformFeedback;
|
if (supportedExtensions.Contains(ExtTransformFeedback.ExtensionName))
|
||||||
|
{
|
||||||
|
featuresTransformFeedback = new PhysicalDeviceTransformFeedbackFeaturesEXT()
|
||||||
|
{
|
||||||
|
SType = StructureType.PhysicalDeviceTransformFeedbackFeaturesExt,
|
||||||
|
PNext = pExtendedFeatures,
|
||||||
|
TransformFeedback = supportedFeaturesTransformFeedback.TransformFeedback
|
||||||
|
};
|
||||||
|
|
||||||
|
pExtendedFeatures = &featuresTransformFeedback;
|
||||||
|
}
|
||||||
|
|
||||||
|
PhysicalDeviceRobustness2FeaturesEXT featuresRobustness2;
|
||||||
|
|
||||||
if (supportedExtensions.Contains("VK_EXT_robustness2"))
|
if (supportedExtensions.Contains("VK_EXT_robustness2"))
|
||||||
{
|
{
|
||||||
var featuresRobustness2 = new PhysicalDeviceRobustness2FeaturesEXT()
|
featuresRobustness2 = new PhysicalDeviceRobustness2FeaturesEXT()
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceRobustness2FeaturesExt,
|
SType = StructureType.PhysicalDeviceRobustness2FeaturesExt,
|
||||||
PNext = pExtendedFeatures,
|
PNext = pExtendedFeatures,
|
||||||
@@ -465,7 +491,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceVulkan11Features,
|
SType = StructureType.PhysicalDeviceVulkan11Features,
|
||||||
PNext = pExtendedFeatures,
|
PNext = pExtendedFeatures,
|
||||||
ShaderDrawParameters = true
|
ShaderDrawParameters = supportedFeaturesVk11.ShaderDrawParameters
|
||||||
};
|
};
|
||||||
|
|
||||||
pExtendedFeatures = &featuresVk11;
|
pExtendedFeatures = &featuresVk11;
|
||||||
@@ -526,8 +552,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
PhysicalDeviceCustomBorderColorFeaturesEXT featuresCustomBorderColor;
|
PhysicalDeviceCustomBorderColorFeaturesEXT featuresCustomBorderColor;
|
||||||
|
|
||||||
if (supportedExtensions.Contains("VK_EXT_custom_border_color") &&
|
if (supportedExtensions.Contains("VK_EXT_custom_border_color") &&
|
||||||
featuresCustomBorderColorSupported.CustomBorderColors &&
|
supportedFeaturesCustomBorderColor.CustomBorderColors &&
|
||||||
featuresCustomBorderColorSupported.CustomBorderColorWithoutFormat)
|
supportedFeaturesCustomBorderColor.CustomBorderColorWithoutFormat)
|
||||||
{
|
{
|
||||||
featuresCustomBorderColor = new PhysicalDeviceCustomBorderColorFeaturesEXT()
|
featuresCustomBorderColor = new PhysicalDeviceCustomBorderColorFeaturesEXT()
|
||||||
{
|
{
|
||||||
|
@@ -590,7 +590,11 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
IsAmdWindows = Vendor == Vendor.Amd && RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
IsAmdWindows = Vendor == Vendor.Amd && RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
||||||
IsIntelWindows = Vendor == Vendor.Intel && RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
IsIntelWindows = Vendor == Vendor.Intel && RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
||||||
IsTBDR = IsMoltenVk || Vendor == Vendor.Qualcomm || Vendor == Vendor.ARM || Vendor == Vendor.ImgTec;
|
IsTBDR = IsMoltenVk ||
|
||||||
|
Vendor == Vendor.Qualcomm ||
|
||||||
|
Vendor == Vendor.ARM ||
|
||||||
|
Vendor == Vendor.Broadcom ||
|
||||||
|
Vendor == Vendor.ImgTec;
|
||||||
|
|
||||||
GpuVendor = vendorName;
|
GpuVendor = vendorName;
|
||||||
GpuRenderer = Marshal.PtrToStringAnsi((IntPtr)properties.DeviceName);
|
GpuRenderer = Marshal.PtrToStringAnsi((IntPtr)properties.DeviceName);
|
||||||
|
@@ -113,7 +113,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
ImageSharingMode = SharingMode.Exclusive,
|
ImageSharingMode = SharingMode.Exclusive,
|
||||||
ImageArrayLayers = 1,
|
ImageArrayLayers = 1,
|
||||||
PreTransform = capabilities.CurrentTransform,
|
PreTransform = capabilities.CurrentTransform,
|
||||||
CompositeAlpha = CompositeAlphaFlagsKHR.OpaqueBitKhr,
|
CompositeAlpha = ChooseCompositeAlpha(capabilities.SupportedCompositeAlpha),
|
||||||
PresentMode = ChooseSwapPresentMode(presentModes, _vsyncEnabled),
|
PresentMode = ChooseSwapPresentMode(presentModes, _vsyncEnabled),
|
||||||
Clipped = true,
|
Clipped = true,
|
||||||
OldSwapchain = oldSwapchain
|
OldSwapchain = oldSwapchain
|
||||||
@@ -182,6 +182,22 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
return availableFormats[0];
|
return availableFormats[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static CompositeAlphaFlagsKHR ChooseCompositeAlpha(CompositeAlphaFlagsKHR supportedFlags)
|
||||||
|
{
|
||||||
|
if (supportedFlags.HasFlag(CompositeAlphaFlagsKHR.OpaqueBitKhr))
|
||||||
|
{
|
||||||
|
return CompositeAlphaFlagsKHR.OpaqueBitKhr;
|
||||||
|
}
|
||||||
|
else if (supportedFlags.HasFlag(CompositeAlphaFlagsKHR.PreMultipliedBitKhr))
|
||||||
|
{
|
||||||
|
return CompositeAlphaFlagsKHR.PreMultipliedBitKhr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return CompositeAlphaFlagsKHR.InheritBitKhr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static PresentModeKHR ChooseSwapPresentMode(PresentModeKHR[] availablePresentModes, bool vsyncEnabled)
|
private static PresentModeKHR ChooseSwapPresentMode(PresentModeKHR[] availablePresentModes, bool vsyncEnabled)
|
||||||
{
|
{
|
||||||
if (!vsyncEnabled && availablePresentModes.Contains(PresentModeKHR.ImmediateKhr))
|
if (!vsyncEnabled && availablePresentModes.Contains(PresentModeKHR.ImmediateKhr))
|
||||||
@@ -192,10 +208,6 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
return PresentModeKHR.MailboxKhr;
|
return PresentModeKHR.MailboxKhr;
|
||||||
}
|
}
|
||||||
else if (availablePresentModes.Contains(PresentModeKHR.FifoKhr))
|
|
||||||
{
|
|
||||||
return PresentModeKHR.FifoKhr;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return PresentModeKHR.FifoKhr;
|
return PresentModeKHR.FifoKhr;
|
||||||
|
@@ -267,6 +267,8 @@ namespace Ryujinx.Horizon.Generators.Hipc
|
|||||||
}
|
}
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
int inArgIndex = 0;
|
||||||
|
int outArgIndex = 0;
|
||||||
int inCopyHandleIndex = 0;
|
int inCopyHandleIndex = 0;
|
||||||
int inMoveHandleIndex = 0;
|
int inMoveHandleIndex = 0;
|
||||||
int inObjectIndex = 0;
|
int inObjectIndex = 0;
|
||||||
@@ -284,7 +286,7 @@ namespace Ryujinx.Horizon.Generators.Hipc
|
|||||||
{
|
{
|
||||||
if (IsNonSpanOutBuffer(compilation, parameter))
|
if (IsNonSpanOutBuffer(compilation, parameter))
|
||||||
{
|
{
|
||||||
generator.AppendLine($"using var {argName} = CommandSerialization.GetWritableRegion(processor.GetBufferRange({index}));");
|
generator.AppendLine($"using var {argName} = CommandSerialization.GetWritableRegion(processor.GetBufferRange({outArgIndex++}));");
|
||||||
|
|
||||||
argName = $"out {GenerateSpanCastElement0(canonicalTypeName, $"{argName}.Memory.Span")}";
|
argName = $"out {GenerateSpanCastElement0(canonicalTypeName, $"{argName}.Memory.Span")}";
|
||||||
}
|
}
|
||||||
@@ -302,7 +304,7 @@ namespace Ryujinx.Horizon.Generators.Hipc
|
|||||||
switch (argType)
|
switch (argType)
|
||||||
{
|
{
|
||||||
case CommandArgType.InArgument:
|
case CommandArgType.InArgument:
|
||||||
value = $"CommandSerialization.DeserializeArg<{canonicalTypeName}>(inRawData, processor.GetInArgOffset({index}))";
|
value = $"CommandSerialization.DeserializeArg<{canonicalTypeName}>(inRawData, processor.GetInArgOffset({inArgIndex++}))";
|
||||||
break;
|
break;
|
||||||
case CommandArgType.InCopyHandle:
|
case CommandArgType.InCopyHandle:
|
||||||
value = $"CommandSerialization.DeserializeCopyHandle(ref context, {inCopyHandleIndex++})";
|
value = $"CommandSerialization.DeserializeCopyHandle(ref context, {inCopyHandleIndex++})";
|
||||||
|
@@ -42,7 +42,7 @@ namespace Ryujinx.Horizon.Prepo.Ipc
|
|||||||
return PrepoResult.PermissionDenied;
|
return PrepoResult.PermissionDenied;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessPlayReport(PlayReportKind.Normal, pid, gameRoomBuffer, reportBuffer, Uid.Null);
|
ProcessPlayReport(PlayReportKind.Normal, gameRoomBuffer, reportBuffer, pid, Uid.Null);
|
||||||
|
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
@@ -57,7 +57,7 @@ namespace Ryujinx.Horizon.Prepo.Ipc
|
|||||||
return PrepoResult.PermissionDenied;
|
return PrepoResult.PermissionDenied;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessPlayReport(PlayReportKind.Normal, pid, gameRoomBuffer, reportBuffer, userId, true);
|
ProcessPlayReport(PlayReportKind.Normal, gameRoomBuffer, reportBuffer, pid, userId, true);
|
||||||
|
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
@@ -107,25 +107,25 @@ namespace Ryujinx.Horizon.Prepo.Ipc
|
|||||||
}
|
}
|
||||||
|
|
||||||
[CmifCommand(20100)]
|
[CmifCommand(20100)]
|
||||||
public Result SaveSystemReport([Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer)] ReadOnlySpan<byte> gameRoomBuffer, [Buffer(HipcBufferFlags.In | HipcBufferFlags.MapAlias)] ReadOnlySpan<byte> reportBuffer, [ClientProcessId] ulong pid)
|
public Result SaveSystemReport([Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer)] ReadOnlySpan<byte> gameRoomBuffer, Sdk.Ncm.ApplicationId applicationId, [Buffer(HipcBufferFlags.In | HipcBufferFlags.MapAlias)] ReadOnlySpan<byte> reportBuffer)
|
||||||
{
|
{
|
||||||
if ((_permissionLevel & PrepoServicePermissionLevel.System) != 0)
|
if ((_permissionLevel & PrepoServicePermissionLevel.System) != 0)
|
||||||
{
|
{
|
||||||
return PrepoResult.PermissionDenied;
|
return PrepoResult.PermissionDenied;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ProcessPlayReport(PlayReportKind.System, pid, gameRoomBuffer, reportBuffer, Uid.Null);
|
return ProcessPlayReport(PlayReportKind.System, gameRoomBuffer, reportBuffer, 0, Uid.Null, false, applicationId);
|
||||||
}
|
}
|
||||||
|
|
||||||
[CmifCommand(20101)]
|
[CmifCommand(20101)]
|
||||||
public Result SaveSystemReportWithUser(Uid userId, [Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer)] ReadOnlySpan<byte> gameRoomBuffer, [Buffer(HipcBufferFlags.In | HipcBufferFlags.MapAlias)] ReadOnlySpan<byte> reportBuffer, [ClientProcessId] ulong pid)
|
public Result SaveSystemReportWithUser(Uid userId, [Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer)] ReadOnlySpan<byte> gameRoomBuffer, Sdk.Ncm.ApplicationId applicationId, [Buffer(HipcBufferFlags.In | HipcBufferFlags.MapAlias)] ReadOnlySpan<byte> reportBuffer)
|
||||||
{
|
{
|
||||||
if ((_permissionLevel & PrepoServicePermissionLevel.System) != 0)
|
if ((_permissionLevel & PrepoServicePermissionLevel.System) != 0)
|
||||||
{
|
{
|
||||||
return PrepoResult.PermissionDenied;
|
return PrepoResult.PermissionDenied;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ProcessPlayReport(PlayReportKind.System, pid, gameRoomBuffer, reportBuffer, userId, true);
|
return ProcessPlayReport(PlayReportKind.System, gameRoomBuffer, reportBuffer, 0, userId, true, applicationId);
|
||||||
}
|
}
|
||||||
|
|
||||||
[CmifCommand(40100)] // 2.0.0+
|
[CmifCommand(40100)] // 2.0.0+
|
||||||
@@ -164,7 +164,7 @@ namespace Ryujinx.Horizon.Prepo.Ipc
|
|||||||
return PrepoResult.PermissionDenied;
|
return PrepoResult.PermissionDenied;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Result ProcessPlayReport(PlayReportKind playReportKind, ulong pid, ReadOnlySpan<byte> gameRoomBuffer, ReadOnlySpan<byte> reportBuffer, Uid userId, bool withUserId = false)
|
private static Result ProcessPlayReport(PlayReportKind playReportKind, ReadOnlySpan<byte> gameRoomBuffer, ReadOnlySpan<byte> reportBuffer, ulong pid, Uid userId, bool withUserId = false, Sdk.Ncm.ApplicationId applicationId = default)
|
||||||
{
|
{
|
||||||
if (withUserId)
|
if (withUserId)
|
||||||
{
|
{
|
||||||
@@ -191,16 +191,23 @@ namespace Ryujinx.Horizon.Prepo.Ipc
|
|||||||
return PrepoResult.InvalidBufferSize;
|
return PrepoResult.InvalidBufferSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: The service calls arp:r using the pid to get the application id, if it fails PrepoResult.InvalidPid is returned.
|
|
||||||
// Reports are stored internally and an event is signaled to transmit them.
|
|
||||||
|
|
||||||
StringBuilder builder = new();
|
StringBuilder builder = new();
|
||||||
MessagePackObject deserializedReport = MessagePackSerializer.UnpackMessagePackObject(reportBuffer.ToArray());
|
MessagePackObject deserializedReport = MessagePackSerializer.UnpackMessagePackObject(reportBuffer.ToArray());
|
||||||
|
|
||||||
builder.AppendLine();
|
builder.AppendLine();
|
||||||
builder.AppendLine("PlayReport log:");
|
builder.AppendLine("PlayReport log:");
|
||||||
builder.AppendLine($" Kind: {playReportKind}");
|
builder.AppendLine($" Kind: {playReportKind}");
|
||||||
builder.AppendLine($" Pid: {pid}");
|
|
||||||
|
// NOTE: The service calls arp:r using the pid to get the application id, if it fails PrepoResult.InvalidPid is returned.
|
||||||
|
// Reports are stored internally and an event is signaled to transmit them.
|
||||||
|
if (pid != 0)
|
||||||
|
{
|
||||||
|
builder.AppendLine($" Pid: {pid}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
builder.AppendLine($" ApplicationId: {applicationId}");
|
||||||
|
}
|
||||||
|
|
||||||
if (!userId.IsNull)
|
if (!userId.IsNull)
|
||||||
{
|
{
|
||||||
|
@@ -6,7 +6,7 @@ using System.Runtime.InteropServices;
|
|||||||
namespace Ryujinx.Horizon.Sdk.Account
|
namespace Ryujinx.Horizon.Sdk.Account
|
||||||
{
|
{
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public readonly record struct Uid
|
readonly record struct Uid
|
||||||
{
|
{
|
||||||
public readonly long High;
|
public readonly long High;
|
||||||
public readonly long Low;
|
public readonly long Low;
|
||||||
|
52
Ryujinx.Horizon/Sdk/Ncm/ApplicationId.cs
Normal file
52
Ryujinx.Horizon/Sdk/Ncm/ApplicationId.cs
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
namespace Ryujinx.Horizon.Sdk.Ncm
|
||||||
|
{
|
||||||
|
readonly struct ApplicationId
|
||||||
|
{
|
||||||
|
public readonly ulong Id;
|
||||||
|
|
||||||
|
public static int Length => sizeof(ulong);
|
||||||
|
|
||||||
|
public static ApplicationId First => new(0x0100000000010000);
|
||||||
|
|
||||||
|
public static ApplicationId Last => new(0x01FFFFFFFFFFFFFF);
|
||||||
|
|
||||||
|
public static ApplicationId Invalid => new(0);
|
||||||
|
|
||||||
|
public bool IsValid => Id >= First.Id && Id <= Last.Id;
|
||||||
|
|
||||||
|
public ApplicationId(ulong id)
|
||||||
|
{
|
||||||
|
Id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
return obj is ApplicationId applicationId && applicationId.Equals(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Equals(ApplicationId other)
|
||||||
|
{
|
||||||
|
return other.Id == Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return Id.GetHashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator ==(ApplicationId lhs, ApplicationId rhs)
|
||||||
|
{
|
||||||
|
return lhs.Equals(rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator !=(ApplicationId lhs, ApplicationId rhs)
|
||||||
|
{
|
||||||
|
return !lhs.Equals(rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"0x{Id:x}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -12,8 +12,8 @@ namespace Ryujinx.Horizon.Sdk.Prepo
|
|||||||
Result RequestImmediateTransmission();
|
Result RequestImmediateTransmission();
|
||||||
Result GetTransmissionStatus(out int status);
|
Result GetTransmissionStatus(out int status);
|
||||||
Result GetSystemSessionId(out ulong systemSessionId);
|
Result GetSystemSessionId(out ulong systemSessionId);
|
||||||
Result SaveSystemReport(ReadOnlySpan<byte> gameRoomBuffer, ReadOnlySpan<byte> reportBuffer, ulong pid);
|
Result SaveSystemReport(ReadOnlySpan<byte> gameRoomBuffer, Ncm.ApplicationId applicationId, ReadOnlySpan<byte> reportBuffer);
|
||||||
Result SaveSystemReportWithUser(Uid userId, ReadOnlySpan<byte> gameRoomBuffer, ReadOnlySpan<byte> reportBuffer, ulong pid);
|
Result SaveSystemReportWithUser(Uid userId, ReadOnlySpan<byte> gameRoomBuffer, Ncm.ApplicationId applicationId, ReadOnlySpan<byte> reportBuffer);
|
||||||
Result IsUserAgreementCheckEnabled(out bool enabled);
|
Result IsUserAgreementCheckEnabled(out bool enabled);
|
||||||
Result SetUserAgreementCheckEnabled(bool enabled);
|
Result SetUserAgreementCheckEnabled(bool enabled);
|
||||||
}
|
}
|
||||||
|
@@ -8,7 +8,7 @@ namespace Ryujinx.Horizon.Sdk.Sm
|
|||||||
{
|
{
|
||||||
public static ServiceName Invalid { get; } = new ServiceName(0);
|
public static ServiceName Invalid { get; } = new ServiceName(0);
|
||||||
|
|
||||||
public bool IsInvalid => Packed == 0;
|
public bool IsValid => Packed != 0;
|
||||||
|
|
||||||
public int Length => sizeof(ulong);
|
public int Length => sizeof(ulong);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user