mirror of
https://git.naxdy.org/Mirror/Ryujinx.git
synced 2025-01-12 21:59:12 +00:00
Work around unsized array MoltenVK bug, disable bindless if not supported
This commit is contained in:
parent
764849b05e
commit
deb2c9a981
10 changed files with 87 additions and 27 deletions
|
@ -8,6 +8,7 @@ namespace Ryujinx.Graphics.GAL
|
||||||
public readonly string VendorName;
|
public readonly string VendorName;
|
||||||
|
|
||||||
public readonly bool HasFrontFacingBug;
|
public readonly bool HasFrontFacingBug;
|
||||||
|
public readonly bool HasUnsizedDescriptorArrayBug;
|
||||||
public readonly bool HasVectorIndexingBug;
|
public readonly bool HasVectorIndexingBug;
|
||||||
public readonly bool NeedsFragmentOutputSpecialization;
|
public readonly bool NeedsFragmentOutputSpecialization;
|
||||||
public readonly bool ReduceShaderPrecision;
|
public readonly bool ReduceShaderPrecision;
|
||||||
|
@ -24,6 +25,7 @@ namespace Ryujinx.Graphics.GAL
|
||||||
public readonly bool SupportsScaledVertexFormats;
|
public readonly bool SupportsScaledVertexFormats;
|
||||||
public readonly bool SupportsSnormBufferTextureFormat;
|
public readonly bool SupportsSnormBufferTextureFormat;
|
||||||
public readonly bool Supports5BitComponentFormat;
|
public readonly bool Supports5BitComponentFormat;
|
||||||
|
public readonly bool SupportsBindlessTextures;
|
||||||
public readonly bool SupportsBlendEquationAdvanced;
|
public readonly bool SupportsBlendEquationAdvanced;
|
||||||
public readonly bool SupportsFragmentShaderInterlock;
|
public readonly bool SupportsFragmentShaderInterlock;
|
||||||
public readonly bool SupportsFragmentShaderOrderingIntel;
|
public readonly bool SupportsFragmentShaderOrderingIntel;
|
||||||
|
@ -64,6 +66,7 @@ namespace Ryujinx.Graphics.GAL
|
||||||
TargetApi api,
|
TargetApi api,
|
||||||
string vendorName,
|
string vendorName,
|
||||||
bool hasFrontFacingBug,
|
bool hasFrontFacingBug,
|
||||||
|
bool hasUnsizedDescriptorArrayBug,
|
||||||
bool hasVectorIndexingBug,
|
bool hasVectorIndexingBug,
|
||||||
bool needsFragmentOutputSpecialization,
|
bool needsFragmentOutputSpecialization,
|
||||||
bool reduceShaderPrecision,
|
bool reduceShaderPrecision,
|
||||||
|
@ -79,6 +82,7 @@ namespace Ryujinx.Graphics.GAL
|
||||||
bool supportsScaledVertexFormats,
|
bool supportsScaledVertexFormats,
|
||||||
bool supportsSnormBufferTextureFormat,
|
bool supportsSnormBufferTextureFormat,
|
||||||
bool supports5BitComponentFormat,
|
bool supports5BitComponentFormat,
|
||||||
|
bool supportsBindlessTextures,
|
||||||
bool supportsBlendEquationAdvanced,
|
bool supportsBlendEquationAdvanced,
|
||||||
bool supportsFragmentShaderInterlock,
|
bool supportsFragmentShaderInterlock,
|
||||||
bool supportsFragmentShaderOrderingIntel,
|
bool supportsFragmentShaderOrderingIntel,
|
||||||
|
@ -115,6 +119,7 @@ namespace Ryujinx.Graphics.GAL
|
||||||
Api = api;
|
Api = api;
|
||||||
VendorName = vendorName;
|
VendorName = vendorName;
|
||||||
HasFrontFacingBug = hasFrontFacingBug;
|
HasFrontFacingBug = hasFrontFacingBug;
|
||||||
|
HasUnsizedDescriptorArrayBug = hasUnsizedDescriptorArrayBug;
|
||||||
HasVectorIndexingBug = hasVectorIndexingBug;
|
HasVectorIndexingBug = hasVectorIndexingBug;
|
||||||
NeedsFragmentOutputSpecialization = needsFragmentOutputSpecialization;
|
NeedsFragmentOutputSpecialization = needsFragmentOutputSpecialization;
|
||||||
ReduceShaderPrecision = reduceShaderPrecision;
|
ReduceShaderPrecision = reduceShaderPrecision;
|
||||||
|
@ -130,6 +135,7 @@ namespace Ryujinx.Graphics.GAL
|
||||||
SupportsScaledVertexFormats = supportsScaledVertexFormats;
|
SupportsScaledVertexFormats = supportsScaledVertexFormats;
|
||||||
SupportsSnormBufferTextureFormat = supportsSnormBufferTextureFormat;
|
SupportsSnormBufferTextureFormat = supportsSnormBufferTextureFormat;
|
||||||
Supports5BitComponentFormat = supports5BitComponentFormat;
|
Supports5BitComponentFormat = supports5BitComponentFormat;
|
||||||
|
SupportsBindlessTextures = supportsBindlessTextures;
|
||||||
SupportsBlendEquationAdvanced = supportsBlendEquationAdvanced;
|
SupportsBlendEquationAdvanced = supportsBlendEquationAdvanced;
|
||||||
SupportsFragmentShaderInterlock = supportsFragmentShaderInterlock;
|
SupportsFragmentShaderInterlock = supportsFragmentShaderInterlock;
|
||||||
SupportsFragmentShaderOrderingIntel = supportsFragmentShaderOrderingIntel;
|
SupportsFragmentShaderOrderingIntel = supportsFragmentShaderOrderingIntel;
|
||||||
|
|
|
@ -157,6 +157,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
|
|
||||||
public bool QueryHostHasFrontFacingBug() => _context.Capabilities.HasFrontFacingBug;
|
public bool QueryHostHasFrontFacingBug() => _context.Capabilities.HasFrontFacingBug;
|
||||||
|
|
||||||
|
public bool QueryHostHasUnsizedDescriptorArrayBug() => _context.Capabilities.HasUnsizedDescriptorArrayBug;
|
||||||
|
|
||||||
public bool QueryHostHasVectorIndexingBug() => _context.Capabilities.HasVectorIndexingBug;
|
public bool QueryHostHasVectorIndexingBug() => _context.Capabilities.HasVectorIndexingBug;
|
||||||
|
|
||||||
public int QueryHostStorageBufferOffsetAlignment() => _context.Capabilities.StorageBufferOffsetAlignment;
|
public int QueryHostStorageBufferOffsetAlignment() => _context.Capabilities.StorageBufferOffsetAlignment;
|
||||||
|
@ -165,6 +167,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
|
|
||||||
public bool QueryHostSupportsBgraFormat() => _context.Capabilities.SupportsBgraFormat;
|
public bool QueryHostSupportsBgraFormat() => _context.Capabilities.SupportsBgraFormat;
|
||||||
|
|
||||||
|
public bool QueryHostSupportsBindlessTextures() => _context.Capabilities.SupportsBindlessTextures;
|
||||||
|
|
||||||
public bool QueryHostSupportsFragmentShaderInterlock() => _context.Capabilities.SupportsFragmentShaderInterlock;
|
public bool QueryHostSupportsFragmentShaderInterlock() => _context.Capabilities.SupportsFragmentShaderInterlock;
|
||||||
|
|
||||||
public bool QueryHostSupportsFragmentShaderOrderingIntel() => _context.Capabilities.SupportsFragmentShaderOrderingIntel;
|
public bool QueryHostSupportsFragmentShaderOrderingIntel() => _context.Capabilities.SupportsFragmentShaderOrderingIntel;
|
||||||
|
|
|
@ -134,6 +134,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
api: TargetApi.OpenGL,
|
api: TargetApi.OpenGL,
|
||||||
vendorName: GpuVendor,
|
vendorName: GpuVendor,
|
||||||
hasFrontFacingBug: intelWindows,
|
hasFrontFacingBug: intelWindows,
|
||||||
|
hasUnsizedDescriptorArrayBug: false,
|
||||||
hasVectorIndexingBug: amdWindows,
|
hasVectorIndexingBug: amdWindows,
|
||||||
needsFragmentOutputSpecialization: false,
|
needsFragmentOutputSpecialization: false,
|
||||||
reduceShaderPrecision: false,
|
reduceShaderPrecision: false,
|
||||||
|
@ -148,6 +149,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
supportsR4G4B4A4Format: true,
|
supportsR4G4B4A4Format: true,
|
||||||
supportsSnormBufferTextureFormat: false,
|
supportsSnormBufferTextureFormat: false,
|
||||||
supports5BitComponentFormat: true,
|
supports5BitComponentFormat: true,
|
||||||
|
supportsBindlessTextures: HwCapabilities.SupportsArbBindlessTexture,
|
||||||
supportsBlendEquationAdvanced: HwCapabilities.SupportsBlendEquationAdvanced,
|
supportsBlendEquationAdvanced: HwCapabilities.SupportsBlendEquationAdvanced,
|
||||||
supportsFragmentShaderInterlock: HwCapabilities.SupportsFragmentShaderInterlock,
|
supportsFragmentShaderInterlock: HwCapabilities.SupportsFragmentShaderInterlock,
|
||||||
supportsFragmentShaderOrderingIntel: HwCapabilities.SupportsFragmentShaderOrdering,
|
supportsFragmentShaderOrderingIntel: HwCapabilities.SupportsFragmentShaderOrdering,
|
||||||
|
|
|
@ -190,7 +190,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
||||||
|
|
||||||
if (sampler.ArraySize == 0)
|
if (sampler.ArraySize == 0)
|
||||||
{
|
{
|
||||||
var sampledImageArrayType = context.TypeRuntimeArray(imageTypeForSampler);
|
var sampledImageArrayType = context.HostCapabilities.HasUnsizedDescriptorArrayBug
|
||||||
|
? context.TypeArray(imageTypeForSampler, context.Constant(context.TypeU32(), 1))
|
||||||
|
: context.TypeRuntimeArray(imageTypeForSampler);
|
||||||
sampledImageArrayPointerType = context.TypePointer(StorageClass.UniformConstant, sampledImageArrayType);
|
sampledImageArrayPointerType = context.TypePointer(StorageClass.UniformConstant, sampledImageArrayType);
|
||||||
}
|
}
|
||||||
else if (sampler.ArraySize != 1)
|
else if (sampler.ArraySize != 1)
|
||||||
|
@ -241,7 +243,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
||||||
|
|
||||||
if (image.ArraySize == 0)
|
if (image.ArraySize == 0)
|
||||||
{
|
{
|
||||||
var imageArrayType = context.TypeRuntimeArray(imageType);
|
var imageArrayType = context.HostCapabilities.HasUnsizedDescriptorArrayBug
|
||||||
|
? context.TypeArray(imageType, context.Constant(context.TypeU32(), 1))
|
||||||
|
: context.TypeRuntimeArray(imageType);
|
||||||
imageArrayPointerType = context.TypePointer(StorageClass.UniformConstant, imageArrayType);
|
imageArrayPointerType = context.TypePointer(StorageClass.UniformConstant, imageArrayType);
|
||||||
}
|
}
|
||||||
else if (image.ArraySize != 1)
|
else if (image.ArraySize != 1)
|
||||||
|
|
|
@ -195,6 +195,15 @@ namespace Ryujinx.Graphics.Shader
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Queries host about the presence of the unsized descriptor array bug.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>True if the bug is present on the host device used, false otherwise</returns>
|
||||||
|
bool QueryHostHasUnsizedDescriptorArrayBug()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Queries host about the presence of the vector indexing bug.
|
/// Queries host about the presence of the vector indexing bug.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -231,6 +240,15 @@ namespace Ryujinx.Graphics.Shader
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Queries host support for accessing bindless textures.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>True if bindless textures are supported, false otherwise</returns>
|
||||||
|
bool QueryHostSupportsBindlessTextures()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Queries host support for fragment shader ordering critical sections on the shader code.
|
/// Queries host support for fragment shader ordering critical sections on the shader code.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -3,6 +3,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
class HostCapabilities
|
class HostCapabilities
|
||||||
{
|
{
|
||||||
public readonly bool ReducedPrecision;
|
public readonly bool ReducedPrecision;
|
||||||
|
public readonly bool HasUnsizedDescriptorArrayBug;
|
||||||
public readonly bool SupportsFragmentShaderInterlock;
|
public readonly bool SupportsFragmentShaderInterlock;
|
||||||
public readonly bool SupportsFragmentShaderOrderingIntel;
|
public readonly bool SupportsFragmentShaderOrderingIntel;
|
||||||
public readonly bool SupportsGeometryShaderPassthrough;
|
public readonly bool SupportsGeometryShaderPassthrough;
|
||||||
|
@ -13,6 +14,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
|
|
||||||
public HostCapabilities(
|
public HostCapabilities(
|
||||||
bool reducedPrecision,
|
bool reducedPrecision,
|
||||||
|
bool hasUnsizedDescriptorArrayBug,
|
||||||
bool supportsFragmentShaderInterlock,
|
bool supportsFragmentShaderInterlock,
|
||||||
bool supportsFragmentShaderOrderingIntel,
|
bool supportsFragmentShaderOrderingIntel,
|
||||||
bool supportsGeometryShaderPassthrough,
|
bool supportsGeometryShaderPassthrough,
|
||||||
|
@ -22,6 +24,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
bool supportsViewportMask)
|
bool supportsViewportMask)
|
||||||
{
|
{
|
||||||
ReducedPrecision = reducedPrecision;
|
ReducedPrecision = reducedPrecision;
|
||||||
|
HasUnsizedDescriptorArrayBug = hasUnsizedDescriptorArrayBug;
|
||||||
SupportsFragmentShaderInterlock = supportsFragmentShaderInterlock;
|
SupportsFragmentShaderInterlock = supportsFragmentShaderInterlock;
|
||||||
SupportsFragmentShaderOrderingIntel = supportsFragmentShaderOrderingIntel;
|
SupportsFragmentShaderOrderingIntel = supportsFragmentShaderOrderingIntel;
|
||||||
SupportsGeometryShaderPassthrough = supportsGeometryShaderPassthrough;
|
SupportsGeometryShaderPassthrough = supportsGeometryShaderPassthrough;
|
||||||
|
|
|
@ -195,12 +195,14 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
private void AddBindlessDefinition(int set, int binding, string name, SamplerType samplerType)
|
private void AddBindlessDefinition(int set, int binding, string name, SamplerType samplerType)
|
||||||
{
|
{
|
||||||
TextureDefinition definition = new(set, binding, name, samplerType, TextureFormat.Unknown, TextureUsageFlags.None, 0);
|
TextureDefinition definition = new(set, binding, name, samplerType, TextureFormat.Unknown, TextureUsageFlags.None, 0);
|
||||||
|
|
||||||
Properties.AddOrUpdateTexture(definition, samplerType & ~(SamplerType.Separate | SamplerType.Shadow));
|
Properties.AddOrUpdateTexture(definition, samplerType & ~(SamplerType.Separate | SamplerType.Shadow));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddBindlessSeparateDefinition(int set, int binding, string name, SamplerType samplerType)
|
private void AddBindlessSeparateDefinition(int set, int binding, string name, SamplerType samplerType)
|
||||||
{
|
{
|
||||||
samplerType = (samplerType & ~SamplerType.Shadow) | SamplerType.Separate;
|
samplerType = (samplerType & ~SamplerType.Shadow) | SamplerType.Separate;
|
||||||
|
|
||||||
AddBindlessDefinition(set, binding, name, samplerType);
|
AddBindlessDefinition(set, binding, name, samplerType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,6 +214,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
binding = _gpuAccessor.QueryBindingConstantBuffer(slot);
|
binding = _gpuAccessor.QueryBindingConstantBuffer(slot);
|
||||||
_cbSlotToBindingMap[slot] = binding;
|
_cbSlotToBindingMap[slot] = binding;
|
||||||
string slotNumber = slot.ToString(CultureInfo.InvariantCulture);
|
string slotNumber = slot.ToString(CultureInfo.InvariantCulture);
|
||||||
|
|
||||||
AddNewConstantBuffer(binding, $"{_stagePrefix}_c{slotNumber}");
|
AddNewConstantBuffer(binding, $"{_stagePrefix}_c{slotNumber}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,6 +237,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
binding = _gpuAccessor.QueryBindingStorageBuffer(slot);
|
binding = _gpuAccessor.QueryBindingStorageBuffer(slot);
|
||||||
_sbSlotToBindingMap[slot] = binding;
|
_sbSlotToBindingMap[slot] = binding;
|
||||||
string slotNumber = slot.ToString(CultureInfo.InvariantCulture);
|
string slotNumber = slot.ToString(CultureInfo.InvariantCulture);
|
||||||
|
|
||||||
AddNewStorageBuffer(binding, $"{_stagePrefix}_s{slotNumber}");
|
AddNewStorageBuffer(binding, $"{_stagePrefix}_s{slotNumber}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,8 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
||||||
ref context.BindlessTextureFlags,
|
ref context.BindlessTextureFlags,
|
||||||
ref context.BindlessIndexedBuffersMask,
|
ref context.BindlessIndexedBuffersMask,
|
||||||
context.BindlessTexturesAllowed,
|
context.BindlessTexturesAllowed,
|
||||||
context.GpuAccessor.QueryTextureBufferIndex());
|
context.GpuAccessor.QueryTextureBufferIndex(),
|
||||||
|
context.GpuAccessor.QueryHostSupportsBindlessTextures());
|
||||||
|
|
||||||
if (prevNode != node)
|
if (prevNode != node)
|
||||||
{
|
{
|
||||||
|
@ -787,7 +788,8 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
||||||
ref BindlessTextureFlags bindlessTextureFlags,
|
ref BindlessTextureFlags bindlessTextureFlags,
|
||||||
ref uint bindlessIndexedBuffersMask,
|
ref uint bindlessIndexedBuffersMask,
|
||||||
bool bindlessTexturesAllowed,
|
bool bindlessTexturesAllowed,
|
||||||
int textureBufferIndex)
|
int textureBufferIndex,
|
||||||
|
bool supportsBindlessTextures)
|
||||||
{
|
{
|
||||||
if (node.Value is not TextureOperation texOp)
|
if (node.Value is not TextureOperation texOp)
|
||||||
{
|
{
|
||||||
|
@ -797,35 +799,36 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
||||||
// If it's already bindless, then we have nothing to do.
|
// If it's already bindless, then we have nothing to do.
|
||||||
if (texOp.Flags.HasFlag(TextureFlags.Bindless))
|
if (texOp.Flags.HasFlag(TextureFlags.Bindless))
|
||||||
{
|
{
|
||||||
resourceManager.EnsureBindlessBinding(targetApi, texOp.Type, texOp.Inst.IsImage());
|
if (SupportsBindlessAccess(texOp.Type, supportsBindlessTextures))
|
||||||
|
|
||||||
if (IsIndexedAccess(resourceManager, texOp, ref bindlessTextureFlags, ref bindlessIndexedBuffersMask, textureBufferIndex))
|
|
||||||
{
|
{
|
||||||
return node;
|
resourceManager.EnsureBindlessBinding(targetApi, texOp.Type, texOp.Inst.IsImage());
|
||||||
}
|
|
||||||
|
|
||||||
if (bindlessTexturesAllowed)
|
if (IsIndexedAccess(resourceManager, texOp, ref bindlessTextureFlags, ref bindlessIndexedBuffersMask, textureBufferIndex))
|
||||||
{
|
|
||||||
bindlessTextureFlags |= BindlessTextureFlags.BindlessFull;
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Set any destination operand to zero and remove the texture access.
|
|
||||||
// This is a case where bindless elimination failed, and we assume
|
|
||||||
// it's too risky to try using full bindless emulation.
|
|
||||||
|
|
||||||
for (int destIndex = 0; destIndex < texOp.DestsCount; destIndex++)
|
|
||||||
{
|
{
|
||||||
Operand dest = texOp.GetDest(destIndex);
|
return node;
|
||||||
node.List.AddBefore(node, new Operation(Instruction.Copy, dest, Const(0)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LinkedListNode<INode> prevNode = node.Previous;
|
if (bindlessTexturesAllowed)
|
||||||
node.List.Remove(node);
|
{
|
||||||
|
bindlessTextureFlags |= BindlessTextureFlags.BindlessFull;
|
||||||
return prevNode;
|
return node;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set any destination operand to zero and remove the texture access.
|
||||||
|
// This is a case where bindless elimination failed, and we assume
|
||||||
|
// it's too risky or not possible to try using full bindless emulation.
|
||||||
|
|
||||||
|
for (int destIndex = 0; destIndex < texOp.DestsCount; destIndex++)
|
||||||
|
{
|
||||||
|
Operand dest = texOp.GetDest(destIndex);
|
||||||
|
node.List.AddBefore(node, new Operation(Instruction.Copy, dest, Const(0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
LinkedListNode<INode> prevNode = node.Previous;
|
||||||
|
node.List.Remove(node);
|
||||||
|
|
||||||
|
return prevNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the index is within the host API limits, then we don't need to make it bindless.
|
// If the index is within the host API limits, then we don't need to make it bindless.
|
||||||
|
@ -866,6 +869,17 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool SupportsBindlessAccess(SamplerType type, bool supportsBindlessTextures)
|
||||||
|
{
|
||||||
|
// TODO: Support bindless buffer texture access.
|
||||||
|
if ((type & SamplerType.Mask) == SamplerType.TextureBuffer)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return supportsBindlessTextures;
|
||||||
|
}
|
||||||
|
|
||||||
private static bool IsIndexedAccess(
|
private static bool IsIndexedAccess(
|
||||||
ResourceManager resourceManager,
|
ResourceManager resourceManager,
|
||||||
TextureOperation texOp,
|
TextureOperation texOp,
|
||||||
|
|
|
@ -371,6 +371,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
|
|
||||||
var hostCapabilities = new HostCapabilities(
|
var hostCapabilities = new HostCapabilities(
|
||||||
GpuAccessor.QueryHostReducedPrecision(),
|
GpuAccessor.QueryHostReducedPrecision(),
|
||||||
|
GpuAccessor.QueryHostHasUnsizedDescriptorArrayBug(),
|
||||||
GpuAccessor.QueryHostSupportsFragmentShaderInterlock(),
|
GpuAccessor.QueryHostSupportsFragmentShaderInterlock(),
|
||||||
GpuAccessor.QueryHostSupportsFragmentShaderOrderingIntel(),
|
GpuAccessor.QueryHostSupportsFragmentShaderOrderingIntel(),
|
||||||
GpuAccessor.QueryHostSupportsGeometryShaderPassthrough(),
|
GpuAccessor.QueryHostSupportsGeometryShaderPassthrough(),
|
||||||
|
|
|
@ -572,10 +572,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
var limits = _physicalDevice.PhysicalDeviceProperties.Limits;
|
var limits = _physicalDevice.PhysicalDeviceProperties.Limits;
|
||||||
|
|
||||||
|
bool supportsDescriptorIndexing = _physicalDevice.IsDeviceExtensionPresent("VK_EXT_descriptor_indexing");
|
||||||
|
|
||||||
return new Capabilities(
|
return new Capabilities(
|
||||||
api: TargetApi.Vulkan,
|
api: TargetApi.Vulkan,
|
||||||
GpuVendor,
|
GpuVendor,
|
||||||
hasFrontFacingBug: IsIntelWindows,
|
hasFrontFacingBug: IsIntelWindows,
|
||||||
|
hasUnsizedDescriptorArrayBug: IsMoltenVk,
|
||||||
hasVectorIndexingBug: Vendor == Vendor.Qualcomm,
|
hasVectorIndexingBug: Vendor == Vendor.Qualcomm,
|
||||||
needsFragmentOutputSpecialization: IsMoltenVk,
|
needsFragmentOutputSpecialization: IsMoltenVk,
|
||||||
reduceShaderPrecision: IsMoltenVk,
|
reduceShaderPrecision: IsMoltenVk,
|
||||||
|
@ -590,6 +593,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
supportsR4G4B4A4Format: supportsR4G4B4A4Format,
|
supportsR4G4B4A4Format: supportsR4G4B4A4Format,
|
||||||
supportsSnormBufferTextureFormat: true,
|
supportsSnormBufferTextureFormat: true,
|
||||||
supports5BitComponentFormat: supports5BitComponentFormat,
|
supports5BitComponentFormat: supports5BitComponentFormat,
|
||||||
|
supportsBindlessTextures: supportsDescriptorIndexing,
|
||||||
supportsBlendEquationAdvanced: Capabilities.SupportsBlendEquationAdvanced,
|
supportsBlendEquationAdvanced: Capabilities.SupportsBlendEquationAdvanced,
|
||||||
supportsFragmentShaderInterlock: Capabilities.SupportsFragmentShaderInterlock,
|
supportsFragmentShaderInterlock: Capabilities.SupportsFragmentShaderInterlock,
|
||||||
supportsFragmentShaderOrderingIntel: false,
|
supportsFragmentShaderOrderingIntel: false,
|
||||||
|
|
Loading…
Reference in a new issue