vulkan: Respect VK_KHR_portability_subset vertex stride alignment (#4419)
* vulkan: Respect VK_KHR_portability_subset vertex stride alignment We were hardcoding alignment to 4, but by specs it can be any values that is a power of 2. This also enable VK_KHR_portability_subset if present as per specs requirements. * address gdkchan's comment * Make NeedsVertexBufferAlignment internal
This commit is contained in:
parent
32450d45de
commit
17078ad929
5 changed files with 24 additions and 16 deletions
|
@ -8,11 +8,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
None = 0,
|
None = 0,
|
||||||
|
|
||||||
VertexBufferAlignment4B = 1,
|
NoTriangleFans = 1,
|
||||||
NoTriangleFans = 1 << 1,
|
NoPointMode = 1 << 1,
|
||||||
NoPointMode = 1 << 2,
|
No3DImageView = 1 << 2,
|
||||||
No3DImageView = 1 << 3,
|
NoLodBias = 1 << 3
|
||||||
NoLodBias = 1 << 4
|
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly struct HardwareCapabilities
|
readonly struct HardwareCapabilities
|
||||||
|
@ -40,6 +39,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
public readonly ShaderStageFlags RequiredSubgroupSizeStages;
|
public readonly ShaderStageFlags RequiredSubgroupSizeStages;
|
||||||
public readonly SampleCountFlags SupportedSampleCounts;
|
public readonly SampleCountFlags SupportedSampleCounts;
|
||||||
public readonly PortabilitySubsetFlags PortabilitySubset;
|
public readonly PortabilitySubsetFlags PortabilitySubset;
|
||||||
|
public readonly uint VertexBufferAlignment;
|
||||||
|
|
||||||
public HardwareCapabilities(
|
public HardwareCapabilities(
|
||||||
bool supportsIndexTypeUint8,
|
bool supportsIndexTypeUint8,
|
||||||
|
@ -64,7 +64,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
uint maxSubgroupSize,
|
uint maxSubgroupSize,
|
||||||
ShaderStageFlags requiredSubgroupSizeStages,
|
ShaderStageFlags requiredSubgroupSizeStages,
|
||||||
SampleCountFlags supportedSampleCounts,
|
SampleCountFlags supportedSampleCounts,
|
||||||
PortabilitySubsetFlags portabilitySubset)
|
PortabilitySubsetFlags portabilitySubset,
|
||||||
|
uint vertexBufferAlignment)
|
||||||
{
|
{
|
||||||
SupportsIndexTypeUint8 = supportsIndexTypeUint8;
|
SupportsIndexTypeUint8 = supportsIndexTypeUint8;
|
||||||
SupportsCustomBorderColor = supportsCustomBorderColor;
|
SupportsCustomBorderColor = supportsCustomBorderColor;
|
||||||
|
@ -89,6 +90,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
RequiredSubgroupSizeStages = requiredSubgroupSizeStages;
|
RequiredSubgroupSizeStages = requiredSubgroupSizeStages;
|
||||||
SupportedSampleCounts = supportedSampleCounts;
|
SupportedSampleCounts = supportedSampleCounts;
|
||||||
PortabilitySubset = portabilitySubset;
|
PortabilitySubset = portabilitySubset;
|
||||||
|
VertexBufferAlignment = vertexBufferAlignment;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Common;
|
||||||
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.Shader;
|
using Ryujinx.Graphics.Shader;
|
||||||
using Silk.NET.Vulkan;
|
using Silk.NET.Vulkan;
|
||||||
using System;
|
using System;
|
||||||
|
@ -1136,7 +1137,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
buffer.Dispose();
|
buffer.Dispose();
|
||||||
|
|
||||||
if (!Gd.Capabilities.PortabilitySubset.HasFlag(PortabilitySubsetFlags.VertexBufferAlignment4B) &&
|
if (Gd.Capabilities.VertexBufferAlignment < 2 &&
|
||||||
(vertexBuffer.Stride % FormatExtensions.MaxBufferFormatScalarSize) == 0)
|
(vertexBuffer.Stride % FormatExtensions.MaxBufferFormatScalarSize) == 0)
|
||||||
{
|
{
|
||||||
buffer = new VertexBufferState(
|
buffer = new VertexBufferState(
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Common;
|
||||||
|
using Ryujinx.Graphics.GAL;
|
||||||
using Silk.NET.Vulkan;
|
using Silk.NET.Vulkan;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
|
@ -253,7 +254,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
if (gd.NeedsVertexBufferAlignment(vbScalarSizes[i], out int alignment))
|
if (gd.NeedsVertexBufferAlignment(vbScalarSizes[i], out int alignment))
|
||||||
{
|
{
|
||||||
alignedStride = (vertexBuffer.Stride + (alignment - 1)) & -alignment;
|
alignedStride = BitUtils.AlignUp(vertexBuffer.Stride, alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Support divisor > 1
|
// TODO: Support divisor > 1
|
||||||
|
|
|
@ -36,7 +36,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
"VK_KHR_shader_float16_int8",
|
"VK_KHR_shader_float16_int8",
|
||||||
"VK_EXT_shader_subgroup_ballot",
|
"VK_EXT_shader_subgroup_ballot",
|
||||||
"VK_EXT_subgroup_size_control",
|
"VK_EXT_subgroup_size_control",
|
||||||
"VK_NV_geometry_shader_passthrough"
|
"VK_NV_geometry_shader_passthrough",
|
||||||
|
"VK_KHR_portability_subset", // By spec, we should enable this if present.
|
||||||
};
|
};
|
||||||
|
|
||||||
public static string[] RequiredExtensions { get; } = new string[]
|
public static string[] RequiredExtensions { get; } = new string[]
|
||||||
|
|
|
@ -234,10 +234,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
Api.GetPhysicalDeviceFeatures2(_physicalDevice, &features2);
|
Api.GetPhysicalDeviceFeatures2(_physicalDevice, &features2);
|
||||||
|
|
||||||
var portabilityFlags = PortabilitySubsetFlags.None;
|
var portabilityFlags = PortabilitySubsetFlags.None;
|
||||||
|
uint vertexBufferAlignment = 1;
|
||||||
|
|
||||||
if (usePortability)
|
if (usePortability)
|
||||||
{
|
{
|
||||||
portabilityFlags |= propertiesPortabilitySubset.MinVertexInputBindingStrideAlignment > 1 ? PortabilitySubsetFlags.VertexBufferAlignment4B : 0;
|
vertexBufferAlignment = propertiesPortabilitySubset.MinVertexInputBindingStrideAlignment;
|
||||||
|
|
||||||
portabilityFlags |= featuresPortabilitySubset.TriangleFans ? 0 : PortabilitySubsetFlags.NoTriangleFans;
|
portabilityFlags |= featuresPortabilitySubset.TriangleFans ? 0 : PortabilitySubsetFlags.NoTriangleFans;
|
||||||
portabilityFlags |= featuresPortabilitySubset.PointPolygons ? 0 : PortabilitySubsetFlags.NoPointMode;
|
portabilityFlags |= featuresPortabilitySubset.PointPolygons ? 0 : PortabilitySubsetFlags.NoPointMode;
|
||||||
portabilityFlags |= featuresPortabilitySubset.ImageView2DOn3DImage ? 0 : PortabilitySubsetFlags.No3DImageView;
|
portabilityFlags |= featuresPortabilitySubset.ImageView2DOn3DImage ? 0 : PortabilitySubsetFlags.No3DImageView;
|
||||||
|
@ -278,7 +280,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
propertiesSubgroupSizeControl.MaxSubgroupSize,
|
propertiesSubgroupSizeControl.MaxSubgroupSize,
|
||||||
propertiesSubgroupSizeControl.RequiredSubgroupSizeStages,
|
propertiesSubgroupSizeControl.RequiredSubgroupSizeStages,
|
||||||
supportedSampleCounts,
|
supportedSampleCounts,
|
||||||
portabilityFlags);
|
portabilityFlags,
|
||||||
|
vertexBufferAlignment);
|
||||||
|
|
||||||
MemoryAllocator = new MemoryAllocator(Api, _physicalDevice, _device, properties.Limits.MaxMemoryAllocationCount);
|
MemoryAllocator = new MemoryAllocator(Api, _physicalDevice, _device, properties.Limits.MaxMemoryAllocationCount);
|
||||||
|
|
||||||
|
@ -636,11 +639,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
PrintGpuInformation();
|
PrintGpuInformation();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool NeedsVertexBufferAlignment(int attrScalarAlignment, out int alignment)
|
internal bool NeedsVertexBufferAlignment(int attrScalarAlignment, out int alignment)
|
||||||
{
|
{
|
||||||
if (Capabilities.PortabilitySubset.HasFlag(PortabilitySubsetFlags.VertexBufferAlignment4B))
|
if (Capabilities.VertexBufferAlignment > 1)
|
||||||
{
|
{
|
||||||
alignment = 4;
|
alignment = (int)Capabilities.VertexBufferAlignment;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue