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>
This commit is contained in:
parent
994f4dc77d
commit
dc0dbc50ab
11 changed files with 87 additions and 5 deletions
|
@ -39,6 +39,7 @@ namespace Ryujinx.Graphics.GAL
|
|||
public readonly bool SupportsViewportMask;
|
||||
public readonly bool SupportsViewportSwizzle;
|
||||
public readonly bool SupportsIndirectParameters;
|
||||
public readonly bool SupportsDepthClipControl;
|
||||
|
||||
public readonly uint MaximumUniformBuffersPerStage;
|
||||
public readonly uint MaximumStorageBuffersPerStage;
|
||||
|
@ -85,6 +86,7 @@ namespace Ryujinx.Graphics.GAL
|
|||
bool supportsViewportMask,
|
||||
bool supportsViewportSwizzle,
|
||||
bool supportsIndirectParameters,
|
||||
bool supportsDepthClipControl,
|
||||
uint maximumUniformBuffersPerStage,
|
||||
uint maximumStorageBuffersPerStage,
|
||||
uint maximumTexturesPerStage,
|
||||
|
@ -127,6 +129,7 @@ namespace Ryujinx.Graphics.GAL
|
|||
SupportsViewportMask = supportsViewportMask;
|
||||
SupportsViewportSwizzle = supportsViewportSwizzle;
|
||||
SupportsIndirectParameters = supportsIndirectParameters;
|
||||
SupportsDepthClipControl = supportsDepthClipControl;
|
||||
MaximumUniformBuffersPerStage = maximumUniformBuffersPerStage;
|
||||
MaximumStorageBuffersPerStage = maximumStorageBuffersPerStage;
|
||||
MaximumTexturesPerStage = maximumTexturesPerStage;
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
|||
private const ushort FileFormatVersionMajor = 1;
|
||||
private const ushort FileFormatVersionMinor = 2;
|
||||
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 SharedDataFileName = "shared.data";
|
||||
|
|
|
@ -165,6 +165,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
|
||||
public bool QueryHostSupportsViewportMask() => _context.Capabilities.SupportsViewportMask;
|
||||
|
||||
public bool QueryHostSupportsDepthClipControl() => _context.Capabilities.SupportsDepthClipControl;
|
||||
|
||||
/// <summary>
|
||||
/// Converts a packed Maxwell texture format to the shader translator texture format.
|
||||
/// </summary>
|
||||
|
|
|
@ -163,6 +163,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
supportsViewportMask: HwCapabilities.SupportsViewportArray2,
|
||||
supportsViewportSwizzle: HwCapabilities.SupportsViewportSwizzle,
|
||||
supportsIndirectParameters: HwCapabilities.SupportsIndirectParameters,
|
||||
supportsDepthClipControl: true,
|
||||
maximumUniformBuffersPerStage: 13, // TODO: Avoid hardcoding those limits here and get from driver?
|
||||
maximumStorageBuffersPerStage: 16,
|
||||
maximumTexturesPerStage: 32,
|
||||
|
|
|
@ -367,6 +367,15 @@ namespace Ryujinx.Graphics.Shader
|
|||
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>
|
||||
/// Queries the point size from the GPU state, used when it is not explicitly set on the shader.
|
||||
/// </summary>
|
||||
|
|
|
@ -246,7 +246,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
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 w = this.Load(StorageKind.Output, IoVariable.Position, null, Const(3));
|
||||
|
@ -283,7 +283,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
oldYLocal = null;
|
||||
}
|
||||
|
||||
if (Config.Options.TargetApi == TargetApi.Vulkan && Config.GpuAccessor.QueryTransformDepthMinusOneToOne())
|
||||
if (Config.GpuAccessor.QueryTransformDepthMinusOneToOne() && !Config.GpuAccessor.QueryHostSupportsDepthClipControl())
|
||||
{
|
||||
oldZLocal = Local();
|
||||
this.Copy(oldZLocal, this.Load(StorageKind.Output, IoVariable.Position, null, Const(2)));
|
||||
|
|
|
@ -43,6 +43,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
public readonly bool SupportsGeometryShader;
|
||||
public readonly bool SupportsViewportArray2;
|
||||
public readonly bool SupportsHostImportedMemory;
|
||||
public readonly bool SupportsDepthClipControl;
|
||||
public readonly uint MinSubgroupSize;
|
||||
public readonly uint MaxSubgroupSize;
|
||||
public readonly ShaderStageFlags RequiredSubgroupSizeStages;
|
||||
|
@ -79,6 +80,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
bool supportsGeometryShader,
|
||||
bool supportsViewportArray2,
|
||||
bool supportsHostImportedMemory,
|
||||
bool supportsDepthClipControl,
|
||||
uint minSubgroupSize,
|
||||
uint maxSubgroupSize,
|
||||
ShaderStageFlags requiredSubgroupSizeStages,
|
||||
|
@ -114,6 +116,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
SupportsGeometryShader = supportsGeometryShader;
|
||||
SupportsViewportArray2 = supportsViewportArray2;
|
||||
SupportsHostImportedMemory = supportsHostImportedMemory;
|
||||
SupportsDepthClipControl = supportsDepthClipControl;
|
||||
MinSubgroupSize = minSubgroupSize;
|
||||
MaxSubgroupSize = maxSubgroupSize;
|
||||
RequiredSubgroupSizeStages = requiredSubgroupSizeStages;
|
||||
|
|
|
@ -813,8 +813,12 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
|
||||
public void SetDepthMode(DepthMode mode)
|
||||
{
|
||||
// Currently this is emulated on the shader, because Vulkan had no support for changing the depth mode.
|
||||
// In the future, we may want to use the VK_EXT_depth_clip_control extension to change it here.
|
||||
bool oldMode = _newState.DepthMode;
|
||||
_newState.DepthMode = mode == DepthMode.MinusOneToOne;
|
||||
if (_newState.DepthMode != oldMode)
|
||||
{
|
||||
SignalStateChange();
|
||||
}
|
||||
}
|
||||
|
||||
public void SetDepthTest(DepthTestDescriptor depthTest)
|
||||
|
|
|
@ -304,6 +304,12 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
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<PipelineShaderStageRequiredSubgroupSizeCreateInfoEXT> StageRequiredSubgroupSizes;
|
||||
public PipelineLayout PipelineLayout;
|
||||
|
@ -331,6 +337,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
|
||||
LineWidth = 1f;
|
||||
SamplesCount = 1;
|
||||
DepthMode = true;
|
||||
}
|
||||
|
||||
public unsafe Auto<DisposablePipeline> CreateComputePipeline(
|
||||
|
@ -482,6 +489,17 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
PScissors = pScissors
|
||||
};
|
||||
|
||||
if (gd.Capabilities.SupportsDepthClipControl)
|
||||
{
|
||||
var viewportDepthClipControlState = new PipelineViewportDepthClipControlCreateInfoEXT()
|
||||
{
|
||||
SType = StructureType.PipelineViewportDepthClipControlCreateInfoExt,
|
||||
NegativeOneToOne = DepthMode
|
||||
};
|
||||
|
||||
viewportState.PNext = &viewportDepthClipControlState;
|
||||
}
|
||||
|
||||
var multisampleState = new PipelineMultisampleStateCreateInfo
|
||||
{
|
||||
SType = StructureType.PipelineMultisampleStateCreateInfo,
|
||||
|
|
|
@ -41,6 +41,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
"VK_EXT_subgroup_size_control",
|
||||
"VK_NV_geometry_shader_passthrough",
|
||||
"VK_NV_viewport_array2",
|
||||
"VK_EXT_depth_clip_control",
|
||||
"VK_KHR_portability_subset" // As per spec, we should enable this if present.
|
||||
};
|
||||
|
||||
|
@ -345,6 +346,17 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
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);
|
||||
|
||||
var supportedFeatures = features2.Features;
|
||||
|
@ -507,6 +519,21 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
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();
|
||||
|
||||
IntPtr* ppEnabledExtensions = stackalloc IntPtr[enabledExtensions.Length];
|
||||
|
|
|
@ -216,6 +216,11 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
SType = StructureType.PhysicalDeviceCustomBorderColorFeaturesExt
|
||||
};
|
||||
|
||||
PhysicalDeviceDepthClipControlFeaturesEXT featuresDepthClipControl = new PhysicalDeviceDepthClipControlFeaturesEXT()
|
||||
{
|
||||
SType = StructureType.PhysicalDeviceDepthClipControlFeaturesExt
|
||||
};
|
||||
|
||||
PhysicalDevicePortabilitySubsetFeaturesKHR featuresPortabilitySubset = new PhysicalDevicePortabilitySubsetFeaturesKHR()
|
||||
{
|
||||
SType = StructureType.PhysicalDevicePortabilitySubsetFeaturesKhr
|
||||
|
@ -244,6 +249,14 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
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");
|
||||
|
||||
if (usePortability)
|
||||
|
@ -310,6 +323,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
_physicalDevice.PhysicalDeviceFeatures.GeometryShader,
|
||||
_physicalDevice.IsDeviceExtensionPresent("VK_NV_viewport_array2"),
|
||||
_physicalDevice.IsDeviceExtensionPresent(ExtExternalMemoryHost.ExtensionName),
|
||||
supportsDepthClipControl && featuresDepthClipControl.DepthClipControl,
|
||||
propertiesSubgroupSizeControl.MinSubgroupSize,
|
||||
propertiesSubgroupSizeControl.MaxSubgroupSize,
|
||||
propertiesSubgroupSizeControl.RequiredSubgroupSizeStages,
|
||||
|
@ -585,6 +599,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
supportsViewportMask: Capabilities.SupportsViewportArray2,
|
||||
supportsViewportSwizzle: false,
|
||||
supportsIndirectParameters: true,
|
||||
supportsDepthClipControl: Capabilities.SupportsDepthClipControl,
|
||||
maximumUniformBuffersPerStage: Constants.MaxUniformBuffersPerStage,
|
||||
maximumStorageBuffersPerStage: Constants.MaxStorageBuffersPerStage,
|
||||
maximumTexturesPerStage: Constants.MaxTexturesPerStage,
|
||||
|
|
Reference in a new issue