SPIR-V: Implement SwizzleAdd, add missing Triangles ExecutionMode for geometry shaders, remove SamplerType field from TextureMeta

This commit is contained in:
gdk 2022-02-19 20:25:39 -03:00 committed by riperiperi
parent c260ef7b0a
commit 1ab42e9ce8
4 changed files with 52 additions and 22 deletions

View file

@ -177,7 +177,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
{
foreach (var descriptor in descriptors)
{
var meta = new TextureMeta(descriptor.CbufSlot, descriptor.HandleIndex, descriptor.Format, descriptor.Type);
var meta = new TextureMeta(descriptor.CbufSlot, descriptor.HandleIndex, descriptor.Format);
if (context.Samplers.ContainsKey(meta))
{
@ -187,22 +187,22 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
bool isBuffer = (descriptor.Type & SamplerType.Mask) == SamplerType.TextureBuffer;
int setIndex = context.Config.Options.TargetApi == TargetApi.Vulkan ? (isBuffer ? 4 : 2) : 0;
var dim = (meta.Type & SamplerType.Mask) switch
var dim = (descriptor.Type & SamplerType.Mask) switch
{
SamplerType.Texture1D => Dim.Dim1D,
SamplerType.Texture2D => Dim.Dim2D,
SamplerType.Texture3D => Dim.Dim3D,
SamplerType.TextureCube => Dim.Cube,
SamplerType.TextureBuffer => Dim.Buffer,
_ => throw new InvalidOperationException($"Invalid sampler type \"{meta.Type & SamplerType.Mask}\".")
_ => throw new InvalidOperationException($"Invalid sampler type \"{descriptor.Type & SamplerType.Mask}\".")
};
var imageType = context.TypeImage(
context.TypeFP32(),
dim,
meta.Type.HasFlag(SamplerType.Shadow),
meta.Type.HasFlag(SamplerType.Array),
meta.Type.HasFlag(SamplerType.Multisample),
descriptor.Type.HasFlag(SamplerType.Shadow),
descriptor.Type.HasFlag(SamplerType.Array),
descriptor.Type.HasFlag(SamplerType.Multisample),
1,
ImageFormat.Unknown);
@ -225,7 +225,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
{
foreach (var descriptor in descriptors)
{
var meta = new TextureMeta(descriptor.CbufSlot, descriptor.HandleIndex, descriptor.Format, descriptor.Type);
var meta = new TextureMeta(descriptor.CbufSlot, descriptor.HandleIndex, descriptor.Format);
if (context.Images.ContainsKey(meta))
{
@ -235,14 +235,14 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
bool isBuffer = (descriptor.Type & SamplerType.Mask) == SamplerType.TextureBuffer;
int setIndex = context.Config.Options.TargetApi == TargetApi.Vulkan ? (isBuffer ? 5 : 3) : 0;
var dim = GetDim(meta.Type);
var dim = GetDim(descriptor.Type);
var imageType = context.TypeImage(
context.GetType(meta.Format.GetComponentType().Convert()),
dim,
meta.Type.HasFlag(SamplerType.Shadow),
meta.Type.HasFlag(SamplerType.Array),
meta.Type.HasFlag(SamplerType.Multisample),
descriptor.Type.HasFlag(SamplerType.Shadow),
descriptor.Type.HasFlag(SamplerType.Array),
descriptor.Type.HasFlag(SamplerType.Multisample),
AccessQualifier.ReadWrite,
GetImageFormat(meta.Format));

View file

@ -125,6 +125,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
Add(Instruction.StoreShared, GenerateStoreShared);
Add(Instruction.StoreStorage, GenerateStoreStorage);
Add(Instruction.Subtract, GenerateSubtract);
Add(Instruction.SwizzleAdd, GenerateSwizzleAdd);
Add(Instruction.TextureSample, GenerateTextureSample);
Add(Instruction.TextureSize, GenerateTextureSize);
Add(Instruction.Truncate, GenerateTruncate);
@ -638,7 +639,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
SpvInstruction value = Src(componentType.Convert());
(var imageType, var imageVariable) = context.Images[new TextureMeta(texOp.CbufSlot, texOp.Handle, texOp.Format, texOp.Type)];
(var imageType, var imageVariable) = context.Images[new TextureMeta(texOp.CbufSlot, texOp.Handle, texOp.Format)];
var image = context.Load(imageType, imageVariable);
@ -732,7 +733,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
pCoords = Src(AggregateType.S32);
}
(var imageType, var imageVariable) = context.Images[new TextureMeta(texOp.CbufSlot, texOp.Handle, texOp.Format, texOp.Type)];
(var imageType, var imageVariable) = context.Images[new TextureMeta(texOp.CbufSlot, texOp.Handle, texOp.Format)];
var image = context.Load(imageType, imageVariable);
@ -819,7 +820,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
var texel = context.CompositeConstruct(context.TypeVector(context.GetType(componentType.Convert()), ComponentsCount), cElems);
(var imageType, var imageVariable) = context.Images[new TextureMeta(texOp.CbufSlot, texOp.Handle, texOp.Format, texOp.Type)];
(var imageType, var imageVariable) = context.Images[new TextureMeta(texOp.CbufSlot, texOp.Handle, texOp.Format)];
var image = context.Load(imageType, imageVariable);
@ -968,7 +969,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
pCoords = Src(AggregateType.FP32);
}
var meta = new TextureMeta(texOp.CbufSlot, texOp.Handle, texOp.Format, texOp.Type);
var meta = new TextureMeta(texOp.CbufSlot, texOp.Handle, texOp.Format);
(_, var sampledImageType, var sampledImageVariable) = context.Samplers[meta];
@ -1281,6 +1282,34 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
return GenerateBinary(context, operation, context.Delegates.FSub, context.Delegates.ISub);
}
private static OperationResult GenerateSwizzleAdd(CodeGenContext context, AstOperation operation)
{
var x = context.Get(AggregateType.FP32, operation.GetSource(0));
var y = context.Get(AggregateType.FP32, operation.GetSource(1));
var mask = context.Get(AggregateType.U32, operation.GetSource(2));
var v4float = context.TypeVector(context.TypeFP32(), (SpvLiteralInteger)4);
var one = context.Constant(context.TypeFP32(), (SpvLiteralInteger)1.0f);
var minusOne = context.Constant(context.TypeFP32(), (SpvLiteralInteger)(-1.0f));
var zero = context.Constant(context.TypeFP32(), (SpvLiteralInteger)0.0f);
var xLut = context.ConstantComposite(v4float, one, minusOne, one, zero);
var yLut = context.ConstantComposite(v4float, one, one, minusOne, one);
var threadId = context.GetAttribute(AggregateType.U32, AttributeConsts.LaneId, false);
var shift = context.BitwiseAnd(context.TypeU32(), threadId, context.Constant(context.TypeU32(), (SpvLiteralInteger)3));
shift = context.ShiftLeftLogical(context.TypeU32(), shift, context.Constant(context.TypeU32(), (SpvLiteralInteger)1));
var lutIdx = context.ShiftRightLogical(context.TypeU32(), mask, shift);
var xLutValue = context.AccessChain(context.TypeFP32(), xLut, lutIdx);
var yLutValue = context.AccessChain(context.TypeFP32(), yLut, lutIdx);
var xResult = context.FMul(context.TypeFP32(), x, xLutValue);
var yResult = context.FMul(context.TypeFP32(), y, yLutValue);
var result = context.FAdd(context.TypeFP32(), xResult, yResult);
return new OperationResult(AggregateType.FP32, result);
}
private static OperationResult GenerateTextureSample(CodeGenContext context, AstOperation operation)
{
AstTextureOperation texOp = (AstTextureOperation)operation;
@ -1520,7 +1549,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
bool colorIsVector = isGather || !isShadow;
var resultType = colorIsVector ? context.TypeVector(context.TypeFP32(), 4) : context.TypeFP32();
var meta = new TextureMeta(texOp.CbufSlot, texOp.Handle, texOp.Format, texOp.Type);
var meta = new TextureMeta(texOp.CbufSlot, texOp.Handle, texOp.Format);
(var imageType, var sampledImageType, var sampledImageVariable) = context.Samplers[meta];
@ -1603,7 +1632,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
var lod = context.GetS32(operation.GetSource(lodSrcIndex));
var meta = new TextureMeta(texOp.CbufSlot, texOp.Handle, texOp.Format, texOp.Type);
var meta = new TextureMeta(texOp.CbufSlot, texOp.Handle, texOp.Format);
(var imageType, var sampledImageType, var sampledImageVariable) = context.Samplers[meta];

View file

@ -163,6 +163,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
case InputTopology.LinesAdjacency:
context.AddExecutionMode(spvFunc, ExecutionMode.InputLinesAdjacency);
break;
case InputTopology.Triangles:
context.AddExecutionMode(spvFunc, ExecutionMode.Triangles);
break;
case InputTopology.TrianglesAdjacency:
context.AddExecutionMode(spvFunc, ExecutionMode.InputTrianglesAdjacency);
break;

View file

@ -7,14 +7,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
public int CbufSlot { get; }
public int Handle { get; }
public TextureFormat Format { get; }
public SamplerType Type { get; }
public TextureMeta(int cbufSlot, int handle, TextureFormat format, SamplerType type)
public TextureMeta(int cbufSlot, int handle, TextureFormat format)
{
CbufSlot = cbufSlot;
Handle = handle;
Format = format;
Type = type;
}
public override bool Equals(object obj)
@ -24,12 +22,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
public bool Equals(TextureMeta other)
{
return CbufSlot == other.CbufSlot && Handle == other.Handle && Format == other.Format && Type == other.Type;
return CbufSlot == other.CbufSlot && Handle == other.Handle && Format == other.Format;
}
public override int GetHashCode()
{
return HashCode.Combine(CbufSlot, Handle, Format, Type);
return HashCode.Combine(CbufSlot, Handle, Format);
}
}
}