forked from Mirror/Ryujinx
Only enable clip distance if written to on shader (#2217)
* Only enable clip distance if written to on shader * Signal InstanceId use through FeatureFlags * Shader cache version bump
This commit is contained in:
parent
89791ba68d
commit
4770cfa920
12 changed files with 79 additions and 23 deletions
|
@ -39,6 +39,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
|
|
||||||
private bool _isAnyVbInstanced;
|
private bool _isAnyVbInstanced;
|
||||||
private bool _vsUsesInstanceId;
|
private bool _vsUsesInstanceId;
|
||||||
|
private byte _vsClipDistancesWritten;
|
||||||
|
|
||||||
private bool _forceShaderUpdate;
|
private bool _forceShaderUpdate;
|
||||||
|
|
||||||
|
@ -993,7 +994,15 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
|
|
||||||
ShaderBundle gs = ShaderCache.GetGraphicsShader(state, addresses);
|
ShaderBundle gs = ShaderCache.GetGraphicsShader(state, addresses);
|
||||||
|
|
||||||
_vsUsesInstanceId = gs.Shaders[0]?.Info.UsesInstanceId ?? false;
|
byte oldVsClipDistancesWritten = _vsClipDistancesWritten;
|
||||||
|
|
||||||
|
_vsUsesInstanceId = gs.Shaders[0]?.Info.UsesInstanceId ?? false;
|
||||||
|
_vsClipDistancesWritten = gs.Shaders[0]?.Info.ClipDistancesWritten ?? 0;
|
||||||
|
|
||||||
|
if (oldVsClipDistancesWritten != _vsClipDistancesWritten)
|
||||||
|
{
|
||||||
|
UpdateUserClipState(state);
|
||||||
|
}
|
||||||
|
|
||||||
int storageBufferBindingsCount = 0;
|
int storageBufferBindingsCount = 0;
|
||||||
int uniformBufferBindingsCount = 0;
|
int uniformBufferBindingsCount = 0;
|
||||||
|
@ -1098,7 +1107,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
/// <param name="state">Current GPU state</param>
|
/// <param name="state">Current GPU state</param>
|
||||||
private void UpdateUserClipState(GpuState state)
|
private void UpdateUserClipState(GpuState state)
|
||||||
{
|
{
|
||||||
int clipMask = state.Get<int>(MethodOffset.ClipDistanceEnable);
|
int clipMask = state.Get<int>(MethodOffset.ClipDistanceEnable) & _vsClipDistancesWritten;
|
||||||
|
|
||||||
for (int i = 0; i < Constants.TotalClipDistances; ++i)
|
for (int i = 0; i < Constants.TotalClipDistances; ++i)
|
||||||
{
|
{
|
||||||
|
|
|
@ -75,7 +75,8 @@ namespace Ryujinx.Graphics.Gpu.Shader.Cache.Definition
|
||||||
programInfo.SBuffers.Count,
|
programInfo.SBuffers.Count,
|
||||||
programInfo.Textures.Count,
|
programInfo.Textures.Count,
|
||||||
programInfo.Images.Count,
|
programInfo.Images.Count,
|
||||||
programInfo.UsesInstanceId);
|
programInfo.UsesInstanceId,
|
||||||
|
programInfo.ClipDistancesWritten);
|
||||||
CBuffers = programInfo.CBuffers.ToArray();
|
CBuffers = programInfo.CBuffers.ToArray();
|
||||||
SBuffers = programInfo.SBuffers.ToArray();
|
SBuffers = programInfo.SBuffers.ToArray();
|
||||||
Textures = programInfo.Textures.ToArray();
|
Textures = programInfo.Textures.ToArray();
|
||||||
|
@ -88,7 +89,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.Cache.Definition
|
||||||
/// <returns>A new <see cref="ShaderProgramInfo"/> from this instance</returns>
|
/// <returns>A new <see cref="ShaderProgramInfo"/> from this instance</returns>
|
||||||
internal ShaderProgramInfo ToShaderProgramInfo()
|
internal ShaderProgramInfo ToShaderProgramInfo()
|
||||||
{
|
{
|
||||||
return new ShaderProgramInfo(CBuffers, SBuffers, Textures, Images, Header.UsesInstanceId);
|
return new ShaderProgramInfo(CBuffers, SBuffers, Textures, Images, Header.UsesInstanceId, Header.ClipDistancesWritten);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -41,10 +41,15 @@ namespace Ryujinx.Graphics.Gpu.Shader.Cache.Definition
|
||||||
[MarshalAs(UnmanagedType.I1)]
|
[MarshalAs(UnmanagedType.I1)]
|
||||||
public bool InUse;
|
public bool InUse;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Mask of clip distances that are written to on the shader.
|
||||||
|
/// </summary>
|
||||||
|
public byte ClipDistancesWritten;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reserved / unused.
|
/// Reserved / unused.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public short Reserved;
|
public byte Reserved;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new host shader cache entry header.
|
/// Create a new host shader cache entry header.
|
||||||
|
@ -54,14 +59,21 @@ namespace Ryujinx.Graphics.Gpu.Shader.Cache.Definition
|
||||||
/// <param name="texturesCount">Count of texture descriptors</param>
|
/// <param name="texturesCount">Count of texture descriptors</param>
|
||||||
/// <param name="imagesCount">Count of image descriptors</param>
|
/// <param name="imagesCount">Count of image descriptors</param>
|
||||||
/// <param name="usesInstanceId">Set to true if the shader uses instance id</param>
|
/// <param name="usesInstanceId">Set to true if the shader uses instance id</param>
|
||||||
public HostShaderCacheEntryHeader(int cBuffersCount, int sBuffersCount, int texturesCount, int imagesCount, bool usesInstanceId) : this()
|
public HostShaderCacheEntryHeader(
|
||||||
|
int cBuffersCount,
|
||||||
|
int sBuffersCount,
|
||||||
|
int texturesCount,
|
||||||
|
int imagesCount,
|
||||||
|
bool usesInstanceId,
|
||||||
|
byte clipDistancesWritten) : this()
|
||||||
{
|
{
|
||||||
CBuffersCount = cBuffersCount;
|
CBuffersCount = cBuffersCount;
|
||||||
SBuffersCount = sBuffersCount;
|
SBuffersCount = sBuffersCount;
|
||||||
TexturesCount = texturesCount;
|
TexturesCount = texturesCount;
|
||||||
ImagesCount = imagesCount;
|
ImagesCount = imagesCount;
|
||||||
UsesInstanceId = usesInstanceId;
|
UsesInstanceId = usesInstanceId;
|
||||||
InUse = true;
|
ClipDistancesWritten = clipDistancesWritten;
|
||||||
|
InUse = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,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 = 2200;
|
private const ulong ShaderCodeGenVersion = 2217;
|
||||||
|
|
||||||
// Progress reporting helpers
|
// Progress reporting helpers
|
||||||
private volatile int _shaderCount;
|
private volatile int _shaderCount;
|
||||||
|
|
|
@ -53,6 +53,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||||
|
|
||||||
Operand dest = Attribute(op.AttributeOffset + index * 4);
|
Operand dest = Attribute(op.AttributeOffset + index * 4);
|
||||||
|
|
||||||
|
context.FlagAttributeWritten(dest.Value);
|
||||||
|
|
||||||
context.Copy(dest, Register(rd));
|
context.Copy(dest, Register(rd));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,13 +11,15 @@ namespace Ryujinx.Graphics.Shader
|
||||||
public ReadOnlyCollection<TextureDescriptor> Images { get; }
|
public ReadOnlyCollection<TextureDescriptor> Images { get; }
|
||||||
|
|
||||||
public bool UsesInstanceId { get; }
|
public bool UsesInstanceId { get; }
|
||||||
|
public byte ClipDistancesWritten { get; }
|
||||||
|
|
||||||
public ShaderProgramInfo(
|
public ShaderProgramInfo(
|
||||||
BufferDescriptor[] cBuffers,
|
BufferDescriptor[] cBuffers,
|
||||||
BufferDescriptor[] sBuffers,
|
BufferDescriptor[] sBuffers,
|
||||||
TextureDescriptor[] textures,
|
TextureDescriptor[] textures,
|
||||||
TextureDescriptor[] images,
|
TextureDescriptor[] images,
|
||||||
bool usesInstanceId)
|
bool usesInstanceId,
|
||||||
|
byte clipDistancesWritten)
|
||||||
{
|
{
|
||||||
CBuffers = Array.AsReadOnly(cBuffers);
|
CBuffers = Array.AsReadOnly(cBuffers);
|
||||||
SBuffers = Array.AsReadOnly(sBuffers);
|
SBuffers = Array.AsReadOnly(sBuffers);
|
||||||
|
@ -25,6 +27,7 @@ namespace Ryujinx.Graphics.Shader
|
||||||
Images = Array.AsReadOnly(images);
|
Images = Array.AsReadOnly(images);
|
||||||
|
|
||||||
UsesInstanceId = usesInstanceId;
|
UsesInstanceId = usesInstanceId;
|
||||||
|
ClipDistancesWritten = clipDistancesWritten;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -291,10 +291,6 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
||||||
{
|
{
|
||||||
Info.IAttributes.Add(attrIndex);
|
Info.IAttributes.Add(attrIndex);
|
||||||
}
|
}
|
||||||
else if (operand.Type == OperandType.Attribute && operand.Value == AttributeConsts.InstanceId)
|
|
||||||
{
|
|
||||||
Info.UsesInstanceId = true;
|
|
||||||
}
|
|
||||||
else if (operand.Type == OperandType.ConstantBuffer)
|
else if (operand.Type == OperandType.ConstantBuffer)
|
||||||
{
|
{
|
||||||
Info.CBuffers.Add(operand.GetCbufSlot());
|
Info.CBuffers.Add(operand.GetCbufSlot());
|
||||||
|
|
|
@ -12,7 +12,6 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
||||||
public HashSet<int> IAttributes { get; }
|
public HashSet<int> IAttributes { get; }
|
||||||
public HashSet<int> OAttributes { get; }
|
public HashSet<int> OAttributes { get; }
|
||||||
|
|
||||||
public bool UsesInstanceId { get; set; }
|
|
||||||
public bool UsesCbIndexing { get; set; }
|
public bool UsesCbIndexing { get; set; }
|
||||||
|
|
||||||
public HelperFunctionsMask HelperFunctionsMask { get; set; }
|
public HelperFunctionsMask HelperFunctionsMask { get; set; }
|
||||||
|
|
|
@ -55,7 +55,11 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
|
|
||||||
public void FlagAttributeRead(int attribute)
|
public void FlagAttributeRead(int attribute)
|
||||||
{
|
{
|
||||||
if (Config.Stage == ShaderStage.Fragment)
|
if (Config.Stage == ShaderStage.Vertex && attribute == AttributeConsts.InstanceId)
|
||||||
|
{
|
||||||
|
Config.SetUsedFeature(FeatureFlags.InstanceId);
|
||||||
|
}
|
||||||
|
else if (Config.Stage == ShaderStage.Fragment)
|
||||||
{
|
{
|
||||||
switch (attribute)
|
switch (attribute)
|
||||||
{
|
{
|
||||||
|
@ -67,6 +71,26 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void FlagAttributeWritten(int attribute)
|
||||||
|
{
|
||||||
|
if (Config.Stage == ShaderStage.Vertex)
|
||||||
|
{
|
||||||
|
switch (attribute)
|
||||||
|
{
|
||||||
|
case AttributeConsts.ClipDistance0:
|
||||||
|
case AttributeConsts.ClipDistance1:
|
||||||
|
case AttributeConsts.ClipDistance2:
|
||||||
|
case AttributeConsts.ClipDistance3:
|
||||||
|
case AttributeConsts.ClipDistance4:
|
||||||
|
case AttributeConsts.ClipDistance5:
|
||||||
|
case AttributeConsts.ClipDistance6:
|
||||||
|
case AttributeConsts.ClipDistance7:
|
||||||
|
Config.SetClipDistanceWritten((attribute - AttributeConsts.ClipDistance0) / 4);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void MarkLabel(Operand label)
|
public void MarkLabel(Operand label)
|
||||||
{
|
{
|
||||||
Add(Instruction.MarkLabel, label);
|
Add(Instruction.MarkLabel, label);
|
||||||
|
|
|
@ -12,9 +12,11 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
None = 0,
|
None = 0,
|
||||||
|
|
||||||
// Affected by resolution scaling.
|
// Affected by resolution scaling.
|
||||||
FragCoordXY = 1 << 1,
|
|
||||||
IntegerSampling = 1 << 0,
|
IntegerSampling = 1 << 0,
|
||||||
|
FragCoordXY = 1 << 1,
|
||||||
|
|
||||||
Bindless = 1 << 2,
|
Bindless = 1 << 2,
|
||||||
|
|
||||||
|
InstanceId = 1 << 3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,8 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
|
|
||||||
public int Size { get; private set; }
|
public int Size { get; private set; }
|
||||||
|
|
||||||
|
public byte ClipDistancesWritten { get; private set; }
|
||||||
|
|
||||||
public FeatureFlags UsedFeatures { get; private set; }
|
public FeatureFlags UsedFeatures { get; private set; }
|
||||||
|
|
||||||
public HashSet<int> TextureHandlesForCache { get; }
|
public HashSet<int> TextureHandlesForCache { get; }
|
||||||
|
@ -115,6 +117,11 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
Size += size;
|
Size += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetClipDistanceWritten(int index)
|
||||||
|
{
|
||||||
|
ClipDistancesWritten |= (byte)(1 << index);
|
||||||
|
}
|
||||||
|
|
||||||
public void SetUsedFeature(FeatureFlags flags)
|
public void SetUsedFeature(FeatureFlags flags)
|
||||||
{
|
{
|
||||||
UsedFeatures |= flags;
|
UsedFeatures |= flags;
|
||||||
|
|
|
@ -94,7 +94,8 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
program.SBufferDescriptors,
|
program.SBufferDescriptors,
|
||||||
program.TextureDescriptors,
|
program.TextureDescriptors,
|
||||||
program.ImageDescriptors,
|
program.ImageDescriptors,
|
||||||
sInfo.UsesInstanceId);
|
config.UsedFeatures.HasFlag(FeatureFlags.InstanceId),
|
||||||
|
config.ClipDistancesWritten);
|
||||||
|
|
||||||
string glslCode = program.Code;
|
string glslCode = program.Code;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue