Compare commits

..

4 Commits

Author SHA1 Message Date
597388ecda Fix incorrect vertex attribute format change (#5112)
* Fix incorrect vertex attribute format change

* Only change vertex format if the host supports the new format
2023-05-29 00:17:07 +02:00
1cf6d7b7bb Fix #5108: Allow surround sound for SDL2 in more scenarios (#5131) 2023-05-29 00:07:27 +02:00
7bc9d0cdad Linux: Use gamemode if it is available when using Ryujinx.sh. (#4938)
* Linux: Detect if gamemode is installed and start it when launching Ryujinx.

When using the Ryujinx.sh script to start the emulator check if gamemoderun exists and use it if it does.

Gamemode mode on Linux changes some system settings to make performance during gaming more consistent mainly by changing the CPU governor to performance.

https://github.com/FeralInteractive/gamemode

* Removed if statement.

* Fix due to wrong assumption about the output of which.

Checks if the which output contains a no match response, otherwise use gamemoderun.

Using a case statement because it makes substring matching possible in sh and also it turns out that adding an empty string after env throws an error because env attempts to parse it as a paramater.

* Missed a couple semicolons.

* Different approach for checking if gamemode is available.

Should hopefully work across all implementations of which.

* Remove unneeded which command.

* Change code to keep launch command to a single line.
2023-05-28 23:54:22 +02:00
dc0dbc50ab Add support for VK_EXT_depth_clip_control. (#5027)
* Add support for VK_EXT_depth_clip_control.

* Code review feedback

Minor formatting

Co-authored-by: gdkchan <gab.dark.100@gmail.com>

* Check .DepthClipControl to make sure the host actually supports the feature.

* Review feedback: remove Vulkan platform switch, relying on QueryHostSupportsDepthClipControl to drive the behaviour - OpenGL returns true, and any future platforms that don't support the [-1, 1] depth mode can return false for the transformation.

---------

Co-authored-by: gdkchan <gab.dark.100@gmail.com>
2023-05-28 23:31:56 +02:00
14 changed files with 138 additions and 22 deletions

View File

@ -11,4 +11,10 @@ if [ -f "$SCRIPT_DIR/Ryujinx.Headless.SDL2" ]; then
RYUJINX_BIN="Ryujinx.Headless.SDL2" RYUJINX_BIN="Ryujinx.Headless.SDL2"
fi fi
env DOTNET_EnableAlternateStackCheck=1 "$SCRIPT_DIR/$RYUJINX_BIN" "$@" COMMAND="env DOTNET_EnableAlternateStackCheck=1"
if command -v gamemoderun > /dev/null 2>&1; then
COMMAND="$COMMAND gamemoderun"
fi
$COMMAND "$SCRIPT_DIR/$RYUJINX_BIN" "$@"

View File

@ -45,7 +45,7 @@ namespace Ryujinx.Audio.Backends.SDL2
} }
else else
{ {
_supportSurroundConfiguration = spec.channels == 6; _supportSurroundConfiguration = spec.channels >= 6;
} }
} }

View File

@ -39,6 +39,7 @@ namespace Ryujinx.Graphics.GAL
public readonly bool SupportsViewportMask; public readonly bool SupportsViewportMask;
public readonly bool SupportsViewportSwizzle; public readonly bool SupportsViewportSwizzle;
public readonly bool SupportsIndirectParameters; public readonly bool SupportsIndirectParameters;
public readonly bool SupportsDepthClipControl;
public readonly uint MaximumUniformBuffersPerStage; public readonly uint MaximumUniformBuffersPerStage;
public readonly uint MaximumStorageBuffersPerStage; public readonly uint MaximumStorageBuffersPerStage;
@ -85,6 +86,7 @@ namespace Ryujinx.Graphics.GAL
bool supportsViewportMask, bool supportsViewportMask,
bool supportsViewportSwizzle, bool supportsViewportSwizzle,
bool supportsIndirectParameters, bool supportsIndirectParameters,
bool supportsDepthClipControl,
uint maximumUniformBuffersPerStage, uint maximumUniformBuffersPerStage,
uint maximumStorageBuffersPerStage, uint maximumStorageBuffersPerStage,
uint maximumTexturesPerStage, uint maximumTexturesPerStage,
@ -127,6 +129,7 @@ namespace Ryujinx.Graphics.GAL
SupportsViewportMask = supportsViewportMask; SupportsViewportMask = supportsViewportMask;
SupportsViewportSwizzle = supportsViewportSwizzle; SupportsViewportSwizzle = supportsViewportSwizzle;
SupportsIndirectParameters = supportsIndirectParameters; SupportsIndirectParameters = supportsIndirectParameters;
SupportsDepthClipControl = supportsDepthClipControl;
MaximumUniformBuffersPerStage = maximumUniformBuffersPerStage; MaximumUniformBuffersPerStage = maximumUniformBuffersPerStage;
MaximumStorageBuffersPerStage = maximumStorageBuffersPerStage; MaximumStorageBuffersPerStage = maximumStorageBuffersPerStage;
MaximumTexturesPerStage = maximumTexturesPerStage; MaximumTexturesPerStage = maximumTexturesPerStage;

View File

@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
private const ushort FileFormatVersionMajor = 1; private const ushort FileFormatVersionMajor = 1;
private const ushort FileFormatVersionMinor = 2; private const ushort FileFormatVersionMinor = 2;
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor; private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
private const uint CodeGenVersion = 5110; private const uint CodeGenVersion = 5027;
private const string SharedTocFileName = "shared.toc"; private const string SharedTocFileName = "shared.toc";
private const string SharedDataFileName = "shared.data"; private const string SharedDataFileName = "shared.data";

View File

@ -165,6 +165,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
public bool QueryHostSupportsViewportMask() => _context.Capabilities.SupportsViewportMask; public bool QueryHostSupportsViewportMask() => _context.Capabilities.SupportsViewportMask;
public bool QueryHostSupportsDepthClipControl() => _context.Capabilities.SupportsDepthClipControl;
/// <summary> /// <summary>
/// Converts a packed Maxwell texture format to the shader translator texture format. /// Converts a packed Maxwell texture format to the shader translator texture format.
/// </summary> /// </summary>

View File

@ -163,6 +163,7 @@ namespace Ryujinx.Graphics.OpenGL
supportsViewportMask: HwCapabilities.SupportsViewportArray2, supportsViewportMask: HwCapabilities.SupportsViewportArray2,
supportsViewportSwizzle: HwCapabilities.SupportsViewportSwizzle, supportsViewportSwizzle: HwCapabilities.SupportsViewportSwizzle,
supportsIndirectParameters: HwCapabilities.SupportsIndirectParameters, supportsIndirectParameters: HwCapabilities.SupportsIndirectParameters,
supportsDepthClipControl: true,
maximumUniformBuffersPerStage: 13, // TODO: Avoid hardcoding those limits here and get from driver? maximumUniformBuffersPerStage: 13, // TODO: Avoid hardcoding those limits here and get from driver?
maximumStorageBuffersPerStage: 16, maximumStorageBuffersPerStage: 16,
maximumTexturesPerStage: 32, maximumTexturesPerStage: 32,

View File

@ -367,6 +367,15 @@ namespace Ryujinx.Graphics.Shader
return true; return true;
} }
/// <summary>
/// Queries whether the host supports depth clip control.
/// </summary>
/// <returns>True if the GPU and driver supports depth clip control, false otherwise</returns>
bool QueryHostSupportsDepthClipControl()
{
return true;
}
/// <summary> /// <summary>
/// Queries the point size from the GPU state, used when it is not explicitly set on the shader. /// Queries the point size from the GPU state, used when it is not explicitly set on the shader.
/// </summary> /// </summary>

View File

@ -246,7 +246,7 @@ namespace Ryujinx.Graphics.Shader.Translation
this.Store(StorageKind.Output, IoVariable.Position, null, Const(1), this.FPFusedMultiplyAdd(y, yScale, negativeOne)); this.Store(StorageKind.Output, IoVariable.Position, null, Const(1), this.FPFusedMultiplyAdd(y, yScale, negativeOne));
} }
if (Config.Options.TargetApi == TargetApi.Vulkan && Config.GpuAccessor.QueryTransformDepthMinusOneToOne()) if (Config.GpuAccessor.QueryTransformDepthMinusOneToOne() && !Config.GpuAccessor.QueryHostSupportsDepthClipControl())
{ {
Operand z = this.Load(StorageKind.Output, IoVariable.Position, null, Const(2)); Operand z = this.Load(StorageKind.Output, IoVariable.Position, null, Const(2));
Operand w = this.Load(StorageKind.Output, IoVariable.Position, null, Const(3)); Operand w = this.Load(StorageKind.Output, IoVariable.Position, null, Const(3));
@ -283,7 +283,7 @@ namespace Ryujinx.Graphics.Shader.Translation
oldYLocal = null; oldYLocal = null;
} }
if (Config.Options.TargetApi == TargetApi.Vulkan && Config.GpuAccessor.QueryTransformDepthMinusOneToOne()) if (Config.GpuAccessor.QueryTransformDepthMinusOneToOne() && !Config.GpuAccessor.QueryHostSupportsDepthClipControl())
{ {
oldZLocal = Local(); oldZLocal = Local();
this.Copy(oldZLocal, this.Load(StorageKind.Output, IoVariable.Position, null, Const(2))); this.Copy(oldZLocal, this.Load(StorageKind.Output, IoVariable.Position, null, Const(2)));

View File

@ -65,6 +65,13 @@ namespace Ryujinx.Graphics.Vulkan
return (formatFeatureFlags & flags) == flags; return (formatFeatureFlags & flags) == flags;
} }
public bool BufferFormatSupports(FormatFeatureFlags flags, VkFormat format)
{
_api.GetPhysicalDeviceFormatProperties(_physicalDevice, format, out var fp);
return (fp.BufferFeatures & flags) == flags;
}
public bool OptimalFormatSupports(FormatFeatureFlags flags, GAL.Format format) public bool OptimalFormatSupports(FormatFeatureFlags flags, GAL.Format format)
{ {
var formatFeatureFlags = _optimalTable[(int)format]; var formatFeatureFlags = _optimalTable[(int)format];

View File

@ -43,6 +43,7 @@ namespace Ryujinx.Graphics.Vulkan
public readonly bool SupportsGeometryShader; public readonly bool SupportsGeometryShader;
public readonly bool SupportsViewportArray2; public readonly bool SupportsViewportArray2;
public readonly bool SupportsHostImportedMemory; public readonly bool SupportsHostImportedMemory;
public readonly bool SupportsDepthClipControl;
public readonly uint MinSubgroupSize; public readonly uint MinSubgroupSize;
public readonly uint MaxSubgroupSize; public readonly uint MaxSubgroupSize;
public readonly ShaderStageFlags RequiredSubgroupSizeStages; public readonly ShaderStageFlags RequiredSubgroupSizeStages;
@ -79,6 +80,7 @@ namespace Ryujinx.Graphics.Vulkan
bool supportsGeometryShader, bool supportsGeometryShader,
bool supportsViewportArray2, bool supportsViewportArray2,
bool supportsHostImportedMemory, bool supportsHostImportedMemory,
bool supportsDepthClipControl,
uint minSubgroupSize, uint minSubgroupSize,
uint maxSubgroupSize, uint maxSubgroupSize,
ShaderStageFlags requiredSubgroupSizeStages, ShaderStageFlags requiredSubgroupSizeStages,
@ -114,6 +116,7 @@ namespace Ryujinx.Graphics.Vulkan
SupportsGeometryShader = supportsGeometryShader; SupportsGeometryShader = supportsGeometryShader;
SupportsViewportArray2 = supportsViewportArray2; SupportsViewportArray2 = supportsViewportArray2;
SupportsHostImportedMemory = supportsHostImportedMemory; SupportsHostImportedMemory = supportsHostImportedMemory;
SupportsDepthClipControl = supportsDepthClipControl;
MinSubgroupSize = minSubgroupSize; MinSubgroupSize = minSubgroupSize;
MaxSubgroupSize = maxSubgroupSize; MaxSubgroupSize = maxSubgroupSize;
RequiredSubgroupSizeStages = requiredSubgroupSizeStages; RequiredSubgroupSizeStages = requiredSubgroupSizeStages;

View File

@ -551,7 +551,6 @@ namespace Ryujinx.Graphics.Vulkan
(uint)maxDrawCount, (uint)maxDrawCount,
(uint)stride); (uint)stride);
} }
} }
else else
{ {
@ -813,8 +812,12 @@ namespace Ryujinx.Graphics.Vulkan
public void SetDepthMode(DepthMode mode) public void SetDepthMode(DepthMode mode)
{ {
// Currently this is emulated on the shader, because Vulkan had no support for changing the depth mode. bool oldMode = _newState.DepthMode;
// In the future, we may want to use the VK_EXT_depth_clip_control extension to change it here. _newState.DepthMode = mode == DepthMode.MinusOneToOne;
if (_newState.DepthMode != oldMode)
{
SignalStateChange();
}
} }
public void SetDepthTest(DepthTestDescriptor depthTest) public void SetDepthTest(DepthTestDescriptor depthTest)

View File

@ -304,6 +304,12 @@ namespace Ryujinx.Graphics.Vulkan
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFFCF) | ((ulong)value << 4); set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFFCF) | ((ulong)value << 4);
} }
public bool DepthMode
{
get => ((Internal.Id9 >> 6) & 0x1) != 0UL;
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFFBF) | ((value ? 1UL : 0UL) << 6);
}
public NativeArray<PipelineShaderStageCreateInfo> Stages; public NativeArray<PipelineShaderStageCreateInfo> Stages;
public NativeArray<PipelineShaderStageRequiredSubgroupSizeCreateInfoEXT> StageRequiredSubgroupSizes; public NativeArray<PipelineShaderStageRequiredSubgroupSizeCreateInfoEXT> StageRequiredSubgroupSizes;
public PipelineLayout PipelineLayout; public PipelineLayout PipelineLayout;
@ -331,6 +337,7 @@ namespace Ryujinx.Graphics.Vulkan
LineWidth = 1f; LineWidth = 1f;
SamplesCount = 1; SamplesCount = 1;
DepthMode = true;
} }
public unsafe Auto<DisposablePipeline> CreateComputePipeline( public unsafe Auto<DisposablePipeline> CreateComputePipeline(
@ -407,7 +414,7 @@ namespace Ryujinx.Graphics.Vulkan
if (isMoltenVk) if (isMoltenVk)
{ {
UpdateVertexAttributeDescriptions(); UpdateVertexAttributeDescriptions(gd);
} }
fixed (VertexInputAttributeDescription* pVertexAttributeDescriptions = &Internal.VertexAttributeDescriptions[0]) fixed (VertexInputAttributeDescription* pVertexAttributeDescriptions = &Internal.VertexAttributeDescriptions[0])
@ -482,6 +489,17 @@ namespace Ryujinx.Graphics.Vulkan
PScissors = pScissors PScissors = pScissors
}; };
if (gd.Capabilities.SupportsDepthClipControl)
{
var viewportDepthClipControlState = new PipelineViewportDepthClipControlCreateInfoEXT()
{
SType = StructureType.PipelineViewportDepthClipControlCreateInfoExt,
NegativeOneToOne = DepthMode
};
viewportState.PNext = &viewportDepthClipControlState;
}
var multisampleState = new PipelineMultisampleStateCreateInfo var multisampleState = new PipelineMultisampleStateCreateInfo
{ {
SType = StructureType.PipelineMultisampleStateCreateInfo, SType = StructureType.PipelineMultisampleStateCreateInfo,
@ -623,7 +641,7 @@ namespace Ryujinx.Graphics.Vulkan
} }
} }
private void UpdateVertexAttributeDescriptions() private void UpdateVertexAttributeDescriptions(VulkanRenderer gd)
{ {
// Vertex attributes exceeding the stride are invalid. // Vertex attributes exceeding the stride are invalid.
// In metal, they cause glitches with the vertex shader fetching incorrect values. // In metal, they cause glitches with the vertex shader fetching incorrect values.
@ -633,7 +651,11 @@ namespace Ryujinx.Graphics.Vulkan
for (int index = 0; index < VertexAttributeDescriptionsCount; index++) for (int index = 0; index < VertexAttributeDescriptionsCount; index++)
{ {
var attribute = Internal.VertexAttributeDescriptions[index]; var attribute = Internal.VertexAttributeDescriptions[index];
ref var vb = ref Internal.VertexBindingDescriptions[(int)attribute.Binding]; int vbIndex = GetVertexBufferIndex(attribute.Binding);
if (vbIndex >= 0)
{
ref var vb = ref Internal.VertexBindingDescriptions[vbIndex];
Format format = attribute.Format; Format format = attribute.Format;
@ -652,11 +674,29 @@ namespace Ryujinx.Graphics.Vulkan
format = newFormat; format = newFormat;
} }
if (attribute.Format != format && gd.FormatCapabilities.BufferFormatSupports(FormatFeatureFlags.VertexBufferBit, format))
{
attribute.Format = format; attribute.Format = format;
}
}
_vertexAttributeDescriptions2[index] = attribute; _vertexAttributeDescriptions2[index] = attribute;
} }
} }
private int GetVertexBufferIndex(uint binding)
{
for (int index = 0; index < VertexBindingDescriptionsCount; index++)
{
if (Internal.VertexBindingDescriptions[index].Binding == binding)
{
return index;
}
}
return -1;
}
public void Dispose() public void Dispose()
{ {
Stages.Dispose(); Stages.Dispose();

View File

@ -41,6 +41,7 @@ namespace Ryujinx.Graphics.Vulkan
"VK_EXT_subgroup_size_control", "VK_EXT_subgroup_size_control",
"VK_NV_geometry_shader_passthrough", "VK_NV_geometry_shader_passthrough",
"VK_NV_viewport_array2", "VK_NV_viewport_array2",
"VK_EXT_depth_clip_control",
"VK_KHR_portability_subset" // As per spec, we should enable this if present. "VK_KHR_portability_subset" // As per spec, we should enable this if present.
}; };
@ -345,6 +346,17 @@ namespace Ryujinx.Graphics.Vulkan
features2.PNext = &supportedFeaturesRobustness2; features2.PNext = &supportedFeaturesRobustness2;
} }
PhysicalDeviceDepthClipControlFeaturesEXT supportedFeaturesDepthClipControl = new PhysicalDeviceDepthClipControlFeaturesEXT()
{
SType = StructureType.PhysicalDeviceDepthClipControlFeaturesExt,
PNext = features2.PNext
};
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_depth_clip_control"))
{
features2.PNext = &supportedFeaturesDepthClipControl;
}
api.GetPhysicalDeviceFeatures2(physicalDevice.PhysicalDevice, &features2); api.GetPhysicalDeviceFeatures2(physicalDevice.PhysicalDevice, &features2);
var supportedFeatures = features2.Features; var supportedFeatures = features2.Features;
@ -507,6 +519,21 @@ namespace Ryujinx.Graphics.Vulkan
pExtendedFeatures = &featuresCustomBorderColor; pExtendedFeatures = &featuresCustomBorderColor;
} }
PhysicalDeviceDepthClipControlFeaturesEXT featuresDepthClipControl;
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_depth_clip_control") &&
supportedFeaturesDepthClipControl.DepthClipControl)
{
featuresDepthClipControl = new PhysicalDeviceDepthClipControlFeaturesEXT()
{
SType = StructureType.PhysicalDeviceDepthClipControlFeaturesExt,
PNext = pExtendedFeatures,
DepthClipControl = true
};
pExtendedFeatures = &featuresDepthClipControl;
}
var enabledExtensions = _requiredExtensions.Union(_desirableExtensions.Intersect(physicalDevice.DeviceExtensions)).ToArray(); var enabledExtensions = _requiredExtensions.Union(_desirableExtensions.Intersect(physicalDevice.DeviceExtensions)).ToArray();
IntPtr* ppEnabledExtensions = stackalloc IntPtr[enabledExtensions.Length]; IntPtr* ppEnabledExtensions = stackalloc IntPtr[enabledExtensions.Length];

View File

@ -216,6 +216,11 @@ namespace Ryujinx.Graphics.Vulkan
SType = StructureType.PhysicalDeviceCustomBorderColorFeaturesExt SType = StructureType.PhysicalDeviceCustomBorderColorFeaturesExt
}; };
PhysicalDeviceDepthClipControlFeaturesEXT featuresDepthClipControl = new PhysicalDeviceDepthClipControlFeaturesEXT()
{
SType = StructureType.PhysicalDeviceDepthClipControlFeaturesExt
};
PhysicalDevicePortabilitySubsetFeaturesKHR featuresPortabilitySubset = new PhysicalDevicePortabilitySubsetFeaturesKHR() PhysicalDevicePortabilitySubsetFeaturesKHR featuresPortabilitySubset = new PhysicalDevicePortabilitySubsetFeaturesKHR()
{ {
SType = StructureType.PhysicalDevicePortabilitySubsetFeaturesKhr SType = StructureType.PhysicalDevicePortabilitySubsetFeaturesKhr
@ -244,6 +249,14 @@ namespace Ryujinx.Graphics.Vulkan
features2.PNext = &featuresCustomBorderColor; features2.PNext = &featuresCustomBorderColor;
} }
bool supportsDepthClipControl = _physicalDevice.IsDeviceExtensionPresent("VK_EXT_depth_clip_control");
if (supportsDepthClipControl)
{
featuresDepthClipControl.PNext = features2.PNext;
features2.PNext = &featuresDepthClipControl;
}
bool usePortability = _physicalDevice.IsDeviceExtensionPresent("VK_KHR_portability_subset"); bool usePortability = _physicalDevice.IsDeviceExtensionPresent("VK_KHR_portability_subset");
if (usePortability) if (usePortability)
@ -310,6 +323,7 @@ namespace Ryujinx.Graphics.Vulkan
_physicalDevice.PhysicalDeviceFeatures.GeometryShader, _physicalDevice.PhysicalDeviceFeatures.GeometryShader,
_physicalDevice.IsDeviceExtensionPresent("VK_NV_viewport_array2"), _physicalDevice.IsDeviceExtensionPresent("VK_NV_viewport_array2"),
_physicalDevice.IsDeviceExtensionPresent(ExtExternalMemoryHost.ExtensionName), _physicalDevice.IsDeviceExtensionPresent(ExtExternalMemoryHost.ExtensionName),
supportsDepthClipControl && featuresDepthClipControl.DepthClipControl,
propertiesSubgroupSizeControl.MinSubgroupSize, propertiesSubgroupSizeControl.MinSubgroupSize,
propertiesSubgroupSizeControl.MaxSubgroupSize, propertiesSubgroupSizeControl.MaxSubgroupSize,
propertiesSubgroupSizeControl.RequiredSubgroupSizeStages, propertiesSubgroupSizeControl.RequiredSubgroupSizeStages,
@ -585,6 +599,7 @@ namespace Ryujinx.Graphics.Vulkan
supportsViewportMask: Capabilities.SupportsViewportArray2, supportsViewportMask: Capabilities.SupportsViewportArray2,
supportsViewportSwizzle: false, supportsViewportSwizzle: false,
supportsIndirectParameters: true, supportsIndirectParameters: true,
supportsDepthClipControl: Capabilities.SupportsDepthClipControl,
maximumUniformBuffersPerStage: Constants.MaxUniformBuffersPerStage, maximumUniformBuffersPerStage: Constants.MaxUniformBuffersPerStage,
maximumStorageBuffersPerStage: Constants.MaxStorageBuffersPerStage, maximumStorageBuffersPerStage: Constants.MaxStorageBuffersPerStage,
maximumTexturesPerStage: Constants.MaxTexturesPerStage, maximumTexturesPerStage: Constants.MaxTexturesPerStage,