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) 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)) if (context.Samplers.ContainsKey(meta))
{ {
@ -187,22 +187,22 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
bool isBuffer = (descriptor.Type & SamplerType.Mask) == SamplerType.TextureBuffer; bool isBuffer = (descriptor.Type & SamplerType.Mask) == SamplerType.TextureBuffer;
int setIndex = context.Config.Options.TargetApi == TargetApi.Vulkan ? (isBuffer ? 4 : 2) : 0; 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.Texture1D => Dim.Dim1D,
SamplerType.Texture2D => Dim.Dim2D, SamplerType.Texture2D => Dim.Dim2D,
SamplerType.Texture3D => Dim.Dim3D, SamplerType.Texture3D => Dim.Dim3D,
SamplerType.TextureCube => Dim.Cube, SamplerType.TextureCube => Dim.Cube,
SamplerType.TextureBuffer => Dim.Buffer, 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( var imageType = context.TypeImage(
context.TypeFP32(), context.TypeFP32(),
dim, dim,
meta.Type.HasFlag(SamplerType.Shadow), descriptor.Type.HasFlag(SamplerType.Shadow),
meta.Type.HasFlag(SamplerType.Array), descriptor.Type.HasFlag(SamplerType.Array),
meta.Type.HasFlag(SamplerType.Multisample), descriptor.Type.HasFlag(SamplerType.Multisample),
1, 1,
ImageFormat.Unknown); ImageFormat.Unknown);
@ -225,7 +225,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
{ {
foreach (var descriptor in descriptors) 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)) if (context.Images.ContainsKey(meta))
{ {
@ -235,14 +235,14 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
bool isBuffer = (descriptor.Type & SamplerType.Mask) == SamplerType.TextureBuffer; bool isBuffer = (descriptor.Type & SamplerType.Mask) == SamplerType.TextureBuffer;
int setIndex = context.Config.Options.TargetApi == TargetApi.Vulkan ? (isBuffer ? 5 : 3) : 0; 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( var imageType = context.TypeImage(
context.GetType(meta.Format.GetComponentType().Convert()), context.GetType(meta.Format.GetComponentType().Convert()),
dim, dim,
meta.Type.HasFlag(SamplerType.Shadow), descriptor.Type.HasFlag(SamplerType.Shadow),
meta.Type.HasFlag(SamplerType.Array), descriptor.Type.HasFlag(SamplerType.Array),
meta.Type.HasFlag(SamplerType.Multisample), descriptor.Type.HasFlag(SamplerType.Multisample),
AccessQualifier.ReadWrite, AccessQualifier.ReadWrite,
GetImageFormat(meta.Format)); GetImageFormat(meta.Format));

View file

@ -125,6 +125,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
Add(Instruction.StoreShared, GenerateStoreShared); Add(Instruction.StoreShared, GenerateStoreShared);
Add(Instruction.StoreStorage, GenerateStoreStorage); Add(Instruction.StoreStorage, GenerateStoreStorage);
Add(Instruction.Subtract, GenerateSubtract); Add(Instruction.Subtract, GenerateSubtract);
Add(Instruction.SwizzleAdd, GenerateSwizzleAdd);
Add(Instruction.TextureSample, GenerateTextureSample); Add(Instruction.TextureSample, GenerateTextureSample);
Add(Instruction.TextureSize, GenerateTextureSize); Add(Instruction.TextureSize, GenerateTextureSize);
Add(Instruction.Truncate, GenerateTruncate); Add(Instruction.Truncate, GenerateTruncate);
@ -638,7 +639,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
SpvInstruction value = Src(componentType.Convert()); 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); var image = context.Load(imageType, imageVariable);
@ -732,7 +733,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
pCoords = Src(AggregateType.S32); 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); 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 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); var image = context.Load(imageType, imageVariable);
@ -968,7 +969,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
pCoords = Src(AggregateType.FP32); 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]; (_, 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); 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) private static OperationResult GenerateTextureSample(CodeGenContext context, AstOperation operation)
{ {
AstTextureOperation texOp = (AstTextureOperation)operation; AstTextureOperation texOp = (AstTextureOperation)operation;
@ -1520,7 +1549,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
bool colorIsVector = isGather || !isShadow; bool colorIsVector = isGather || !isShadow;
var resultType = colorIsVector ? context.TypeVector(context.TypeFP32(), 4) : context.TypeFP32(); 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]; (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 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]; (var imageType, var sampledImageType, var sampledImageVariable) = context.Samplers[meta];

View file

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

View file

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