Move shader resource descriptor creation out of the backend (#2290)

* Move shader resource descriptor creation out of the backend

* Remove now unused code, and other nits

* Shader cache version bump

* Nits

* Set format for bindless image load/store

* Fix buffer write flag
This commit is contained in:
gdkchan
2021-05-19 18:15:26 -03:00
committed by GitHub
parent b5c72b44de
commit 49745cfa37
25 changed files with 565 additions and 516 deletions

View File

@ -4,31 +4,28 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
{
class AstTextureOperation : AstOperation
{
public SamplerType Type { get; }
public SamplerType Type { get; }
public TextureFormat Format { get; }
public TextureFlags Flags { get; }
public TextureFlags Flags { get; }
public int CbufSlot { get; }
public int Handle { get; }
public int ArraySize { get; }
public int CbufSlot { get; }
public int Handle { get; }
public AstTextureOperation(
Instruction inst,
SamplerType type,
TextureFormat format,
TextureFlags flags,
int cbufSlot,
int handle,
int arraySize,
int index,
Instruction inst,
SamplerType type,
TextureFormat format,
TextureFlags flags,
int cbufSlot,
int handle,
int index,
params IAstNode[] sources) : base(inst, index, sources, sources.Length)
{
Type = type;
Format = format;
Flags = flags;
CbufSlot = cbufSlot;
Handle = handle;
ArraySize = arraySize;
Type = type;
Format = format;
Flags = flags;
CbufSlot = cbufSlot;
Handle = handle;
}
}
}

View File

@ -2,7 +2,6 @@ using Ryujinx.Graphics.Shader.IntermediateRepresentation;
using Ryujinx.Graphics.Shader.Translation;
using System;
using System.Collections.Generic;
using System.Numerics;
namespace Ryujinx.Graphics.Shader.StructuredIr
{
@ -100,7 +99,6 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
texOp.Flags,
texOp.CbufSlot,
texOp.Handle,
4, // TODO: Non-hardcoded array size.
texOp.Index,
sources);
}
@ -109,34 +107,6 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
{
AstOperand dest = context.GetOperandDef(operation.Dest);
if (inst == Instruction.LoadConstant)
{
Operand slot = operation.GetSource(0);
if (slot.Type == OperandType.Constant)
{
context.Info.CBuffers.Add(slot.Value);
}
else
{
// If the value is not constant, then we don't know
// how many constant buffers are used, so we assume
// all of them are used.
int cbCount = 32 - BitOperations.LeadingZeroCount(context.Config.GpuAccessor.QueryConstantBufferUse());
for (int index = 0; index < cbCount; index++)
{
context.Info.CBuffers.Add(index);
}
context.Info.UsesCbIndexing = true;
}
}
else if (UsesStorage(inst))
{
AddSBufferUse(context.Info.SBuffers, operation);
}
// If all the sources are bool, it's better to use short-circuiting
// logical operations, rather than forcing a cast to int and doing
// a bitwise operation with the value, as it is likely to be used as
@ -169,23 +139,12 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
if (operation is TextureOperation texOp)
{
if (texOp.Inst == Instruction.ImageLoad || texOp.Inst == Instruction.ImageStore)
if (texOp.Inst == Instruction.ImageLoad)
{
dest.VarType = texOp.Format.GetComponentType();
}
AstTextureOperation astTexOp = GetAstTextureOperation(texOp);
if (texOp.Inst == Instruction.ImageLoad)
{
context.Info.Images.Add(astTexOp);
}
else
{
context.Info.Samplers.Add(astTexOp);
}
source = astTexOp;
source = GetAstTextureOperation(texOp);
}
else if (!isCopy)
{
@ -206,17 +165,10 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
{
AstTextureOperation astTexOp = GetAstTextureOperation(texOp);
context.Info.Images.Add(astTexOp);
context.AddNode(astTexOp);
}
else
{
if (UsesStorage(inst))
{
AddSBufferUse(context.Info.SBuffers, operation);
}
context.AddNode(new AstOperation(inst, operation.Index, sources, operation.SourcesCount));
}
@ -257,26 +209,6 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
}
}
private static void AddSBufferUse(HashSet<int> sBuffers, Operation operation)
{
Operand slot = operation.GetSource(0);
if (slot.Type == OperandType.Constant)
{
sBuffers.Add(slot.Value);
}
else
{
// If the value is not constant, then we don't know
// how many storage buffers are used, so we assume
// all of them are used.
for (int index = 0; index < GlobalMemory.StorageMaxCount; index++)
{
sBuffers.Add(index);
}
}
}
private static VariableType GetVarTypeFromUses(Operand dest)
{
HashSet<Operand> visited = new HashSet<Operand>();
@ -301,7 +233,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
{
foreach (INode useNode in operand.UseOps)
{
if (!(useNode is Operation operation))
if (useNode is not Operation operation)
{
continue;
}
@ -340,7 +272,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
{
foreach (IAstNode node in sources)
{
if (!(node is AstOperand operand))
if (node is not AstOperand operand)
{
return false;
}
@ -356,52 +288,37 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
private static bool IsBranchInst(Instruction inst)
{
switch (inst)
return inst switch
{
case Instruction.Branch:
case Instruction.BranchIfFalse:
case Instruction.BranchIfTrue:
return true;
}
return false;
Instruction.Branch or
Instruction.BranchIfFalse or
Instruction.BranchIfTrue => true,
_ => false,
};
}
private static bool IsBitwiseInst(Instruction inst)
{
switch (inst)
return inst switch
{
case Instruction.BitwiseAnd:
case Instruction.BitwiseExclusiveOr:
case Instruction.BitwiseNot:
case Instruction.BitwiseOr:
return true;
}
return false;
Instruction.BitwiseAnd or
Instruction.BitwiseExclusiveOr or
Instruction.BitwiseNot or
Instruction.BitwiseOr => true,
_ => false
};
}
private static Instruction GetLogicalFromBitwiseInst(Instruction inst)
{
switch (inst)
return inst switch
{
case Instruction.BitwiseAnd: return Instruction.LogicalAnd;
case Instruction.BitwiseExclusiveOr: return Instruction.LogicalExclusiveOr;
case Instruction.BitwiseNot: return Instruction.LogicalNot;
case Instruction.BitwiseOr: return Instruction.LogicalOr;
}
throw new ArgumentException($"Unexpected instruction \"{inst}\".");
}
private static bool UsesStorage(Instruction inst)
{
if (inst == Instruction.LoadStorage || inst == Instruction.StoreStorage)
{
return true;
}
return inst.IsAtomic() && (inst & Instruction.MrMask) == Instruction.MrStorage;
Instruction.BitwiseAnd => Instruction.LogicalAnd,
Instruction.BitwiseExclusiveOr => Instruction.LogicalExclusiveOr,
Instruction.BitwiseNot => Instruction.LogicalNot,
Instruction.BitwiseOr => Instruction.LogicalOr,
_ => throw new ArgumentException($"Unexpected instruction \"{inst}\".")
};
}
}
}

View File

@ -291,10 +291,6 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
{
Info.IAttributes.Add(attrIndex);
}
else if (operand.Type == OperandType.ConstantBuffer)
{
Info.CBuffers.Add(operand.GetCbufSlot());
}
return GetOperand(operand);
}

View File

@ -6,31 +6,17 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
{
public List<StructuredFunction> Functions { get; }
public HashSet<int> CBuffers { get; }
public HashSet<int> SBuffers { get; }
public HashSet<int> IAttributes { get; }
public HashSet<int> OAttributes { get; }
public bool UsesCbIndexing { get; set; }
public HelperFunctionsMask HelperFunctionsMask { get; set; }
public HashSet<AstTextureOperation> Samplers { get; }
public HashSet<AstTextureOperation> Images { get; }
public StructuredProgramInfo()
{
Functions = new List<StructuredFunction>();
CBuffers = new HashSet<int>();
SBuffers = new HashSet<int>();
IAttributes = new HashSet<int>();
OAttributes = new HashSet<int>();
Samplers = new HashSet<AstTextureOperation>();
Images = new HashSet<AstTextureOperation>();
}
}
}