mirror of
https://git.naxdy.org/Mirror/Ryujinx.git
synced 2025-02-22 17:10:19 +00:00
SPIR-V: Implement SwizzleAdd, add missing Triangles ExecutionMode for geometry shaders, remove SamplerType field from TextureMeta
This commit is contained in:
parent
c260ef7b0a
commit
1ab42e9ce8
4 changed files with 52 additions and 22 deletions
|
@ -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));
|
||||||
|
|
||||||
|
|
|
@ -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];
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue