forked from Mirror/Ryujinx
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,
|
||||
|
||||
VertexBufferAlignment4B = 1,
|
||||
NoTriangleFans = 1 << 1,
|
||||
NoPointMode = 1 << 2,
|
||||
No3DImageView = 1 << 3,
|
||||
NoLodBias = 1 << 4
|
||||
NoTriangleFans = 1,
|
||||
NoPointMode = 1 << 1,
|
||||
No3DImageView = 1 << 2,
|
||||
NoLodBias = 1 << 3
|
||||
}
|
||||
|
||||
readonly struct HardwareCapabilities
|
||||
|
@ -40,6 +39,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
public readonly ShaderStageFlags RequiredSubgroupSizeStages;
|
||||
public readonly SampleCountFlags SupportedSampleCounts;
|
||||
public readonly PortabilitySubsetFlags PortabilitySubset;
|
||||
public readonly uint VertexBufferAlignment;
|
||||
|
||||
public HardwareCapabilities(
|
||||
bool supportsIndexTypeUint8,
|
||||
|
@ -64,7 +64,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
uint maxSubgroupSize,
|
||||
ShaderStageFlags requiredSubgroupSizeStages,
|
||||
SampleCountFlags supportedSampleCounts,
|
||||
PortabilitySubsetFlags portabilitySubset)
|
||||
PortabilitySubsetFlags portabilitySubset,
|
||||
uint vertexBufferAlignment)
|
||||
{
|
||||
SupportsIndexTypeUint8 = supportsIndexTypeUint8;
|
||||
SupportsCustomBorderColor = supportsCustomBorderColor;
|
||||
|
@ -89,6 +90,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
RequiredSubgroupSizeStages = requiredSubgroupSizeStages;
|
||||
SupportedSampleCounts = supportedSampleCounts;
|
||||
PortabilitySubset = portabilitySubset;
|
||||
VertexBufferAlignment = vertexBufferAlignment;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.Shader;
|
||||
using Silk.NET.Vulkan;
|
||||
using System;
|
||||
|
@ -1136,7 +1137,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
|
||||
buffer.Dispose();
|
||||
|
||||
if (!Gd.Capabilities.PortabilitySubset.HasFlag(PortabilitySubsetFlags.VertexBufferAlignment4B) &&
|
||||
if (Gd.Capabilities.VertexBufferAlignment < 2 &&
|
||||
(vertexBuffer.Stride % FormatExtensions.MaxBufferFormatScalarSize) == 0)
|
||||
{
|
||||
buffer = new VertexBufferState(
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.Vulkan;
|
||||
using System;
|
||||
|
||||
|
@ -253,7 +254,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
|
||||
if (gd.NeedsVertexBufferAlignment(vbScalarSizes[i], out int alignment))
|
||||
{
|
||||
alignedStride = (vertexBuffer.Stride + (alignment - 1)) & -alignment;
|
||||
alignedStride = BitUtils.AlignUp(vertexBuffer.Stride, alignment);
|
||||
}
|
||||
|
||||
// TODO: Support divisor > 1
|
||||
|
|
|
@ -36,7 +36,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
"VK_KHR_shader_float16_int8",
|
||||
"VK_EXT_shader_subgroup_ballot",
|
||||
"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[]
|
||||
|
|
|
@ -234,10 +234,12 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
Api.GetPhysicalDeviceFeatures2(_physicalDevice, &features2);
|
||||
|
||||
var portabilityFlags = PortabilitySubsetFlags.None;
|
||||
uint vertexBufferAlignment = 1;
|
||||
|
||||
if (usePortability)
|
||||
{
|
||||
portabilityFlags |= propertiesPortabilitySubset.MinVertexInputBindingStrideAlignment > 1 ? PortabilitySubsetFlags.VertexBufferAlignment4B : 0;
|
||||
vertexBufferAlignment = propertiesPortabilitySubset.MinVertexInputBindingStrideAlignment;
|
||||
|
||||
portabilityFlags |= featuresPortabilitySubset.TriangleFans ? 0 : PortabilitySubsetFlags.NoTriangleFans;
|
||||
portabilityFlags |= featuresPortabilitySubset.PointPolygons ? 0 : PortabilitySubsetFlags.NoPointMode;
|
||||
portabilityFlags |= featuresPortabilitySubset.ImageView2DOn3DImage ? 0 : PortabilitySubsetFlags.No3DImageView;
|
||||
|
@ -278,7 +280,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
propertiesSubgroupSizeControl.MaxSubgroupSize,
|
||||
propertiesSubgroupSizeControl.RequiredSubgroupSizeStages,
|
||||
supportedSampleCounts,
|
||||
portabilityFlags);
|
||||
portabilityFlags,
|
||||
vertexBufferAlignment);
|
||||
|
||||
MemoryAllocator = new MemoryAllocator(Api, _physicalDevice, _device, properties.Limits.MaxMemoryAllocationCount);
|
||||
|
||||
|
@ -636,11 +639,11 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
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;
|
||||
}
|
||||
|
|
Reference in a new issue