mirror of
https://github.com/GreemDev/Ryujinx.git
synced 2024-12-23 02:15:49 +00:00
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 _vsUsesInstanceId;
|
||||
private byte _vsClipDistancesWritten;
|
||||
|
||||
private bool _forceShaderUpdate;
|
||||
|
||||
|
@ -993,7 +994,15 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
|
||||
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 uniformBufferBindingsCount = 0;
|
||||
|
@ -1098,7 +1107,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
/// <param name="state">Current GPU state</param>
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -75,7 +75,8 @@ namespace Ryujinx.Graphics.Gpu.Shader.Cache.Definition
|
|||
programInfo.SBuffers.Count,
|
||||
programInfo.Textures.Count,
|
||||
programInfo.Images.Count,
|
||||
programInfo.UsesInstanceId);
|
||||
programInfo.UsesInstanceId,
|
||||
programInfo.ClipDistancesWritten);
|
||||
CBuffers = programInfo.CBuffers.ToArray();
|
||||
SBuffers = programInfo.SBuffers.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>
|
||||
internal ShaderProgramInfo ToShaderProgramInfo()
|
||||
{
|
||||
return new ShaderProgramInfo(CBuffers, SBuffers, Textures, Images, Header.UsesInstanceId);
|
||||
return new ShaderProgramInfo(CBuffers, SBuffers, Textures, Images, Header.UsesInstanceId, Header.ClipDistancesWritten);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -41,10 +41,15 @@ namespace Ryujinx.Graphics.Gpu.Shader.Cache.Definition
|
|||
[MarshalAs(UnmanagedType.I1)]
|
||||
public bool InUse;
|
||||
|
||||
/// <summary>
|
||||
/// Mask of clip distances that are written to on the shader.
|
||||
/// </summary>
|
||||
public byte ClipDistancesWritten;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved / unused.
|
||||
/// </summary>
|
||||
public short Reserved;
|
||||
public byte Reserved;
|
||||
|
||||
/// <summary>
|
||||
/// 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="imagesCount">Count of image descriptors</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;
|
||||
SBuffersCount = sBuffersCount;
|
||||
TexturesCount = texturesCount;
|
||||
ImagesCount = imagesCount;
|
||||
UsesInstanceId = usesInstanceId;
|
||||
InUse = true;
|
||||
CBuffersCount = cBuffersCount;
|
||||
SBuffersCount = sBuffersCount;
|
||||
TexturesCount = texturesCount;
|
||||
ImagesCount = imagesCount;
|
||||
UsesInstanceId = usesInstanceId;
|
||||
ClipDistancesWritten = clipDistancesWritten;
|
||||
InUse = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
/// <summary>
|
||||
/// Version of the codegen (to be changed when codegen or guest format change).
|
||||
/// </summary>
|
||||
private const ulong ShaderCodeGenVersion = 2200;
|
||||
private const ulong ShaderCodeGenVersion = 2217;
|
||||
|
||||
// Progress reporting helpers
|
||||
private volatile int _shaderCount;
|
||||
|
|
|
@ -53,6 +53,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
Operand dest = Attribute(op.AttributeOffset + index * 4);
|
||||
|
||||
context.FlagAttributeWritten(dest.Value);
|
||||
|
||||
context.Copy(dest, Register(rd));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,13 +11,15 @@ namespace Ryujinx.Graphics.Shader
|
|||
public ReadOnlyCollection<TextureDescriptor> Images { get; }
|
||||
|
||||
public bool UsesInstanceId { get; }
|
||||
public byte ClipDistancesWritten { get; }
|
||||
|
||||
public ShaderProgramInfo(
|
||||
BufferDescriptor[] cBuffers,
|
||||
BufferDescriptor[] sBuffers,
|
||||
TextureDescriptor[] textures,
|
||||
TextureDescriptor[] images,
|
||||
bool usesInstanceId)
|
||||
bool usesInstanceId,
|
||||
byte clipDistancesWritten)
|
||||
{
|
||||
CBuffers = Array.AsReadOnly(cBuffers);
|
||||
SBuffers = Array.AsReadOnly(sBuffers);
|
||||
|
@ -25,6 +27,7 @@ namespace Ryujinx.Graphics.Shader
|
|||
Images = Array.AsReadOnly(images);
|
||||
|
||||
UsesInstanceId = usesInstanceId;
|
||||
ClipDistancesWritten = clipDistancesWritten;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -291,10 +291,6 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
{
|
||||
Info.IAttributes.Add(attrIndex);
|
||||
}
|
||||
else if (operand.Type == OperandType.Attribute && operand.Value == AttributeConsts.InstanceId)
|
||||
{
|
||||
Info.UsesInstanceId = true;
|
||||
}
|
||||
else if (operand.Type == OperandType.ConstantBuffer)
|
||||
{
|
||||
Info.CBuffers.Add(operand.GetCbufSlot());
|
||||
|
|
|
@ -12,7 +12,6 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||
public HashSet<int> IAttributes { get; }
|
||||
public HashSet<int> OAttributes { get; }
|
||||
|
||||
public bool UsesInstanceId { get; set; }
|
||||
public bool UsesCbIndexing { get; set; }
|
||||
|
||||
public HelperFunctionsMask HelperFunctionsMask { get; set; }
|
||||
|
|
|
@ -55,7 +55,11 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
|
||||
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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
Add(Instruction.MarkLabel, label);
|
||||
|
|
|
@ -12,9 +12,11 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
None = 0,
|
||||
|
||||
// Affected by resolution scaling.
|
||||
FragCoordXY = 1 << 1,
|
||||
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 byte ClipDistancesWritten { get; private set; }
|
||||
|
||||
public FeatureFlags UsedFeatures { get; private set; }
|
||||
|
||||
public HashSet<int> TextureHandlesForCache { get; }
|
||||
|
@ -115,6 +117,11 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
Size += size;
|
||||
}
|
||||
|
||||
public void SetClipDistanceWritten(int index)
|
||||
{
|
||||
ClipDistancesWritten |= (byte)(1 << index);
|
||||
}
|
||||
|
||||
public void SetUsedFeature(FeatureFlags flags)
|
||||
{
|
||||
UsedFeatures |= flags;
|
||||
|
|
|
@ -94,7 +94,8 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
program.SBufferDescriptors,
|
||||
program.TextureDescriptors,
|
||||
program.ImageDescriptors,
|
||||
sInfo.UsesInstanceId);
|
||||
config.UsedFeatures.HasFlag(FeatureFlags.InstanceId),
|
||||
config.ClipDistancesWritten);
|
||||
|
||||
string glslCode = program.Code;
|
||||
|
||||
|
|
Loading…
Reference in a new issue