mirror of
https://git.naxdy.org/Mirror/Ryujinx.git
synced 2024-12-31 21:13:04 +00:00
b423197619
* Move some properties out of ShaderConfig * Stop using ShaderConfig on backends * Replace ShaderConfig usages on Translator and passes * Move remaining properties out of ShaderConfig and delete ShaderConfig * Remove ResourceManager property from TranslatorContext * Move Rewriter passes to separate transform pass files * Fix TransformPasses.RunPass on cases where a node is removed * Move remaining ClipDistancePrimitivesWritten and UsedFeatures updates to decode stage * Reduce excessive parameter passing a bit by using structs more * Remove binding parameter from ShaderProperties methods since it is redundant * Replace decoder instruction checks with switch statement * Put GLSL on the same plan as SPIR-V for input/output declaration * Stop mutating TranslatorContext state when Translate is called * Pass most of the graphics state using a struct instead of individual query methods * Auto-format * Auto-format * Add backend logging interface * Auto-format * Remove unnecessary use of interpolated strings * Remove more modifications of AttributeUsage after decode * PR feedback * gl_Layer is not supported on compute
168 lines
5.8 KiB
C#
168 lines
5.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Numerics;
|
|
|
|
namespace Ryujinx.Graphics.Shader.Translation
|
|
{
|
|
class AttributeUsage
|
|
{
|
|
public bool NextUsesFixedFuncAttributes { get; private set; }
|
|
public int UsedInputAttributes { get; private set; }
|
|
public int UsedOutputAttributes { get; private set; }
|
|
public HashSet<int> UsedInputAttributesPerPatch { get; }
|
|
public HashSet<int> UsedOutputAttributesPerPatch { get; }
|
|
public HashSet<int> NextUsedInputAttributesPerPatch { get; private set; }
|
|
public int PassthroughAttributes { get; private set; }
|
|
private int _nextUsedInputAttributes;
|
|
private int _thisUsedInputAttributes;
|
|
private Dictionary<int, int> _perPatchAttributeLocations;
|
|
private readonly IGpuAccessor _gpuAccessor;
|
|
|
|
public UInt128 NextInputAttributesComponents { get; private set; }
|
|
public UInt128 ThisInputAttributesComponents { get; private set; }
|
|
|
|
public AttributeUsage(IGpuAccessor gpuAccessor)
|
|
{
|
|
_gpuAccessor = gpuAccessor;
|
|
|
|
UsedInputAttributesPerPatch = new();
|
|
UsedOutputAttributesPerPatch = new();
|
|
}
|
|
|
|
public void SetInputUserAttribute(int index, int component)
|
|
{
|
|
int mask = 1 << index;
|
|
|
|
UsedInputAttributes |= mask;
|
|
_thisUsedInputAttributes |= mask;
|
|
ThisInputAttributesComponents |= UInt128.One << (index * 4 + component);
|
|
}
|
|
|
|
public void SetInputUserAttributePerPatch(int index)
|
|
{
|
|
UsedInputAttributesPerPatch.Add(index);
|
|
}
|
|
|
|
public void SetOutputUserAttribute(int index)
|
|
{
|
|
UsedOutputAttributes |= 1 << index;
|
|
}
|
|
|
|
public void SetOutputUserAttributePerPatch(int index)
|
|
{
|
|
UsedOutputAttributesPerPatch.Add(index);
|
|
}
|
|
|
|
public void MergeFromtNextStage(bool gpPassthrough, bool nextUsesFixedFunctionAttributes, AttributeUsage nextStage)
|
|
{
|
|
NextInputAttributesComponents = nextStage.ThisInputAttributesComponents;
|
|
NextUsedInputAttributesPerPatch = nextStage.UsedInputAttributesPerPatch;
|
|
NextUsesFixedFuncAttributes = nextUsesFixedFunctionAttributes;
|
|
MergeOutputUserAttributes(gpPassthrough, nextStage.UsedInputAttributes, nextStage.UsedInputAttributesPerPatch);
|
|
|
|
if (UsedOutputAttributesPerPatch.Count != 0)
|
|
{
|
|
// Regular and per-patch input/output locations can't overlap,
|
|
// so we must assign on our location using unused regular input/output locations.
|
|
|
|
Dictionary<int, int> locationsMap = new();
|
|
|
|
int freeMask = ~UsedOutputAttributes;
|
|
|
|
foreach (int attr in UsedOutputAttributesPerPatch)
|
|
{
|
|
int location = BitOperations.TrailingZeroCount(freeMask);
|
|
if (location == 32)
|
|
{
|
|
_gpuAccessor.Log($"No enough free locations for patch input/output 0x{attr:X}.");
|
|
break;
|
|
}
|
|
|
|
locationsMap.Add(attr, location);
|
|
freeMask &= ~(1 << location);
|
|
}
|
|
|
|
// Both stages must agree on the locations, so use the same "map" for both.
|
|
_perPatchAttributeLocations = locationsMap;
|
|
nextStage._perPatchAttributeLocations = locationsMap;
|
|
}
|
|
}
|
|
|
|
private void MergeOutputUserAttributes(bool gpPassthrough, int mask, IEnumerable<int> perPatch)
|
|
{
|
|
_nextUsedInputAttributes = mask;
|
|
|
|
if (gpPassthrough)
|
|
{
|
|
PassthroughAttributes = mask & ~UsedOutputAttributes;
|
|
}
|
|
else
|
|
{
|
|
UsedOutputAttributes |= mask;
|
|
UsedOutputAttributesPerPatch.UnionWith(perPatch);
|
|
}
|
|
}
|
|
|
|
public int GetPerPatchAttributeLocation(int index)
|
|
{
|
|
if (_perPatchAttributeLocations == null || !_perPatchAttributeLocations.TryGetValue(index, out int location))
|
|
{
|
|
return index;
|
|
}
|
|
|
|
return location;
|
|
}
|
|
|
|
public bool IsUsedOutputAttribute(int attr)
|
|
{
|
|
// The check for fixed function attributes on the next stage is conservative,
|
|
// returning false if the output is just not used by the next stage is also valid.
|
|
if (NextUsesFixedFuncAttributes &&
|
|
attr >= AttributeConsts.UserAttributeBase &&
|
|
attr < AttributeConsts.UserAttributeEnd)
|
|
{
|
|
int index = (attr - AttributeConsts.UserAttributeBase) >> 4;
|
|
return (_nextUsedInputAttributes & (1 << index)) != 0;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public int GetFreeUserAttribute(bool isOutput, int index)
|
|
{
|
|
int useMask = isOutput ? _nextUsedInputAttributes : _thisUsedInputAttributes;
|
|
int bit = -1;
|
|
|
|
while (useMask != -1)
|
|
{
|
|
bit = BitOperations.TrailingZeroCount(~useMask);
|
|
|
|
if (bit == 32)
|
|
{
|
|
bit = -1;
|
|
break;
|
|
}
|
|
else if (index < 1)
|
|
{
|
|
break;
|
|
}
|
|
|
|
useMask |= 1 << bit;
|
|
index--;
|
|
}
|
|
|
|
return bit;
|
|
}
|
|
|
|
public void SetAllInputUserAttributes()
|
|
{
|
|
UsedInputAttributes |= Constants.AllAttributesMask;
|
|
ThisInputAttributesComponents |= ~UInt128.Zero >> (128 - Constants.MaxAttributes * 4);
|
|
}
|
|
|
|
public void SetAllOutputUserAttributes()
|
|
{
|
|
UsedOutputAttributes |= Constants.AllAttributesMask;
|
|
}
|
|
}
|
|
}
|