Workaround for Intel FrontFacing built-in variable bug (#2540)
This commit is contained in:
parent
0a80a837cb
commit
c3e2646f9e
13 changed files with 161 additions and 113 deletions
|
@ -2,6 +2,9 @@ namespace Ryujinx.Graphics.GAL
|
||||||
{
|
{
|
||||||
public struct Capabilities
|
public struct Capabilities
|
||||||
{
|
{
|
||||||
|
public bool HasFrontFacingBug { get; }
|
||||||
|
public bool HasVectorIndexingBug { get; }
|
||||||
|
|
||||||
public bool SupportsAstcCompression { get; }
|
public bool SupportsAstcCompression { get; }
|
||||||
public bool SupportsImageLoadFormatted { get; }
|
public bool SupportsImageLoadFormatted { get; }
|
||||||
public bool SupportsMismatchingViewFormat { get; }
|
public bool SupportsMismatchingViewFormat { get; }
|
||||||
|
@ -14,6 +17,8 @@ namespace Ryujinx.Graphics.GAL
|
||||||
public int StorageBufferOffsetAlignment { get; }
|
public int StorageBufferOffsetAlignment { get; }
|
||||||
|
|
||||||
public Capabilities(
|
public Capabilities(
|
||||||
|
bool hasFrontFacingBug,
|
||||||
|
bool hasVectorIndexingBug,
|
||||||
bool supportsAstcCompression,
|
bool supportsAstcCompression,
|
||||||
bool supportsImageLoadFormatted,
|
bool supportsImageLoadFormatted,
|
||||||
bool supportsMismatchingViewFormat,
|
bool supportsMismatchingViewFormat,
|
||||||
|
@ -24,6 +29,8 @@ namespace Ryujinx.Graphics.GAL
|
||||||
float maximumSupportedAnisotropy,
|
float maximumSupportedAnisotropy,
|
||||||
int storageBufferOffsetAlignment)
|
int storageBufferOffsetAlignment)
|
||||||
{
|
{
|
||||||
|
HasFrontFacingBug = hasFrontFacingBug;
|
||||||
|
HasVectorIndexingBug = hasVectorIndexingBug;
|
||||||
SupportsAstcCompression = supportsAstcCompression;
|
SupportsAstcCompression = supportsAstcCompression;
|
||||||
SupportsImageLoadFormatted = supportsImageLoadFormatted;
|
SupportsImageLoadFormatted = supportsImageLoadFormatted;
|
||||||
SupportsMismatchingViewFormat = supportsMismatchingViewFormat;
|
SupportsMismatchingViewFormat = supportsMismatchingViewFormat;
|
||||||
|
|
|
@ -9,7 +9,6 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
{
|
{
|
||||||
class CachedGpuAccessor : TextureDescriptorCapableGpuAccessor, IGpuAccessor
|
class CachedGpuAccessor : TextureDescriptorCapableGpuAccessor, IGpuAccessor
|
||||||
{
|
{
|
||||||
private readonly GpuContext _context;
|
|
||||||
private readonly ReadOnlyMemory<byte> _data;
|
private readonly ReadOnlyMemory<byte> _data;
|
||||||
private readonly ReadOnlyMemory<byte> _cb1Data;
|
private readonly ReadOnlyMemory<byte> _cb1Data;
|
||||||
private readonly GuestGpuAccessorHeader _header;
|
private readonly GuestGpuAccessorHeader _header;
|
||||||
|
@ -28,9 +27,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
ReadOnlyMemory<byte> data,
|
ReadOnlyMemory<byte> data,
|
||||||
ReadOnlyMemory<byte> cb1Data,
|
ReadOnlyMemory<byte> cb1Data,
|
||||||
GuestGpuAccessorHeader header,
|
GuestGpuAccessorHeader header,
|
||||||
Dictionary<int, GuestTextureDescriptor> guestTextureDescriptors)
|
IReadOnlyDictionary<int, GuestTextureDescriptor> guestTextureDescriptors) : base(context)
|
||||||
{
|
{
|
||||||
_context = context;
|
|
||||||
_data = data;
|
_data = data;
|
||||||
_cb1Data = cb1Data;
|
_cb1Data = cb1Data;
|
||||||
_header = header;
|
_header = header;
|
||||||
|
@ -136,24 +134,6 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
return _header.PrimitiveTopology;
|
return _header.PrimitiveTopology;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Queries host storage buffer alignment required.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>Host storage buffer alignment in bytes</returns>
|
|
||||||
public int QueryStorageBufferOffsetAlignment() => _context.Capabilities.StorageBufferOffsetAlignment;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Queries host support for readable images without a explicit format declaration on the shader.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>True if formatted image load is supported, false otherwise</returns>
|
|
||||||
public bool QuerySupportsImageLoadFormatted() => _context.Capabilities.SupportsImageLoadFormatted;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Queries host GPU non-constant texture offset support.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>True if the GPU and driver supports non-constant texture offsets, false otherwise</returns>
|
|
||||||
public bool QuerySupportsNonConstantTextureOffset() => _context.Capabilities.SupportsNonConstantTextureOffset;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the texture descriptor for a given texture on the pool.
|
/// Gets the texture descriptor for a given texture on the pool.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -7,9 +7,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a GPU state and memory accessor.
|
/// Represents a GPU state and memory accessor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
class GpuAccessor : TextureDescriptorCapableGpuAccessor, IGpuAccessor
|
class GpuAccessor : TextureDescriptorCapableGpuAccessor
|
||||||
{
|
{
|
||||||
private readonly GpuContext _context;
|
|
||||||
private readonly GpuChannel _channel;
|
private readonly GpuChannel _channel;
|
||||||
private readonly GpuAccessorState _state;
|
private readonly GpuAccessorState _state;
|
||||||
private readonly int _stageIndex;
|
private readonly int _stageIndex;
|
||||||
|
@ -29,9 +28,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
/// <param name="channel">GPU channel</param>
|
/// <param name="channel">GPU channel</param>
|
||||||
/// <param name="state">Current GPU state</param>
|
/// <param name="state">Current GPU state</param>
|
||||||
/// <param name="stageIndex">Graphics shader stage index (0 = Vertex, 4 = Fragment)</param>
|
/// <param name="stageIndex">Graphics shader stage index (0 = Vertex, 4 = Fragment)</param>
|
||||||
public GpuAccessor(GpuContext context, GpuChannel channel, GpuAccessorState state, int stageIndex)
|
public GpuAccessor(GpuContext context, GpuChannel channel, GpuAccessorState state, int stageIndex) : base(context)
|
||||||
{
|
{
|
||||||
_context = context;
|
|
||||||
_channel = channel;
|
_channel = channel;
|
||||||
_state = state;
|
_state = state;
|
||||||
_stageIndex = stageIndex;
|
_stageIndex = stageIndex;
|
||||||
|
@ -56,9 +54,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
int localSizeY,
|
int localSizeY,
|
||||||
int localSizeZ,
|
int localSizeZ,
|
||||||
int localMemorySize,
|
int localMemorySize,
|
||||||
int sharedMemorySize)
|
int sharedMemorySize) : base(context)
|
||||||
{
|
{
|
||||||
_context = context;
|
|
||||||
_channel = channel;
|
_channel = channel;
|
||||||
_state = state;
|
_state = state;
|
||||||
_compute = true;
|
_compute = true;
|
||||||
|
@ -182,30 +179,6 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Queries host storage buffer alignment required.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>Host storage buffer alignment in bytes</returns>
|
|
||||||
public int QueryStorageBufferOffsetAlignment() => _context.Capabilities.StorageBufferOffsetAlignment;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Queries host support for readable images without a explicit format declaration on the shader.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>True if formatted image load is supported, false otherwise</returns>
|
|
||||||
public bool QuerySupportsImageLoadFormatted() => _context.Capabilities.SupportsImageLoadFormatted;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Queries host GPU non-constant texture offset support.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>True if the GPU and driver supports non-constant texture offsets, false otherwise</returns>
|
|
||||||
public bool QuerySupportsNonConstantTextureOffset() => _context.Capabilities.SupportsNonConstantTextureOffset;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Queries host GPU texture shadow LOD support.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>True if the GPU and driver supports texture shadow LOD, false otherwise</returns>
|
|
||||||
public bool QuerySupportsTextureShadowLod() => _context.Capabilities.SupportsTextureShadowLod;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the texture descriptor for a given texture on the pool.
|
/// Gets the texture descriptor for a given texture on the pool.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
55
Ryujinx.Graphics.Gpu/Shader/GpuAccessorBase.cs
Normal file
55
Ryujinx.Graphics.Gpu/Shader/GpuAccessorBase.cs
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a GPU state and memory accessor.
|
||||||
|
/// </summary>
|
||||||
|
class GpuAccessorBase
|
||||||
|
{
|
||||||
|
private readonly GpuContext _context;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the GPU state accessor.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="context">GPU context</param>
|
||||||
|
public GpuAccessorBase(GpuContext context)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Queries host about the presence of the FrontFacing built-in variable bug.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>True if the bug is present on the host device used, false otherwise</returns>
|
||||||
|
public bool QueryHostHasFrontFacingBug() => _context.Capabilities.HasFrontFacingBug;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Queries host about the presence of the vector indexing bug.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>True if the bug is present on the host device used, false otherwise</returns>
|
||||||
|
public bool QueryHostHasVectorIndexingBug() => _context.Capabilities.HasVectorIndexingBug;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Queries host storage buffer alignment required.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Host storage buffer alignment in bytes</returns>
|
||||||
|
public int QueryHostStorageBufferOffsetAlignment() => _context.Capabilities.StorageBufferOffsetAlignment;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Queries host support for readable images without a explicit format declaration on the shader.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>True if formatted image load is supported, false otherwise</returns>
|
||||||
|
public bool QueryHostSupportsImageLoadFormatted() => _context.Capabilities.SupportsImageLoadFormatted;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Queries host GPU non-constant texture offset support.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>True if the GPU and driver supports non-constant texture offsets, false otherwise</returns>
|
||||||
|
public bool QueryHostSupportsNonConstantTextureOffset() => _context.Capabilities.SupportsNonConstantTextureOffset;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Queries host GPU texture shadow LOD support.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>True if the GPU and driver supports texture shadow LOD, false otherwise</returns>
|
||||||
|
public bool QueryHostSupportsTextureShadowLod() => _context.Capabilities.SupportsTextureShadowLod;
|
||||||
|
}
|
||||||
|
}
|
|
@ -38,7 +38,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Version of the codegen (to be changed when codegen or guest format change).
|
/// Version of the codegen (to be changed when codegen or guest format change).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private const ulong ShaderCodeGenVersion = 2538;
|
private const ulong ShaderCodeGenVersion = 2540;
|
||||||
|
|
||||||
// Progress reporting helpers
|
// Progress reporting helpers
|
||||||
private volatile int _shaderCount;
|
private volatile int _shaderCount;
|
||||||
|
|
|
@ -4,8 +4,12 @@ using Ryujinx.Graphics.Shader;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Gpu.Shader
|
namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
{
|
{
|
||||||
abstract class TextureDescriptorCapableGpuAccessor : IGpuAccessor
|
abstract class TextureDescriptorCapableGpuAccessor : GpuAccessorBase, IGpuAccessor
|
||||||
{
|
{
|
||||||
|
public TextureDescriptorCapableGpuAccessor(GpuContext context) : base(context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public abstract T MemoryRead<T>(ulong address) where T : unmanaged;
|
public abstract T MemoryRead<T>(ulong address) where T : unmanaged;
|
||||||
|
|
||||||
public abstract ITextureDescriptor GetTextureDescriptor(int handle, int cbufSlot);
|
public abstract ITextureDescriptor GetTextureDescriptor(int handle, int cbufSlot);
|
||||||
|
|
|
@ -99,6 +99,8 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
public Capabilities GetCapabilities()
|
public Capabilities GetCapabilities()
|
||||||
{
|
{
|
||||||
return new Capabilities(
|
return new Capabilities(
|
||||||
|
HwCapabilities.Vendor == HwCapabilities.GpuVendor.IntelWindows,
|
||||||
|
HwCapabilities.Vendor == HwCapabilities.GpuVendor.AmdWindows,
|
||||||
HwCapabilities.SupportsAstcCompression,
|
HwCapabilities.SupportsAstcCompression,
|
||||||
HwCapabilities.SupportsImageLoadFormatted,
|
HwCapabilities.SupportsImageLoadFormatted,
|
||||||
HwCapabilities.SupportsMismatchingViewFormat,
|
HwCapabilities.SupportsMismatchingViewFormat,
|
||||||
|
|
|
@ -157,15 +157,18 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
||||||
|
|
||||||
offsetExpr = Enclose(offsetExpr, src2, Instruction.ShiftRightS32, isLhs: true);
|
offsetExpr = Enclose(offsetExpr, src2, Instruction.ShiftRightS32, isLhs: true);
|
||||||
|
|
||||||
|
var config = context.Config;
|
||||||
|
bool indexElement = !config.GpuAccessor.QueryHostHasVectorIndexingBug();
|
||||||
|
|
||||||
if (src1 is AstOperand oper && oper.Type == OperandType.Constant)
|
if (src1 is AstOperand oper && oper.Type == OperandType.Constant)
|
||||||
{
|
{
|
||||||
bool cbIndexable = context.Config.UsedFeatures.HasFlag(Translation.FeatureFlags.CbIndexing);
|
bool cbIndexable = config.UsedFeatures.HasFlag(Translation.FeatureFlags.CbIndexing);
|
||||||
return OperandManager.GetConstantBufferName(oper.Value, offsetExpr, context.Config.Stage, cbIndexable);
|
return OperandManager.GetConstantBufferName(oper.Value, offsetExpr, config.Stage, cbIndexable, indexElement);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string slotExpr = GetSoureExpr(context, src1, GetSrcVarType(operation.Inst, 0));
|
string slotExpr = GetSoureExpr(context, src1, GetSrcVarType(operation.Inst, 0));
|
||||||
return OperandManager.GetConstantBufferName(slotExpr, offsetExpr, context.Config.Stage);
|
return OperandManager.GetConstantBufferName(slotExpr, offsetExpr, config.Stage, indexElement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,7 +317,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
||||||
|
|
||||||
// 2D Array and Cube shadow samplers with LOD level or bias requires an extension.
|
// 2D Array and Cube shadow samplers with LOD level or bias requires an extension.
|
||||||
// If the extension is not supported, just remove the LOD parameter.
|
// If the extension is not supported, just remove the LOD parameter.
|
||||||
if (isArray && isShadow && (is2D || isCube) && !context.Config.GpuAccessor.QuerySupportsTextureShadowLod())
|
if (isArray && isShadow && (is2D || isCube) && !context.Config.GpuAccessor.QueryHostSupportsTextureShadowLod())
|
||||||
{
|
{
|
||||||
hasLodBias = false;
|
hasLodBias = false;
|
||||||
hasLodLevel = false;
|
hasLodLevel = false;
|
||||||
|
@ -322,7 +325,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
||||||
|
|
||||||
// Cube shadow samplers with LOD level requires an extension.
|
// Cube shadow samplers with LOD level requires an extension.
|
||||||
// If the extension is not supported, just remove the LOD level parameter.
|
// If the extension is not supported, just remove the LOD level parameter.
|
||||||
if (isShadow && isCube && !context.Config.GpuAccessor.QuerySupportsTextureShadowLod())
|
if (isShadow && isCube && !context.Config.GpuAccessor.QueryHostSupportsTextureShadowLod())
|
||||||
{
|
{
|
||||||
hasLodLevel = false;
|
hasLodLevel = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,8 +117,13 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
||||||
return $"{GetUbName(stage, slot, cbIndexable)}[{offset >> 2}].{GetSwizzleMask(offset & 3)}";
|
return $"{GetUbName(stage, slot, cbIndexable)}[{offset >> 2}].{GetSwizzleMask(offset & 3)}";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetVec4Indexed(string vectorName, string indexExpr)
|
private static string GetVec4Indexed(string vectorName, string indexExpr, bool indexElement)
|
||||||
{
|
{
|
||||||
|
if (indexElement)
|
||||||
|
{
|
||||||
|
return $"{vectorName}[{indexExpr}]";
|
||||||
|
}
|
||||||
|
|
||||||
string result = $"{vectorName}.x";
|
string result = $"{vectorName}.x";
|
||||||
for (int i = 1; i < 4; i++)
|
for (int i = 1; i < 4; i++)
|
||||||
{
|
{
|
||||||
|
@ -127,14 +132,14 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
||||||
return $"({result})";
|
return $"({result})";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetConstantBufferName(int slot, string offsetExpr, ShaderStage stage, bool cbIndexable)
|
public static string GetConstantBufferName(int slot, string offsetExpr, ShaderStage stage, bool cbIndexable, bool indexElement)
|
||||||
{
|
{
|
||||||
return GetVec4Indexed(GetUbName(stage, slot, cbIndexable) + $"[{offsetExpr} >> 2]", offsetExpr + " & 3");
|
return GetVec4Indexed(GetUbName(stage, slot, cbIndexable) + $"[{offsetExpr} >> 2]", offsetExpr + " & 3", indexElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetConstantBufferName(string slotExpr, string offsetExpr, ShaderStage stage)
|
public static string GetConstantBufferName(string slotExpr, string offsetExpr, ShaderStage stage, bool indexElement)
|
||||||
{
|
{
|
||||||
return GetVec4Indexed(GetUbName(stage, slotExpr) + $"[{offsetExpr} >> 2]", offsetExpr + " & 3");
|
return GetVec4Indexed(GetUbName(stage, slotExpr) + $"[{offsetExpr} >> 2]", offsetExpr + " & 3", indexElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetOutAttributeName(AstOperand attr, ShaderConfig config)
|
public static string GetOutAttributeName(AstOperand attr, ShaderConfig config)
|
||||||
|
@ -198,6 +203,15 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
||||||
case AttributeConsts.PositionY: return $"(gl_FragCoord.y / {DefaultNames.SupportBlockRenderScaleName}[0])";
|
case AttributeConsts.PositionY: return $"(gl_FragCoord.y / {DefaultNames.SupportBlockRenderScaleName}[0])";
|
||||||
case AttributeConsts.PositionZ: return "gl_FragCoord.z";
|
case AttributeConsts.PositionZ: return "gl_FragCoord.z";
|
||||||
case AttributeConsts.PositionW: return "gl_FragCoord.w";
|
case AttributeConsts.PositionW: return "gl_FragCoord.w";
|
||||||
|
|
||||||
|
case AttributeConsts.FrontFacing:
|
||||||
|
if (config.GpuAccessor.QueryHostHasFrontFacingBug())
|
||||||
|
{
|
||||||
|
// This is required for Intel on Windows, gl_FrontFacing sometimes returns incorrect
|
||||||
|
// (flipped) values. Doing this seems to fix it.
|
||||||
|
return "(-floatBitsToInt(float(gl_FrontFacing)) < 0)";
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,36 @@
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QueryHostHasFrontFacingBug()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QueryHostHasVectorIndexingBug()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int QueryHostStorageBufferOffsetAlignment()
|
||||||
|
{
|
||||||
|
return 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QueryHostSupportsImageLoadFormatted()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QueryHostSupportsNonConstantTextureOffset()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QueryHostSupportsTextureShadowLod()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool QueryIsTextureBuffer(int handle, int cbufSlot = -1)
|
bool QueryIsTextureBuffer(int handle, int cbufSlot = -1)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -64,26 +94,6 @@
|
||||||
return InputTopology.Points;
|
return InputTopology.Points;
|
||||||
}
|
}
|
||||||
|
|
||||||
int QueryStorageBufferOffsetAlignment()
|
|
||||||
{
|
|
||||||
return 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QuerySupportsImageLoadFormatted()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QuerySupportsNonConstantTextureOffset()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QuerySupportsTextureShadowLod()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
TextureFormat QueryTextureFormat(int handle, int cbufSlot = -1)
|
TextureFormat QueryTextureFormat(int handle, int cbufSlot = -1)
|
||||||
{
|
{
|
||||||
return TextureFormat.R8G8B8A8Unorm;
|
return TextureFormat.R8G8B8A8Unorm;
|
||||||
|
|
|
@ -71,7 +71,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
||||||
|
|
||||||
Operand baseAddrTrunc = Local();
|
Operand baseAddrTrunc = Local();
|
||||||
|
|
||||||
Operand alignMask = Const(-config.GpuAccessor.QueryStorageBufferOffsetAlignment());
|
Operand alignMask = Const(-config.GpuAccessor.QueryHostStorageBufferOffsetAlignment());
|
||||||
|
|
||||||
Operation andOp = new Operation(Instruction.BitwiseAnd, baseAddrTrunc, baseAddrLow, alignMask);
|
Operation andOp = new Operation(Instruction.BitwiseAnd, baseAddrTrunc, baseAddrLow, alignMask);
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
||||||
|
|
||||||
Operand baseAddrTrunc = Local();
|
Operand baseAddrTrunc = Local();
|
||||||
|
|
||||||
Operand alignMask = Const(-config.GpuAccessor.QueryStorageBufferOffsetAlignment());
|
Operand alignMask = Const(-config.GpuAccessor.QueryHostStorageBufferOffsetAlignment());
|
||||||
|
|
||||||
Operation andOp = new Operation(Instruction.BitwiseAnd, baseAddrTrunc, baseAddrLow, alignMask);
|
Operation andOp = new Operation(Instruction.BitwiseAnd, baseAddrTrunc, baseAddrLow, alignMask);
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
sbSlot = PrependOperation(Instruction.ConditionalSelect, inRange, Const(slot), sbSlot);
|
sbSlot = PrependOperation(Instruction.ConditionalSelect, inRange, Const(slot), sbSlot);
|
||||||
}
|
}
|
||||||
|
|
||||||
Operand alignMask = Const(-config.GpuAccessor.QueryStorageBufferOffsetAlignment());
|
Operand alignMask = Const(-config.GpuAccessor.QueryHostStorageBufferOffsetAlignment());
|
||||||
|
|
||||||
Operand baseAddrTrunc = PrependOperation(Instruction.BitwiseAnd, sbBaseAddrLow, alignMask);
|
Operand baseAddrTrunc = PrependOperation(Instruction.BitwiseAnd, sbBaseAddrLow, alignMask);
|
||||||
Operand byteOffset = PrependOperation(Instruction.Subtract, addrLow, baseAddrTrunc);
|
Operand byteOffset = PrependOperation(Instruction.Subtract, addrLow, baseAddrTrunc);
|
||||||
|
@ -145,7 +145,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
bool hasOffset = (texOp.Flags & TextureFlags.Offset) != 0;
|
bool hasOffset = (texOp.Flags & TextureFlags.Offset) != 0;
|
||||||
bool hasOffsets = (texOp.Flags & TextureFlags.Offsets) != 0;
|
bool hasOffsets = (texOp.Flags & TextureFlags.Offsets) != 0;
|
||||||
|
|
||||||
bool hasInvalidOffset = (hasOffset || hasOffsets) && !config.GpuAccessor.QuerySupportsNonConstantTextureOffset();
|
bool hasInvalidOffset = (hasOffset || hasOffsets) && !config.GpuAccessor.QueryHostSupportsNonConstantTextureOffset();
|
||||||
|
|
||||||
bool isBindless = (texOp.Flags & TextureFlags.Bindless) != 0;
|
bool isBindless = (texOp.Flags & TextureFlags.Bindless) != 0;
|
||||||
|
|
||||||
|
|
|
@ -145,7 +145,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
{
|
{
|
||||||
// When the formatted load extension is supported, we don't need to
|
// When the formatted load extension is supported, we don't need to
|
||||||
// specify a format, we can just declare it without a format and the GPU will handle it.
|
// specify a format, we can just declare it without a format and the GPU will handle it.
|
||||||
if (GpuAccessor.QuerySupportsImageLoadFormatted())
|
if (GpuAccessor.QueryHostSupportsImageLoadFormatted())
|
||||||
{
|
{
|
||||||
return TextureFormat.Unknown;
|
return TextureFormat.Unknown;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue