mirror of
https://github.com/Ryubing/Ryujinx.git
synced 2025-03-10 17:14:25 +00:00
misc: chore: Use explicit types in Shader project
This commit is contained in:
parent
68bbb29be6
commit
f2aa6b3a5b
@ -149,7 +149,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
|
|
||||||
if (context.Definitions.TransformFeedbackEnabled && context.Definitions.LastInVertexPipeline)
|
if (context.Definitions.TransformFeedbackEnabled && context.Definitions.LastInVertexPipeline)
|
||||||
{
|
{
|
||||||
var tfOutput = context.Definitions.GetTransformFeedbackOutput(AttributeConsts.PositionX);
|
TransformFeedbackOutput tfOutput = context.Definitions.GetTransformFeedbackOutput(AttributeConsts.PositionX);
|
||||||
if (tfOutput.Valid)
|
if (tfOutput.Valid)
|
||||||
{
|
{
|
||||||
context.AppendLine($"layout (xfb_buffer = {tfOutput.Buffer}, xfb_offset = {tfOutput.Offset}, xfb_stride = {tfOutput.Stride}) out gl_PerVertex");
|
context.AppendLine($"layout (xfb_buffer = {tfOutput.Buffer}, xfb_offset = {tfOutput.Offset}, xfb_stride = {tfOutput.Stride}) out gl_PerVertex");
|
||||||
@ -338,7 +338,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
|
|
||||||
private static void DeclareSamplers(CodeGenContext context, IEnumerable<TextureDefinition> definitions)
|
private static void DeclareSamplers(CodeGenContext context, IEnumerable<TextureDefinition> definitions)
|
||||||
{
|
{
|
||||||
foreach (var definition in definitions)
|
foreach (TextureDefinition definition in definitions)
|
||||||
{
|
{
|
||||||
string arrayDecl = string.Empty;
|
string arrayDecl = string.Empty;
|
||||||
|
|
||||||
@ -366,7 +366,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
|
|
||||||
private static void DeclareImages(CodeGenContext context, IEnumerable<TextureDefinition> definitions)
|
private static void DeclareImages(CodeGenContext context, IEnumerable<TextureDefinition> definitions)
|
||||||
{
|
{
|
||||||
foreach (var definition in definitions)
|
foreach (TextureDefinition definition in definitions)
|
||||||
{
|
{
|
||||||
string arrayDecl = string.Empty;
|
string arrayDecl = string.Empty;
|
||||||
|
|
||||||
@ -413,7 +413,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
foreach (var ioDefinition in inputs.OrderBy(x => x.Location))
|
foreach (IoDefinition ioDefinition in inputs.OrderBy(x => x.Location))
|
||||||
{
|
{
|
||||||
DeclareInputAttribute(context, ioDefinition.Location, ioDefinition.Component);
|
DeclareInputAttribute(context, ioDefinition.Location, ioDefinition.Component);
|
||||||
}
|
}
|
||||||
@ -427,7 +427,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
|
|
||||||
private static void DeclareInputAttributesPerPatch(CodeGenContext context, IEnumerable<IoDefinition> inputs)
|
private static void DeclareInputAttributesPerPatch(CodeGenContext context, IEnumerable<IoDefinition> inputs)
|
||||||
{
|
{
|
||||||
foreach (var ioDefinition in inputs.OrderBy(x => x.Location))
|
foreach (IoDefinition ioDefinition in inputs.OrderBy(x => x.Location))
|
||||||
{
|
{
|
||||||
DeclareInputAttributePerPatch(context, ioDefinition.Location);
|
DeclareInputAttributePerPatch(context, ioDefinition.Location);
|
||||||
}
|
}
|
||||||
@ -521,7 +521,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var ioDefinition in outputs)
|
foreach (IoDefinition ioDefinition in outputs)
|
||||||
{
|
{
|
||||||
DeclareOutputAttribute(context, ioDefinition.Location, ioDefinition.Component);
|
DeclareOutputAttribute(context, ioDefinition.Location, ioDefinition.Component);
|
||||||
}
|
}
|
||||||
@ -548,7 +548,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
|
|
||||||
string xfb = string.Empty;
|
string xfb = string.Empty;
|
||||||
|
|
||||||
var tfOutput = context.Definitions.GetTransformFeedbackOutput(location, component);
|
TransformFeedbackOutput tfOutput = context.Definitions.GetTransformFeedbackOutput(location, component);
|
||||||
if (tfOutput.Valid)
|
if (tfOutput.Valid)
|
||||||
{
|
{
|
||||||
xfb = $", xfb_buffer = {tfOutput.Buffer}, xfb_offset = {tfOutput.Offset}, xfb_stride = {tfOutput.Stride}";
|
xfb = $", xfb_buffer = {tfOutput.Buffer}, xfb_offset = {tfOutput.Offset}, xfb_stride = {tfOutput.Stride}";
|
||||||
@ -570,7 +570,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
|
|
||||||
string xfb = string.Empty;
|
string xfb = string.Empty;
|
||||||
|
|
||||||
var tfOutput = context.Definitions.GetTransformFeedbackOutput(location, 0);
|
TransformFeedbackOutput tfOutput = context.Definitions.GetTransformFeedbackOutput(location, 0);
|
||||||
if (tfOutput.Valid)
|
if (tfOutput.Valid)
|
||||||
{
|
{
|
||||||
xfb = $", xfb_buffer = {tfOutput.Buffer}, xfb_offset = {tfOutput.Offset}, xfb_stride = {tfOutput.Stride}";
|
xfb = $", xfb_buffer = {tfOutput.Buffer}, xfb_offset = {tfOutput.Offset}, xfb_stride = {tfOutput.Stride}";
|
||||||
@ -606,7 +606,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
|
|
||||||
private static void DeclareOutputAttributesPerPatch(CodeGenContext context, IEnumerable<IoDefinition> outputs)
|
private static void DeclareOutputAttributesPerPatch(CodeGenContext context, IEnumerable<IoDefinition> outputs)
|
||||||
{
|
{
|
||||||
foreach (var ioDefinition in outputs)
|
foreach (IoDefinition ioDefinition in outputs)
|
||||||
{
|
{
|
||||||
DeclareOutputAttributePerPatch(context, ioDefinition.Location);
|
DeclareOutputAttributePerPatch(context, ioDefinition.Location);
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
|
|
||||||
Debug.Assert(funcId.Type == OperandType.Constant);
|
Debug.Assert(funcId.Type == OperandType.Constant);
|
||||||
|
|
||||||
var function = context.GetFunction(funcId.Value);
|
StructuredFunction function = context.GetFunction(funcId.Value);
|
||||||
|
|
||||||
string[] args = new string[operation.SourcesCount - 1];
|
string[] args = new string[operation.SourcesCount - 1];
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
|
|
||||||
bool isArray = (texOp.Type & SamplerType.Array) != 0;
|
bool isArray = (texOp.Type & SamplerType.Array) != 0;
|
||||||
|
|
||||||
var texCallBuilder = new StringBuilder();
|
StringBuilder texCallBuilder = new StringBuilder();
|
||||||
|
|
||||||
if (texOp.Inst == Instruction.ImageAtomic)
|
if (texOp.Inst == Instruction.ImageAtomic)
|
||||||
{
|
{
|
||||||
|
@ -69,7 +69,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
|||||||
context.AppendLine("using namespace metal;");
|
context.AppendLine("using namespace metal;");
|
||||||
context.AppendLine();
|
context.AppendLine();
|
||||||
|
|
||||||
var fsi = (info.HelperFunctionsMask & HelperFunctionsMask.FSI) != 0;
|
bool fsi = (info.HelperFunctionsMask & HelperFunctionsMask.FSI) != 0;
|
||||||
|
|
||||||
DeclareInputAttributes(context, info.IoDefinitions.Where(x => IsUserDefined(x, StorageKind.Input)));
|
DeclareInputAttributes(context, info.IoDefinitions.Where(x => IsUserDefined(x, StorageKind.Input)));
|
||||||
context.AppendLine();
|
context.AppendLine();
|
||||||
@ -79,25 +79,25 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
|||||||
DeclareBufferStructures(context, context.Properties.StorageBuffers.Values.OrderBy(x => x.Binding).ToArray(), false, fsi);
|
DeclareBufferStructures(context, context.Properties.StorageBuffers.Values.OrderBy(x => x.Binding).ToArray(), false, fsi);
|
||||||
|
|
||||||
// We need to declare each set as a new struct
|
// We need to declare each set as a new struct
|
||||||
var textureDefinitions = context.Properties.Textures.Values
|
Dictionary<int, TextureDefinition[]> textureDefinitions = context.Properties.Textures.Values
|
||||||
.GroupBy(x => x.Set)
|
.GroupBy(x => x.Set)
|
||||||
.ToDictionary(x => x.Key, x => x.OrderBy(y => y.Binding).ToArray());
|
.ToDictionary(x => x.Key, x => x.OrderBy(y => y.Binding).ToArray());
|
||||||
|
|
||||||
var imageDefinitions = context.Properties.Images.Values
|
Dictionary<int, TextureDefinition[]> imageDefinitions = context.Properties.Images.Values
|
||||||
.GroupBy(x => x.Set)
|
.GroupBy(x => x.Set)
|
||||||
.ToDictionary(x => x.Key, x => x.OrderBy(y => y.Binding).ToArray());
|
.ToDictionary(x => x.Key, x => x.OrderBy(y => y.Binding).ToArray());
|
||||||
|
|
||||||
var textureSets = textureDefinitions.Keys.ToArray();
|
int[] textureSets = textureDefinitions.Keys.ToArray();
|
||||||
var imageSets = imageDefinitions.Keys.ToArray();
|
int[] imageSets = imageDefinitions.Keys.ToArray();
|
||||||
|
|
||||||
var sets = textureSets.Union(imageSets).ToArray();
|
int[] sets = textureSets.Union(imageSets).ToArray();
|
||||||
|
|
||||||
foreach (var set in textureDefinitions)
|
foreach (KeyValuePair<int, TextureDefinition[]> set in textureDefinitions)
|
||||||
{
|
{
|
||||||
DeclareTextures(context, set.Value, set.Key);
|
DeclareTextures(context, set.Value, set.Key);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var set in imageDefinitions)
|
foreach (KeyValuePair<int, TextureDefinition[]> set in imageDefinitions)
|
||||||
{
|
{
|
||||||
DeclareImages(context, set.Value, set.Key, fsi);
|
DeclareImages(context, set.Value, set.Key, fsi);
|
||||||
}
|
}
|
||||||
@ -186,8 +186,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
|||||||
|
|
||||||
public static string GetVarTypeName(AggregateType type, bool atomic = false)
|
public static string GetVarTypeName(AggregateType type, bool atomic = false)
|
||||||
{
|
{
|
||||||
var s32 = atomic ? "atomic_int" : "int";
|
string s32 = atomic ? "atomic_int" : "int";
|
||||||
var u32 = atomic ? "atomic_uint" : "uint";
|
string u32 = atomic ? "atomic_uint" : "uint";
|
||||||
|
|
||||||
return type switch
|
return type switch
|
||||||
{
|
{
|
||||||
@ -216,22 +216,22 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
|||||||
{
|
{
|
||||||
string prefix = isShared ? "threadgroup " : string.Empty;
|
string prefix = isShared ? "threadgroup " : string.Empty;
|
||||||
|
|
||||||
foreach (var memory in memories)
|
foreach (MemoryDefinition memory in memories)
|
||||||
{
|
{
|
||||||
string arraySize = "";
|
string arraySize = "";
|
||||||
if ((memory.Type & AggregateType.Array) != 0)
|
if ((memory.Type & AggregateType.Array) != 0)
|
||||||
{
|
{
|
||||||
arraySize = $"[{memory.ArrayLength}]";
|
arraySize = $"[{memory.ArrayLength}]";
|
||||||
}
|
}
|
||||||
var typeName = GetVarTypeName(memory.Type & ~AggregateType.Array);
|
string typeName = GetVarTypeName(memory.Type & ~AggregateType.Array);
|
||||||
context.AppendLine($"{prefix}{typeName} {memory.Name}{arraySize};");
|
context.AppendLine($"{prefix}{typeName} {memory.Name}{arraySize};");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void DeclareBufferStructures(CodeGenContext context, BufferDefinition[] buffers, bool constant, bool fsi)
|
private static void DeclareBufferStructures(CodeGenContext context, BufferDefinition[] buffers, bool constant, bool fsi)
|
||||||
{
|
{
|
||||||
var name = constant ? "ConstantBuffers" : "StorageBuffers";
|
string name = constant ? "ConstantBuffers" : "StorageBuffers";
|
||||||
var addressSpace = constant ? "constant" : "device";
|
string addressSpace = constant ? "constant" : "device";
|
||||||
|
|
||||||
string[] bufferDec = new string[buffers.Length];
|
string[] bufferDec = new string[buffers.Length];
|
||||||
|
|
||||||
@ -239,7 +239,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
|||||||
{
|
{
|
||||||
BufferDefinition buffer = buffers[i];
|
BufferDefinition buffer = buffers[i];
|
||||||
|
|
||||||
var needsPadding = buffer.Layout == BufferLayout.Std140;
|
bool needsPadding = buffer.Layout == BufferLayout.Std140;
|
||||||
string fsiSuffix = !constant && fsi ? " [[raster_order_group(0)]]" : "";
|
string fsiSuffix = !constant && fsi ? " [[raster_order_group(0)]]" : "";
|
||||||
|
|
||||||
bufferDec[i] = $"{addressSpace} {Defaults.StructPrefix}_{buffer.Name}* {buffer.Name}{fsiSuffix};";
|
bufferDec[i] = $"{addressSpace} {Defaults.StructPrefix}_{buffer.Name}* {buffer.Name}{fsiSuffix};";
|
||||||
@ -249,7 +249,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
|||||||
|
|
||||||
foreach (StructureField field in buffer.Type.Fields)
|
foreach (StructureField field in buffer.Type.Fields)
|
||||||
{
|
{
|
||||||
var type = field.Type;
|
AggregateType type = field.Type;
|
||||||
type |= (needsPadding && (field.Type & AggregateType.Array) != 0)
|
type |= (needsPadding && (field.Type & AggregateType.Array) != 0)
|
||||||
? AggregateType.Vector4
|
? AggregateType.Vector4
|
||||||
: AggregateType.Invalid;
|
: AggregateType.Invalid;
|
||||||
@ -282,7 +282,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
|||||||
context.AppendLine($"struct {name}");
|
context.AppendLine($"struct {name}");
|
||||||
context.EnterScope();
|
context.EnterScope();
|
||||||
|
|
||||||
foreach (var declaration in bufferDec)
|
foreach (string declaration in bufferDec)
|
||||||
{
|
{
|
||||||
context.AppendLine(declaration);
|
context.AppendLine(declaration);
|
||||||
}
|
}
|
||||||
@ -293,7 +293,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
|||||||
|
|
||||||
private static void DeclareTextures(CodeGenContext context, TextureDefinition[] textures, int set)
|
private static void DeclareTextures(CodeGenContext context, TextureDefinition[] textures, int set)
|
||||||
{
|
{
|
||||||
var setName = GetNameForSet(set);
|
string setName = GetNameForSet(set);
|
||||||
context.AppendLine($"struct {setName}");
|
context.AppendLine($"struct {setName}");
|
||||||
context.EnterScope();
|
context.EnterScope();
|
||||||
|
|
||||||
@ -303,7 +303,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
|||||||
{
|
{
|
||||||
if (texture.Type != SamplerType.None)
|
if (texture.Type != SamplerType.None)
|
||||||
{
|
{
|
||||||
var textureTypeName = texture.Type.ToMslTextureType(texture.Format.GetComponentType());
|
string textureTypeName = texture.Type.ToMslTextureType(texture.Format.GetComponentType());
|
||||||
|
|
||||||
if (texture.ArrayLength > 1)
|
if (texture.ArrayLength > 1)
|
||||||
{
|
{
|
||||||
@ -315,7 +315,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
|||||||
|
|
||||||
if (!texture.Separate && texture.Type != SamplerType.TextureBuffer)
|
if (!texture.Separate && texture.Type != SamplerType.TextureBuffer)
|
||||||
{
|
{
|
||||||
var samplerType = "sampler";
|
string samplerType = "sampler";
|
||||||
|
|
||||||
if (texture.ArrayLength > 1)
|
if (texture.ArrayLength > 1)
|
||||||
{
|
{
|
||||||
@ -326,7 +326,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var declaration in textureDec)
|
foreach (string declaration in textureDec)
|
||||||
{
|
{
|
||||||
context.AppendLine(declaration);
|
context.AppendLine(declaration);
|
||||||
}
|
}
|
||||||
@ -337,7 +337,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
|||||||
|
|
||||||
private static void DeclareImages(CodeGenContext context, TextureDefinition[] images, int set, bool fsi)
|
private static void DeclareImages(CodeGenContext context, TextureDefinition[] images, int set, bool fsi)
|
||||||
{
|
{
|
||||||
var setName = GetNameForSet(set);
|
string setName = GetNameForSet(set);
|
||||||
context.AppendLine($"struct {setName}");
|
context.AppendLine($"struct {setName}");
|
||||||
context.EnterScope();
|
context.EnterScope();
|
||||||
|
|
||||||
@ -347,7 +347,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
|||||||
{
|
{
|
||||||
TextureDefinition image = images[i];
|
TextureDefinition image = images[i];
|
||||||
|
|
||||||
var imageTypeName = image.Type.ToMslTextureType(image.Format.GetComponentType(), true);
|
string imageTypeName = image.Type.ToMslTextureType(image.Format.GetComponentType(), true);
|
||||||
if (image.ArrayLength > 1)
|
if (image.ArrayLength > 1)
|
||||||
{
|
{
|
||||||
imageTypeName = $"array<{imageTypeName}, {image.ArrayLength}>";
|
imageTypeName = $"array<{imageTypeName}, {image.ArrayLength}>";
|
||||||
@ -358,7 +358,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
|||||||
imageDec[i] = $"{imageTypeName} {image.Name}{fsiSuffix};";
|
imageDec[i] = $"{imageTypeName} {image.Name}{fsiSuffix};";
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var declaration in imageDec)
|
foreach (string declaration in imageDec)
|
||||||
{
|
{
|
||||||
context.AppendLine(declaration);
|
context.AppendLine(declaration);
|
||||||
}
|
}
|
||||||
@ -401,14 +401,14 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
|||||||
// We need to use the SPIRV-Cross workaround
|
// We need to use the SPIRV-Cross workaround
|
||||||
for (int i = 0; i < Constants.MaxAttributes; i++)
|
for (int i = 0; i < Constants.MaxAttributes; i++)
|
||||||
{
|
{
|
||||||
var suffix = context.Definitions.Stage == ShaderStage.Fragment ? $"[[user(loc{i})]]" : $"[[attribute({i})]]";
|
string suffix = context.Definitions.Stage == ShaderStage.Fragment ? $"[[user(loc{i})]]" : $"[[attribute({i})]]";
|
||||||
context.AppendLine($"float4 {Defaults.IAttributePrefix}{i} {suffix};");
|
context.AppendLine($"float4 {Defaults.IAttributePrefix}{i} {suffix};");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inputs.Any())
|
if (inputs.Any())
|
||||||
{
|
{
|
||||||
foreach (var ioDefinition in inputs.OrderBy(x => x.Location))
|
foreach (IoDefinition ioDefinition in inputs.OrderBy(x => x.Location))
|
||||||
{
|
{
|
||||||
if (context.Definitions.IaIndexing && ioDefinition.IoVariable == IoVariable.UserDefined)
|
if (context.Definitions.IaIndexing && ioDefinition.IoVariable == IoVariable.UserDefined)
|
||||||
{
|
{
|
||||||
@ -500,11 +500,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
|||||||
IoDefinition firstOutput = outputs.ElementAtOrDefault(0);
|
IoDefinition firstOutput = outputs.ElementAtOrDefault(0);
|
||||||
IoDefinition secondOutput = outputs.ElementAtOrDefault(1);
|
IoDefinition secondOutput = outputs.ElementAtOrDefault(1);
|
||||||
|
|
||||||
var type1 = GetVarTypeName(context.Definitions.GetFragmentOutputColorType(firstOutput.Location));
|
string type1 = GetVarTypeName(context.Definitions.GetFragmentOutputColorType(firstOutput.Location));
|
||||||
var type2 = GetVarTypeName(context.Definitions.GetFragmentOutputColorType(secondOutput.Location));
|
string type2 = GetVarTypeName(context.Definitions.GetFragmentOutputColorType(secondOutput.Location));
|
||||||
|
|
||||||
var name1 = $"color{firstOutput.Location}";
|
string name1 = $"color{firstOutput.Location}";
|
||||||
var name2 = $"color{firstOutput.Location + 1}";
|
string name2 = $"color{firstOutput.Location + 1}";
|
||||||
|
|
||||||
context.AppendLine($"{type1} {name1} [[color({firstOutput.Location}), index(0)]];");
|
context.AppendLine($"{type1} {name1} [[color({firstOutput.Location}), index(0)]];");
|
||||||
context.AppendLine($"{type2} {name2} [[color({firstOutput.Location}), index(1)]];");
|
context.AppendLine($"{type2} {name2} [[color({firstOutput.Location}), index(1)]];");
|
||||||
@ -512,7 +512,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
|||||||
outputs = outputs.Skip(2);
|
outputs = outputs.Skip(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var ioDefinition in outputs)
|
foreach (IoDefinition ioDefinition in outputs)
|
||||||
{
|
{
|
||||||
if (context.Definitions.OaIndexing && ioDefinition.IoVariable == IoVariable.UserDefined)
|
if (context.Definitions.OaIndexing && ioDefinition.IoVariable == IoVariable.UserDefined)
|
||||||
{
|
{
|
||||||
|
@ -49,7 +49,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions
|
|||||||
? AggregateType.S32
|
? AggregateType.S32
|
||||||
: AggregateType.U32;
|
: AggregateType.U32;
|
||||||
|
|
||||||
var shared = operation.StorageKind == StorageKind.SharedMemory;
|
bool shared = operation.StorageKind == StorageKind.SharedMemory;
|
||||||
|
|
||||||
builder.Append($"({(shared ? "threadgroup" : "device")} {Declarations.GetVarTypeName(dstType, true)}*)&{GenerateLoadOrStore(context, operation, isStore: false)}");
|
builder.Append($"({(shared ? "threadgroup" : "device")} {Declarations.GetVarTypeName(dstType, true)}*)&{GenerateLoadOrStore(context, operation, isStore: false)}");
|
||||||
|
|
||||||
@ -120,7 +120,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions
|
|||||||
case 2:
|
case 2:
|
||||||
if (operation.ForcePrecise)
|
if (operation.ForcePrecise)
|
||||||
{
|
{
|
||||||
var func = (inst & Instruction.Mask) switch
|
string func = (inst & Instruction.Mask) switch
|
||||||
{
|
{
|
||||||
Instruction.Add => "PreciseFAdd",
|
Instruction.Add => "PreciseFAdd",
|
||||||
Instruction.Subtract => "PreciseFSub",
|
Instruction.Subtract => "PreciseFSub",
|
||||||
|
@ -7,7 +7,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions
|
|||||||
{
|
{
|
||||||
public static string Barrier(CodeGenContext context, AstOperation operation)
|
public static string Barrier(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var device = (operation.Inst & Instruction.Mask) == Instruction.MemoryBarrier;
|
bool device = (operation.Inst & Instruction.Mask) == Instruction.MemoryBarrier;
|
||||||
|
|
||||||
return $"threadgroup_barrier(mem_flags::mem_{(device ? "device" : "threadgroup")})";
|
return $"threadgroup_barrier(mem_flags::mem_{(device ? "device" : "threadgroup")})";
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions
|
|||||||
{
|
{
|
||||||
AstOperand funcId = (AstOperand)operation.GetSource(0);
|
AstOperand funcId = (AstOperand)operation.GetSource(0);
|
||||||
|
|
||||||
var function = context.GetFunction(funcId.Value);
|
StructuredFunction function = context.GetFunction(funcId.Value);
|
||||||
|
|
||||||
int argCount = operation.SourcesCount - 1;
|
int argCount = operation.SourcesCount - 1;
|
||||||
int additionalArgCount = CodeGenContext.AdditionalArgCount + (context.Definitions.Stage != ShaderStage.Compute ? 1 : 0);
|
int additionalArgCount = CodeGenContext.AdditionalArgCount + (context.Definitions.Stage != ShaderStage.Compute ? 1 : 0);
|
||||||
|
@ -157,7 +157,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions
|
|||||||
|
|
||||||
bool isArray = (texOp.Type & SamplerType.Array) != 0;
|
bool isArray = (texOp.Type & SamplerType.Array) != 0;
|
||||||
|
|
||||||
var texCallBuilder = new StringBuilder();
|
StringBuilder texCallBuilder = new StringBuilder();
|
||||||
|
|
||||||
int srcIndex = 0;
|
int srcIndex = 0;
|
||||||
|
|
||||||
@ -194,7 +194,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions
|
|||||||
|
|
||||||
texCallBuilder.Append('(');
|
texCallBuilder.Append('(');
|
||||||
|
|
||||||
var coordsBuilder = new StringBuilder();
|
StringBuilder coordsBuilder = new StringBuilder();
|
||||||
|
|
||||||
int coordsCount = texOp.Type.GetDimensions();
|
int coordsCount = texOp.Type.GetDimensions();
|
||||||
|
|
||||||
@ -326,8 +326,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions
|
|||||||
coordsExpr = GetSourceExpr(context, texOp.GetSource(coordsIndex), AggregateType.FP32);
|
coordsExpr = GetSourceExpr(context, texOp.GetSource(coordsIndex), AggregateType.FP32);
|
||||||
}
|
}
|
||||||
|
|
||||||
var clamped = $"{textureName}.calculate_clamped_lod({samplerName}, {coordsExpr})";
|
string clamped = $"{textureName}.calculate_clamped_lod({samplerName}, {coordsExpr})";
|
||||||
var unclamped = $"{textureName}.calculate_unclamped_lod({samplerName}, {coordsExpr})";
|
string unclamped = $"{textureName}.calculate_unclamped_lod({samplerName}, {coordsExpr})";
|
||||||
|
|
||||||
return $"float2({clamped}, {unclamped}){GetMask(texOp.Index)}";
|
return $"float2({clamped}, {unclamped}){GetMask(texOp.Index)}";
|
||||||
}
|
}
|
||||||
@ -352,7 +352,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions
|
|||||||
bool isArray = (texOp.Type & SamplerType.Array) != 0;
|
bool isArray = (texOp.Type & SamplerType.Array) != 0;
|
||||||
bool isShadow = (texOp.Type & SamplerType.Shadow) != 0;
|
bool isShadow = (texOp.Type & SamplerType.Shadow) != 0;
|
||||||
|
|
||||||
var texCallBuilder = new StringBuilder();
|
StringBuilder texCallBuilder = new StringBuilder();
|
||||||
|
|
||||||
bool colorIsVector = isGather || !isShadow;
|
bool colorIsVector = isGather || !isShadow;
|
||||||
|
|
||||||
@ -525,8 +525,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions
|
|||||||
|
|
||||||
private static string GetSamplerName(CodeGenContext context, AstTextureOperation texOp, ref int srcIndex)
|
private static string GetSamplerName(CodeGenContext context, AstTextureOperation texOp, ref int srcIndex)
|
||||||
{
|
{
|
||||||
var index = texOp.IsSeparate ? texOp.GetSamplerSetAndBinding() : texOp.GetTextureSetAndBinding();
|
SetBindingPair index = texOp.IsSeparate ? texOp.GetSamplerSetAndBinding() : texOp.GetTextureSetAndBinding();
|
||||||
var sourceIndex = texOp.IsSeparate ? srcIndex++ : srcIndex + 1;
|
int sourceIndex = texOp.IsSeparate ? srcIndex++ : srcIndex + 1;
|
||||||
|
|
||||||
TextureDefinition samplerDefinition = context.Properties.Textures[index];
|
TextureDefinition samplerDefinition = context.Properties.Textures[index];
|
||||||
string name = samplerDefinition.Name;
|
string name = samplerDefinition.Name;
|
||||||
@ -589,7 +589,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions
|
|||||||
{
|
{
|
||||||
AstTextureOperation texOp = (AstTextureOperation)operation;
|
AstTextureOperation texOp = (AstTextureOperation)operation;
|
||||||
|
|
||||||
var texCallBuilder = new StringBuilder();
|
StringBuilder texCallBuilder = new StringBuilder();
|
||||||
|
|
||||||
int srcIndex = 0;
|
int srcIndex = 0;
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions
|
|||||||
bool isOutput,
|
bool isOutput,
|
||||||
bool isPerPatch)
|
bool isPerPatch)
|
||||||
{
|
{
|
||||||
var returnValue = ioVariable switch
|
(string, AggregateType) returnValue = ioVariable switch
|
||||||
{
|
{
|
||||||
IoVariable.BaseInstance => ("base_instance", AggregateType.U32),
|
IoVariable.BaseInstance => ("base_instance", AggregateType.U32),
|
||||||
IoVariable.BaseVertex => ("base_vertex", AggregateType.U32),
|
IoVariable.BaseVertex => ("base_vertex", AggregateType.U32),
|
||||||
|
@ -20,7 +20,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
|||||||
|
|
||||||
CodeGenContext context = new(info, parameters);
|
CodeGenContext context = new(info, parameters);
|
||||||
|
|
||||||
var sets = Declarations.Declare(context, info);
|
int[] sets = Declarations.Declare(context, info);
|
||||||
|
|
||||||
if (info.Functions.Count != 0)
|
if (info.Functions.Count != 0)
|
||||||
{
|
{
|
||||||
@ -168,15 +168,15 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
|||||||
args = args.Append($"constant ConstantBuffers &constant_buffers [[buffer({Defaults.ConstantBuffersIndex})]]").ToArray();
|
args = args.Append($"constant ConstantBuffers &constant_buffers [[buffer({Defaults.ConstantBuffersIndex})]]").ToArray();
|
||||||
args = args.Append($"device StorageBuffers &storage_buffers [[buffer({Defaults.StorageBuffersIndex})]]").ToArray();
|
args = args.Append($"device StorageBuffers &storage_buffers [[buffer({Defaults.StorageBuffersIndex})]]").ToArray();
|
||||||
|
|
||||||
foreach (var set in sets)
|
foreach (int set in sets)
|
||||||
{
|
{
|
||||||
var bindingIndex = set + Defaults.BaseSetIndex;
|
long bindingIndex = set + Defaults.BaseSetIndex;
|
||||||
args = args.Append($"constant {Declarations.GetNameForSet(set)} &{Declarations.GetNameForSet(set, true)} [[buffer({bindingIndex})]]").ToArray();
|
args = args.Append($"constant {Declarations.GetNameForSet(set)} &{Declarations.GetNameForSet(set, true)} [[buffer({bindingIndex})]]").ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var funcPrefix = $"{funcKeyword} {returnType} {funcName ?? function.Name}(";
|
string funcPrefix = $"{funcKeyword} {returnType} {funcName ?? function.Name}(";
|
||||||
var indent = new string(' ', funcPrefix.Length);
|
string indent = new string(' ', funcPrefix.Length);
|
||||||
|
|
||||||
return $"{funcPrefix}{string.Join($", \n{indent}", args)})";
|
return $"{funcPrefix}{string.Join($", \n{indent}", args)})";
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
private BlockState GetBlockStateLazy(AstBlock block)
|
private BlockState GetBlockStateLazy(AstBlock block)
|
||||||
{
|
{
|
||||||
if (!_labels.TryGetValue(block, out var blockState))
|
if (!_labels.TryGetValue(block, out BlockState blockState))
|
||||||
{
|
{
|
||||||
blockState = new BlockState();
|
blockState = new BlockState();
|
||||||
|
|
||||||
@ -139,7 +139,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
public Instruction NewBlock()
|
public Instruction NewBlock()
|
||||||
{
|
{
|
||||||
var label = Label();
|
Instruction label = Label();
|
||||||
Branch(label);
|
Branch(label);
|
||||||
AddLabel(label);
|
AddLabel(label);
|
||||||
return label;
|
return label;
|
||||||
@ -147,7 +147,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
public Instruction[] GetMainInterface()
|
public Instruction[] GetMainInterface()
|
||||||
{
|
{
|
||||||
var mainInterface = new List<Instruction>();
|
List<Instruction> mainInterface = new List<Instruction>();
|
||||||
|
|
||||||
mainInterface.AddRange(Inputs.Values);
|
mainInterface.AddRange(Inputs.Values);
|
||||||
mainInterface.AddRange(Outputs.Values);
|
mainInterface.AddRange(Outputs.Values);
|
||||||
@ -196,7 +196,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
{
|
{
|
||||||
if (node is AstOperation operation)
|
if (node is AstOperation operation)
|
||||||
{
|
{
|
||||||
var opResult = Instructions.Generate(this, operation);
|
OperationResult opResult = Instructions.Generate(this, operation);
|
||||||
return BitcastIfNeeded(type, opResult.Type, opResult.Value);
|
return BitcastIfNeeded(type, opResult.Type, opResult.Value);
|
||||||
}
|
}
|
||||||
else if (node is AstOperand operand)
|
else if (node is AstOperand operand)
|
||||||
@ -218,7 +218,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
{
|
{
|
||||||
if (node is AstOperation operation)
|
if (node is AstOperation operation)
|
||||||
{
|
{
|
||||||
var opResult = Instructions.Generate(this, operation);
|
OperationResult opResult = Instructions.Generate(this, operation);
|
||||||
type = opResult.Type;
|
type = opResult.Type;
|
||||||
return opResult.Value;
|
return opResult.Value;
|
||||||
}
|
}
|
||||||
@ -273,13 +273,13 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
public Instruction GetLocal(AggregateType dstType, AstOperand local)
|
public Instruction GetLocal(AggregateType dstType, AstOperand local)
|
||||||
{
|
{
|
||||||
var srcType = local.VarType;
|
AggregateType srcType = local.VarType;
|
||||||
return BitcastIfNeeded(dstType, srcType, Load(GetType(srcType), GetLocalPointer(local)));
|
return BitcastIfNeeded(dstType, srcType, Load(GetType(srcType), GetLocalPointer(local)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Instruction GetArgument(AggregateType dstType, AstOperand funcArg)
|
public Instruction GetArgument(AggregateType dstType, AstOperand funcArg)
|
||||||
{
|
{
|
||||||
var srcType = funcArg.VarType;
|
AggregateType srcType = funcArg.VarType;
|
||||||
return BitcastIfNeeded(dstType, srcType, Load(GetType(srcType), GetArgumentPointer(funcArg)));
|
return BitcastIfNeeded(dstType, srcType, Load(GetType(srcType), GetArgumentPointer(funcArg)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,8 +339,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
}
|
}
|
||||||
else if (srcType == AggregateType.Bool)
|
else if (srcType == AggregateType.Bool)
|
||||||
{
|
{
|
||||||
var intTrue = Constant(TypeS32(), IrConsts.True);
|
Instruction intTrue = Constant(TypeS32(), IrConsts.True);
|
||||||
var intFalse = Constant(TypeS32(), IrConsts.False);
|
Instruction intFalse = Constant(TypeS32(), IrConsts.False);
|
||||||
|
|
||||||
return BitcastIfNeeded(dstType, AggregateType.S32, Select(TypeS32(), value, intTrue, intFalse));
|
return BitcastIfNeeded(dstType, AggregateType.S32, Select(TypeS32(), value, intTrue, intFalse));
|
||||||
}
|
}
|
||||||
|
@ -20,10 +20,10 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
private static void DeclareParameters(CodeGenContext context, IEnumerable<AggregateType> argTypes, int argIndex)
|
private static void DeclareParameters(CodeGenContext context, IEnumerable<AggregateType> argTypes, int argIndex)
|
||||||
{
|
{
|
||||||
foreach (var argType in argTypes)
|
foreach (AggregateType argType in argTypes)
|
||||||
{
|
{
|
||||||
var argPointerType = context.TypePointer(StorageClass.Function, context.GetType(argType));
|
SpvInstruction argPointerType = context.TypePointer(StorageClass.Function, context.GetType(argType));
|
||||||
var spvArg = context.FunctionParameter(argPointerType);
|
SpvInstruction spvArg = context.FunctionParameter(argPointerType);
|
||||||
|
|
||||||
context.DeclareArgument(argIndex++, spvArg);
|
context.DeclareArgument(argIndex++, spvArg);
|
||||||
}
|
}
|
||||||
@ -33,8 +33,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
{
|
{
|
||||||
foreach (AstOperand local in function.Locals)
|
foreach (AstOperand local in function.Locals)
|
||||||
{
|
{
|
||||||
var localPointerType = context.TypePointer(StorageClass.Function, context.GetType(local.VarType));
|
SpvInstruction localPointerType = context.TypePointer(StorageClass.Function, context.GetType(local.VarType));
|
||||||
var spvLocal = context.Variable(localPointerType, StorageClass.Function);
|
SpvInstruction spvLocal = context.Variable(localPointerType, StorageClass.Function);
|
||||||
|
|
||||||
context.AddLocalVariable(spvLocal);
|
context.AddLocalVariable(spvLocal);
|
||||||
context.DeclareLocal(local, spvLocal);
|
context.DeclareLocal(local, spvLocal);
|
||||||
@ -60,8 +60,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
{
|
{
|
||||||
foreach ((int id, MemoryDefinition memory) in memories)
|
foreach ((int id, MemoryDefinition memory) in memories)
|
||||||
{
|
{
|
||||||
var pointerType = context.TypePointer(storage, context.GetType(memory.Type, memory.ArrayLength));
|
SpvInstruction pointerType = context.TypePointer(storage, context.GetType(memory.Type, memory.ArrayLength));
|
||||||
var variable = context.Variable(pointerType, storage);
|
SpvInstruction variable = context.Variable(pointerType, storage);
|
||||||
|
|
||||||
context.AddGlobalVariable(variable);
|
context.AddGlobalVariable(variable);
|
||||||
|
|
||||||
@ -123,7 +123,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var structType = context.TypeStruct(false, structFieldTypes);
|
SpvInstruction structType = context.TypeStruct(false, structFieldTypes);
|
||||||
|
|
||||||
if (decoratedTypes.Add(structType))
|
if (decoratedTypes.Add(structType))
|
||||||
{
|
{
|
||||||
@ -135,8 +135,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var pointerType = context.TypePointer(StorageClass.Uniform, structType);
|
SpvInstruction pointerType = context.TypePointer(StorageClass.Uniform, structType);
|
||||||
var variable = context.Variable(pointerType, StorageClass.Uniform);
|
SpvInstruction variable = context.Variable(pointerType, StorageClass.Uniform);
|
||||||
|
|
||||||
context.Name(variable, buffer.Name);
|
context.Name(variable, buffer.Name);
|
||||||
context.Decorate(variable, Decoration.DescriptorSet, (LiteralInteger)setIndex);
|
context.Decorate(variable, Decoration.DescriptorSet, (LiteralInteger)setIndex);
|
||||||
@ -156,7 +156,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
private static void DeclareSamplers(CodeGenContext context, IEnumerable<TextureDefinition> samplers)
|
private static void DeclareSamplers(CodeGenContext context, IEnumerable<TextureDefinition> samplers)
|
||||||
{
|
{
|
||||||
foreach (var sampler in samplers)
|
foreach (TextureDefinition sampler in samplers)
|
||||||
{
|
{
|
||||||
int setIndex = context.TargetApi == TargetApi.Vulkan ? sampler.Set : 0;
|
int setIndex = context.TargetApi == TargetApi.Vulkan ? sampler.Set : 0;
|
||||||
|
|
||||||
@ -165,7 +165,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
if (sampler.Type != SamplerType.None)
|
if (sampler.Type != SamplerType.None)
|
||||||
{
|
{
|
||||||
var dim = (sampler.Type & SamplerType.Mask) switch
|
Dim dim = (sampler.Type & SamplerType.Mask) switch
|
||||||
{
|
{
|
||||||
SamplerType.Texture1D => Dim.Dim1D,
|
SamplerType.Texture1D => Dim.Dim1D,
|
||||||
SamplerType.Texture2D => Dim.Dim2D,
|
SamplerType.Texture2D => Dim.Dim2D,
|
||||||
@ -191,22 +191,22 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
imageType = sampledImageType = context.TypeSampler();
|
imageType = sampledImageType = context.TypeSampler();
|
||||||
}
|
}
|
||||||
|
|
||||||
var sampledOrSeparateImageType = sampler.Separate ? imageType : sampledImageType;
|
SpvInstruction sampledOrSeparateImageType = sampler.Separate ? imageType : sampledImageType;
|
||||||
var sampledImagePointerType = context.TypePointer(StorageClass.UniformConstant, sampledOrSeparateImageType);
|
SpvInstruction sampledImagePointerType = context.TypePointer(StorageClass.UniformConstant, sampledOrSeparateImageType);
|
||||||
var sampledImageArrayPointerType = sampledImagePointerType;
|
SpvInstruction sampledImageArrayPointerType = sampledImagePointerType;
|
||||||
|
|
||||||
if (sampler.ArrayLength == 0)
|
if (sampler.ArrayLength == 0)
|
||||||
{
|
{
|
||||||
var sampledImageArrayType = context.TypeRuntimeArray(sampledOrSeparateImageType);
|
SpvInstruction sampledImageArrayType = context.TypeRuntimeArray(sampledOrSeparateImageType);
|
||||||
sampledImageArrayPointerType = context.TypePointer(StorageClass.UniformConstant, sampledImageArrayType);
|
sampledImageArrayPointerType = context.TypePointer(StorageClass.UniformConstant, sampledImageArrayType);
|
||||||
}
|
}
|
||||||
else if (sampler.ArrayLength != 1)
|
else if (sampler.ArrayLength != 1)
|
||||||
{
|
{
|
||||||
var sampledImageArrayType = context.TypeArray(sampledOrSeparateImageType, context.Constant(context.TypeU32(), sampler.ArrayLength));
|
SpvInstruction sampledImageArrayType = context.TypeArray(sampledOrSeparateImageType, context.Constant(context.TypeU32(), sampler.ArrayLength));
|
||||||
sampledImageArrayPointerType = context.TypePointer(StorageClass.UniformConstant, sampledImageArrayType);
|
sampledImageArrayPointerType = context.TypePointer(StorageClass.UniformConstant, sampledImageArrayType);
|
||||||
}
|
}
|
||||||
|
|
||||||
var sampledImageVariable = context.Variable(sampledImageArrayPointerType, StorageClass.UniformConstant);
|
SpvInstruction sampledImageVariable = context.Variable(sampledImageArrayPointerType, StorageClass.UniformConstant);
|
||||||
|
|
||||||
context.Samplers.Add(new(sampler.Set, sampler.Binding), new SamplerDeclaration(
|
context.Samplers.Add(new(sampler.Set, sampler.Binding), new SamplerDeclaration(
|
||||||
imageType,
|
imageType,
|
||||||
@ -225,13 +225,13 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
private static void DeclareImages(CodeGenContext context, IEnumerable<TextureDefinition> images)
|
private static void DeclareImages(CodeGenContext context, IEnumerable<TextureDefinition> images)
|
||||||
{
|
{
|
||||||
foreach (var image in images)
|
foreach (TextureDefinition image in images)
|
||||||
{
|
{
|
||||||
int setIndex = context.TargetApi == TargetApi.Vulkan ? image.Set : 0;
|
int setIndex = context.TargetApi == TargetApi.Vulkan ? image.Set : 0;
|
||||||
|
|
||||||
var dim = GetDim(image.Type);
|
Dim dim = GetDim(image.Type);
|
||||||
|
|
||||||
var imageType = context.TypeImage(
|
SpvInstruction imageType = context.TypeImage(
|
||||||
context.GetType(image.Format.GetComponentType()),
|
context.GetType(image.Format.GetComponentType()),
|
||||||
dim,
|
dim,
|
||||||
image.Type.HasFlag(SamplerType.Shadow),
|
image.Type.HasFlag(SamplerType.Shadow),
|
||||||
@ -240,21 +240,21 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
AccessQualifier.ReadWrite,
|
AccessQualifier.ReadWrite,
|
||||||
GetImageFormat(image.Format));
|
GetImageFormat(image.Format));
|
||||||
|
|
||||||
var imagePointerType = context.TypePointer(StorageClass.UniformConstant, imageType);
|
SpvInstruction imagePointerType = context.TypePointer(StorageClass.UniformConstant, imageType);
|
||||||
var imageArrayPointerType = imagePointerType;
|
SpvInstruction imageArrayPointerType = imagePointerType;
|
||||||
|
|
||||||
if (image.ArrayLength == 0)
|
if (image.ArrayLength == 0)
|
||||||
{
|
{
|
||||||
var imageArrayType = context.TypeRuntimeArray(imageType);
|
SpvInstruction imageArrayType = context.TypeRuntimeArray(imageType);
|
||||||
imageArrayPointerType = context.TypePointer(StorageClass.UniformConstant, imageArrayType);
|
imageArrayPointerType = context.TypePointer(StorageClass.UniformConstant, imageArrayType);
|
||||||
}
|
}
|
||||||
else if (image.ArrayLength != 1)
|
else if (image.ArrayLength != 1)
|
||||||
{
|
{
|
||||||
var imageArrayType = context.TypeArray(imageType, context.Constant(context.TypeU32(), image.ArrayLength));
|
SpvInstruction imageArrayType = context.TypeArray(imageType, context.Constant(context.TypeU32(), image.ArrayLength));
|
||||||
imageArrayPointerType = context.TypePointer(StorageClass.UniformConstant, imageArrayType);
|
imageArrayPointerType = context.TypePointer(StorageClass.UniformConstant, imageArrayType);
|
||||||
}
|
}
|
||||||
|
|
||||||
var imageVariable = context.Variable(imageArrayPointerType, StorageClass.UniformConstant);
|
SpvInstruction imageVariable = context.Variable(imageArrayPointerType, StorageClass.UniformConstant);
|
||||||
|
|
||||||
context.Images.Add(new(image.Set, image.Binding), new ImageDeclaration(imageType, imagePointerType, imageVariable, image.ArrayLength != 1));
|
context.Images.Add(new(image.Set, image.Binding), new ImageDeclaration(imageType, imagePointerType, imageVariable, image.ArrayLength != 1));
|
||||||
|
|
||||||
@ -338,7 +338,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
if (context.Definitions.Stage == ShaderStage.Fragment && context.Definitions.DualSourceBlend)
|
if (context.Definitions.Stage == ShaderStage.Fragment && context.Definitions.DualSourceBlend)
|
||||||
{
|
{
|
||||||
foreach (var ioDefinition in info.IoDefinitions)
|
foreach (IoDefinition ioDefinition in info.IoDefinitions)
|
||||||
{
|
{
|
||||||
if (ioDefinition.IoVariable == IoVariable.FragmentOutputColor && ioDefinition.Location < firstLocation)
|
if (ioDefinition.IoVariable == IoVariable.FragmentOutputColor && ioDefinition.Location < firstLocation)
|
||||||
{
|
{
|
||||||
@ -347,13 +347,13 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var ioDefinition in info.IoDefinitions)
|
foreach (IoDefinition ioDefinition in info.IoDefinitions)
|
||||||
{
|
{
|
||||||
PixelImap iq = PixelImap.Unused;
|
PixelImap iq = PixelImap.Unused;
|
||||||
|
|
||||||
if (context.Definitions.Stage == ShaderStage.Fragment)
|
if (context.Definitions.Stage == ShaderStage.Fragment)
|
||||||
{
|
{
|
||||||
var ioVariable = ioDefinition.IoVariable;
|
IoVariable ioVariable = ioDefinition.IoVariable;
|
||||||
if (ioVariable == IoVariable.UserDefined)
|
if (ioVariable == IoVariable.UserDefined)
|
||||||
{
|
{
|
||||||
iq = context.Definitions.ImapTypes[ioDefinition.Location].GetFirstUsedType();
|
iq = context.Definitions.ImapTypes[ioDefinition.Location].GetFirstUsedType();
|
||||||
@ -389,11 +389,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
{
|
{
|
||||||
if (context.Definitions.Stage != ShaderStage.Vertex)
|
if (context.Definitions.Stage != ShaderStage.Vertex)
|
||||||
{
|
{
|
||||||
var perVertexInputStructType = CreatePerVertexStructType(context);
|
SpvInstruction perVertexInputStructType = CreatePerVertexStructType(context);
|
||||||
int arraySize = context.Definitions.Stage == ShaderStage.Geometry ? context.Definitions.InputTopology.ToInputVertices() : 32;
|
int arraySize = context.Definitions.Stage == ShaderStage.Geometry ? context.Definitions.InputTopology.ToInputVertices() : 32;
|
||||||
var perVertexInputArrayType = context.TypeArray(perVertexInputStructType, context.Constant(context.TypeU32(), arraySize));
|
SpvInstruction perVertexInputArrayType = context.TypeArray(perVertexInputStructType, context.Constant(context.TypeU32(), arraySize));
|
||||||
var perVertexInputPointerType = context.TypePointer(StorageClass.Input, perVertexInputArrayType);
|
SpvInstruction perVertexInputPointerType = context.TypePointer(StorageClass.Input, perVertexInputArrayType);
|
||||||
var perVertexInputVariable = context.Variable(perVertexInputPointerType, StorageClass.Input);
|
SpvInstruction perVertexInputVariable = context.Variable(perVertexInputPointerType, StorageClass.Input);
|
||||||
|
|
||||||
context.Name(perVertexInputVariable, "gl_in");
|
context.Name(perVertexInputVariable, "gl_in");
|
||||||
|
|
||||||
@ -411,11 +411,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var perVertexOutputStructType = CreatePerVertexStructType(context);
|
SpvInstruction perVertexOutputStructType = CreatePerVertexStructType(context);
|
||||||
|
|
||||||
void DecorateTfo(IoVariable ioVariable, int fieldIndex)
|
void DecorateTfo(IoVariable ioVariable, int fieldIndex)
|
||||||
{
|
{
|
||||||
if (context.Definitions.TryGetTransformFeedbackOutput(ioVariable, 0, 0, out var transformFeedbackOutput))
|
if (context.Definitions.TryGetTransformFeedbackOutput(ioVariable, 0, 0, out TransformFeedbackOutput transformFeedbackOutput))
|
||||||
{
|
{
|
||||||
context.MemberDecorate(perVertexOutputStructType, fieldIndex, Decoration.XfbBuffer, (LiteralInteger)transformFeedbackOutput.Buffer);
|
context.MemberDecorate(perVertexOutputStructType, fieldIndex, Decoration.XfbBuffer, (LiteralInteger)transformFeedbackOutput.Buffer);
|
||||||
context.MemberDecorate(perVertexOutputStructType, fieldIndex, Decoration.XfbStride, (LiteralInteger)transformFeedbackOutput.Stride);
|
context.MemberDecorate(perVertexOutputStructType, fieldIndex, Decoration.XfbStride, (LiteralInteger)transformFeedbackOutput.Stride);
|
||||||
@ -439,8 +439,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
perVertexOutputArrayType = perVertexOutputStructType;
|
perVertexOutputArrayType = perVertexOutputStructType;
|
||||||
}
|
}
|
||||||
|
|
||||||
var perVertexOutputPointerType = context.TypePointer(StorageClass.Output, perVertexOutputArrayType);
|
SpvInstruction perVertexOutputPointerType = context.TypePointer(StorageClass.Output, perVertexOutputArrayType);
|
||||||
var perVertexOutputVariable = context.Variable(perVertexOutputPointerType, StorageClass.Output);
|
SpvInstruction perVertexOutputVariable = context.Variable(perVertexOutputPointerType, StorageClass.Output);
|
||||||
|
|
||||||
context.AddGlobalVariable(perVertexOutputVariable);
|
context.AddGlobalVariable(perVertexOutputVariable);
|
||||||
context.Outputs.Add(new IoDefinition(StorageKind.Output, IoVariable.Position), perVertexOutputVariable);
|
context.Outputs.Add(new IoDefinition(StorageKind.Output, IoVariable.Position), perVertexOutputVariable);
|
||||||
@ -449,12 +449,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
private static SpvInstruction CreatePerVertexStructType(CodeGenContext context)
|
private static SpvInstruction CreatePerVertexStructType(CodeGenContext context)
|
||||||
{
|
{
|
||||||
var vec4FloatType = context.TypeVector(context.TypeFP32(), 4);
|
SpvInstruction vec4FloatType = context.TypeVector(context.TypeFP32(), 4);
|
||||||
var floatType = context.TypeFP32();
|
SpvInstruction floatType = context.TypeFP32();
|
||||||
var array8FloatType = context.TypeArray(context.TypeFP32(), context.Constant(context.TypeU32(), 8));
|
SpvInstruction array8FloatType = context.TypeArray(context.TypeFP32(), context.Constant(context.TypeU32(), 8));
|
||||||
var array1FloatType = context.TypeArray(context.TypeFP32(), context.Constant(context.TypeU32(), 1));
|
SpvInstruction array1FloatType = context.TypeArray(context.TypeFP32(), context.Constant(context.TypeU32(), 1));
|
||||||
|
|
||||||
var perVertexStructType = context.TypeStruct(true, vec4FloatType, floatType, array8FloatType, array1FloatType);
|
SpvInstruction perVertexStructType = context.TypeStruct(true, vec4FloatType, floatType, array8FloatType, array1FloatType);
|
||||||
|
|
||||||
context.Name(perVertexStructType, "gl_PerVertex");
|
context.Name(perVertexStructType, "gl_PerVertex");
|
||||||
|
|
||||||
@ -487,7 +487,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
int firstLocation = 0)
|
int firstLocation = 0)
|
||||||
{
|
{
|
||||||
IoVariable ioVariable = ioDefinition.IoVariable;
|
IoVariable ioVariable = ioDefinition.IoVariable;
|
||||||
var storageClass = isOutput ? StorageClass.Output : StorageClass.Input;
|
StorageClass storageClass = isOutput ? StorageClass.Output : StorageClass.Input;
|
||||||
|
|
||||||
bool isBuiltIn;
|
bool isBuiltIn;
|
||||||
BuiltIn builtIn = default;
|
BuiltIn builtIn = default;
|
||||||
@ -532,7 +532,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
var spvType = context.GetType(varType, IoMap.GetSpirvBuiltInArrayLength(ioVariable));
|
SpvInstruction spvType = context.GetType(varType, IoMap.GetSpirvBuiltInArrayLength(ioVariable));
|
||||||
bool builtInPassthrough = false;
|
bool builtInPassthrough = false;
|
||||||
|
|
||||||
if (!isPerPatch && IoMap.IsPerVertex(ioVariable, context.Definitions.Stage, isOutput))
|
if (!isPerPatch && IoMap.IsPerVertex(ioVariable, context.Definitions.Stage, isOutput))
|
||||||
@ -551,8 +551,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
spvType = context.TypeArray(spvType, context.Constant(context.TypeU32(), context.Definitions.ThreadsPerInputPrimitive));
|
spvType = context.TypeArray(spvType, context.Constant(context.TypeU32(), context.Definitions.ThreadsPerInputPrimitive));
|
||||||
}
|
}
|
||||||
|
|
||||||
var spvPointerType = context.TypePointer(storageClass, spvType);
|
SpvInstruction spvPointerType = context.TypePointer(storageClass, spvType);
|
||||||
var spvVar = context.Variable(spvPointerType, storageClass);
|
SpvInstruction spvVar = context.Variable(spvPointerType, storageClass);
|
||||||
|
|
||||||
if (builtInPassthrough)
|
if (builtInPassthrough)
|
||||||
{
|
{
|
||||||
@ -641,7 +641,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
ioVariable,
|
ioVariable,
|
||||||
ioDefinition.Location,
|
ioDefinition.Location,
|
||||||
ioDefinition.Component,
|
ioDefinition.Component,
|
||||||
out var transformFeedbackOutput))
|
out TransformFeedbackOutput transformFeedbackOutput))
|
||||||
{
|
{
|
||||||
context.Decorate(spvVar, Decoration.XfbBuffer, (LiteralInteger)transformFeedbackOutput.Buffer);
|
context.Decorate(spvVar, Decoration.XfbBuffer, (LiteralInteger)transformFeedbackOutput.Buffer);
|
||||||
context.Decorate(spvVar, Decoration.XfbStride, (LiteralInteger)transformFeedbackOutput.Stride);
|
context.Decorate(spvVar, Decoration.XfbStride, (LiteralInteger)transformFeedbackOutput.Stride);
|
||||||
@ -650,7 +650,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
context.AddGlobalVariable(spvVar);
|
context.AddGlobalVariable(spvVar);
|
||||||
|
|
||||||
var dict = isPerPatch
|
Dictionary<IoDefinition, SpvInstruction> dict = isPerPatch
|
||||||
? (isOutput ? context.OutputsPerPatch : context.InputsPerPatch)
|
? (isOutput ? context.OutputsPerPatch : context.InputsPerPatch)
|
||||||
: (isOutput ? context.Outputs : context.Inputs);
|
: (isOutput ? context.Outputs : context.Inputs);
|
||||||
dict.Add(ioDefinition, spvVar);
|
dict.Add(ioDefinition, spvVar);
|
||||||
|
@ -153,7 +153,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
public static OperationResult Generate(CodeGenContext context, AstOperation operation)
|
public static OperationResult Generate(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var handler = _instTable[(int)(operation.Inst & Instruction.Mask)];
|
Func<CodeGenContext, AstOperation, OperationResult> handler = _instTable[(int)(operation.Inst & Instruction.Mask)];
|
||||||
if (handler != null)
|
if (handler != null)
|
||||||
{
|
{
|
||||||
return handler(context, operation);
|
return handler(context, operation);
|
||||||
@ -226,13 +226,13 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
private static OperationResult GenerateBallot(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateBallot(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var source = operation.GetSource(0);
|
IAstNode source = operation.GetSource(0);
|
||||||
|
|
||||||
var uvec4Type = context.TypeVector(context.TypeU32(), 4);
|
SpvInstruction uvec4Type = context.TypeVector(context.TypeU32(), 4);
|
||||||
var execution = context.Constant(context.TypeU32(), Scope.Subgroup);
|
SpvInstruction execution = context.Constant(context.TypeU32(), Scope.Subgroup);
|
||||||
|
|
||||||
var maskVector = context.GroupNonUniformBallot(uvec4Type, execution, context.Get(AggregateType.Bool, source));
|
SpvInstruction maskVector = context.GroupNonUniformBallot(uvec4Type, execution, context.Get(AggregateType.Bool, source));
|
||||||
var mask = context.CompositeExtract(context.TypeU32(), maskVector, (SpvLiteralInteger)operation.Index);
|
SpvInstruction mask = context.CompositeExtract(context.TypeU32(), maskVector, (SpvLiteralInteger)operation.Index);
|
||||||
|
|
||||||
return new OperationResult(AggregateType.U32, mask);
|
return new OperationResult(AggregateType.U32, mask);
|
||||||
}
|
}
|
||||||
@ -308,21 +308,21 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
Debug.Assert(funcId.Type == OperandType.Constant);
|
Debug.Assert(funcId.Type == OperandType.Constant);
|
||||||
|
|
||||||
var (function, spvFunc) = context.GetFunction(funcId.Value);
|
(StructuredFunction function, SpvInstruction spvFunc) = context.GetFunction(funcId.Value);
|
||||||
|
|
||||||
var args = new SpvInstruction[operation.SourcesCount - 1];
|
SpvInstruction[] args = new SpvInstruction[operation.SourcesCount - 1];
|
||||||
|
|
||||||
for (int i = 0; i < args.Length; i++)
|
for (int i = 0; i < args.Length; i++)
|
||||||
{
|
{
|
||||||
var operand = operation.GetSource(i + 1);
|
IAstNode operand = operation.GetSource(i + 1);
|
||||||
|
|
||||||
AstOperand local = (AstOperand)operand;
|
AstOperand local = (AstOperand)operand;
|
||||||
Debug.Assert(local.Type == OperandType.LocalVariable);
|
Debug.Assert(local.Type == OperandType.LocalVariable);
|
||||||
args[i] = context.GetLocalPointer(local);
|
args[i] = context.GetLocalPointer(local);
|
||||||
}
|
}
|
||||||
|
|
||||||
var retType = function.ReturnType;
|
AggregateType retType = function.ReturnType;
|
||||||
var result = context.FunctionCall(context.GetType(retType), spvFunc, args);
|
SpvInstruction result = context.FunctionCall(context.GetType(retType), spvFunc, args);
|
||||||
return new OperationResult(retType, result);
|
return new OperationResult(retType, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -398,11 +398,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
private static OperationResult GenerateConditionalSelect(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateConditionalSelect(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var src1 = operation.GetSource(0);
|
IAstNode src1 = operation.GetSource(0);
|
||||||
var src2 = operation.GetSource(1);
|
IAstNode src2 = operation.GetSource(1);
|
||||||
var src3 = operation.GetSource(2);
|
IAstNode src3 = operation.GetSource(2);
|
||||||
|
|
||||||
var cond = context.Get(AggregateType.Bool, src1);
|
SpvInstruction cond = context.Get(AggregateType.Bool, src1);
|
||||||
|
|
||||||
if (operation.Inst.HasFlag(Instruction.FP64))
|
if (operation.Inst.HasFlag(Instruction.FP64))
|
||||||
{
|
{
|
||||||
@ -420,70 +420,70 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
private static OperationResult GenerateConvertFP32ToFP64(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateConvertFP32ToFP64(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var source = operation.GetSource(0);
|
IAstNode source = operation.GetSource(0);
|
||||||
|
|
||||||
return new OperationResult(AggregateType.FP64, context.FConvert(context.TypeFP64(), context.GetFP32(source)));
|
return new OperationResult(AggregateType.FP64, context.FConvert(context.TypeFP64(), context.GetFP32(source)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OperationResult GenerateConvertFP32ToS32(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateConvertFP32ToS32(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var source = operation.GetSource(0);
|
IAstNode source = operation.GetSource(0);
|
||||||
|
|
||||||
return new OperationResult(AggregateType.S32, context.ConvertFToS(context.TypeS32(), context.GetFP32(source)));
|
return new OperationResult(AggregateType.S32, context.ConvertFToS(context.TypeS32(), context.GetFP32(source)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OperationResult GenerateConvertFP32ToU32(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateConvertFP32ToU32(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var source = operation.GetSource(0);
|
IAstNode source = operation.GetSource(0);
|
||||||
|
|
||||||
return new OperationResult(AggregateType.U32, context.ConvertFToU(context.TypeU32(), context.GetFP32(source)));
|
return new OperationResult(AggregateType.U32, context.ConvertFToU(context.TypeU32(), context.GetFP32(source)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OperationResult GenerateConvertFP64ToFP32(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateConvertFP64ToFP32(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var source = operation.GetSource(0);
|
IAstNode source = operation.GetSource(0);
|
||||||
|
|
||||||
return new OperationResult(AggregateType.FP32, context.FConvert(context.TypeFP32(), context.GetFP64(source)));
|
return new OperationResult(AggregateType.FP32, context.FConvert(context.TypeFP32(), context.GetFP64(source)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OperationResult GenerateConvertFP64ToS32(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateConvertFP64ToS32(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var source = operation.GetSource(0);
|
IAstNode source = operation.GetSource(0);
|
||||||
|
|
||||||
return new OperationResult(AggregateType.S32, context.ConvertFToS(context.TypeS32(), context.GetFP64(source)));
|
return new OperationResult(AggregateType.S32, context.ConvertFToS(context.TypeS32(), context.GetFP64(source)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OperationResult GenerateConvertFP64ToU32(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateConvertFP64ToU32(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var source = operation.GetSource(0);
|
IAstNode source = operation.GetSource(0);
|
||||||
|
|
||||||
return new OperationResult(AggregateType.U32, context.ConvertFToU(context.TypeU32(), context.GetFP64(source)));
|
return new OperationResult(AggregateType.U32, context.ConvertFToU(context.TypeU32(), context.GetFP64(source)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OperationResult GenerateConvertS32ToFP32(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateConvertS32ToFP32(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var source = operation.GetSource(0);
|
IAstNode source = operation.GetSource(0);
|
||||||
|
|
||||||
return new OperationResult(AggregateType.FP32, context.ConvertSToF(context.TypeFP32(), context.GetS32(source)));
|
return new OperationResult(AggregateType.FP32, context.ConvertSToF(context.TypeFP32(), context.GetS32(source)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OperationResult GenerateConvertS32ToFP64(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateConvertS32ToFP64(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var source = operation.GetSource(0);
|
IAstNode source = operation.GetSource(0);
|
||||||
|
|
||||||
return new OperationResult(AggregateType.FP64, context.ConvertSToF(context.TypeFP64(), context.GetS32(source)));
|
return new OperationResult(AggregateType.FP64, context.ConvertSToF(context.TypeFP64(), context.GetS32(source)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OperationResult GenerateConvertU32ToFP32(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateConvertU32ToFP32(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var source = operation.GetSource(0);
|
IAstNode source = operation.GetSource(0);
|
||||||
|
|
||||||
return new OperationResult(AggregateType.FP32, context.ConvertUToF(context.TypeFP32(), context.GetU32(source)));
|
return new OperationResult(AggregateType.FP32, context.ConvertUToF(context.TypeFP32(), context.GetU32(source)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OperationResult GenerateConvertU32ToFP64(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateConvertU32ToFP64(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var source = operation.GetSource(0);
|
IAstNode source = operation.GetSource(0);
|
||||||
|
|
||||||
return new OperationResult(AggregateType.FP64, context.ConvertUToF(context.TypeFP64(), context.GetU32(source)));
|
return new OperationResult(AggregateType.FP64, context.ConvertUToF(context.TypeFP64(), context.GetU32(source)));
|
||||||
}
|
}
|
||||||
@ -555,19 +555,19 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
private static OperationResult GenerateFindLSB(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateFindLSB(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var source = context.GetU32(operation.GetSource(0));
|
SpvInstruction source = context.GetU32(operation.GetSource(0));
|
||||||
return new OperationResult(AggregateType.U32, context.GlslFindILsb(context.TypeU32(), source));
|
return new OperationResult(AggregateType.U32, context.GlslFindILsb(context.TypeU32(), source));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OperationResult GenerateFindMSBS32(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateFindMSBS32(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var source = context.GetS32(operation.GetSource(0));
|
SpvInstruction source = context.GetS32(operation.GetSource(0));
|
||||||
return new OperationResult(AggregateType.U32, context.GlslFindSMsb(context.TypeU32(), source));
|
return new OperationResult(AggregateType.U32, context.GlslFindSMsb(context.TypeU32(), source));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OperationResult GenerateFindMSBU32(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateFindMSBU32(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var source = context.GetU32(operation.GetSource(0));
|
SpvInstruction source = context.GetU32(operation.GetSource(0));
|
||||||
return new OperationResult(AggregateType.U32, context.GlslFindUMsb(context.TypeU32(), source));
|
return new OperationResult(AggregateType.U32, context.GlslFindUMsb(context.TypeU32(), source));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -591,7 +591,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
{
|
{
|
||||||
AstTextureOperation texOp = (AstTextureOperation)operation;
|
AstTextureOperation texOp = (AstTextureOperation)operation;
|
||||||
|
|
||||||
var componentType = texOp.Format.GetComponentType();
|
AggregateType componentType = texOp.Format.GetComponentType();
|
||||||
|
|
||||||
bool isArray = (texOp.Type & SamplerType.Array) != 0;
|
bool isArray = (texOp.Type & SamplerType.Array) != 0;
|
||||||
|
|
||||||
@ -630,7 +630,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
elems[i] = Src(AggregateType.S32);
|
elems[i] = Src(AggregateType.S32);
|
||||||
}
|
}
|
||||||
|
|
||||||
var vectorType = context.TypeVector(context.TypeS32(), pCount);
|
SpvInstruction vectorType = context.TypeVector(context.TypeS32(), pCount);
|
||||||
pCoords = context.CompositeConstruct(vectorType, elems);
|
pCoords = context.CompositeConstruct(vectorType, elems);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -640,11 +640,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
SpvInstruction value = Src(componentType);
|
SpvInstruction value = Src(componentType);
|
||||||
|
|
||||||
var pointer = context.ImageTexelPointer(imagePointerType, image, pCoords, context.Constant(context.TypeU32(), 0));
|
SpvInstruction pointer = context.ImageTexelPointer(imagePointerType, image, pCoords, context.Constant(context.TypeU32(), 0));
|
||||||
var one = context.Constant(context.TypeU32(), 1);
|
SpvInstruction one = context.Constant(context.TypeU32(), 1);
|
||||||
var zero = context.Constant(context.TypeU32(), 0);
|
SpvInstruction zero = context.Constant(context.TypeU32(), 0);
|
||||||
|
|
||||||
var result = (texOp.Flags & TextureFlags.AtomicMask) switch
|
SpvInstruction result = (texOp.Flags & TextureFlags.AtomicMask) switch
|
||||||
{
|
{
|
||||||
TextureFlags.Add => context.AtomicIAdd(resultType, pointer, one, zero, value),
|
TextureFlags.Add => context.AtomicIAdd(resultType, pointer, one, zero, value),
|
||||||
TextureFlags.Minimum => componentType == AggregateType.S32
|
TextureFlags.Minimum => componentType == AggregateType.S32
|
||||||
@ -670,7 +670,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
{
|
{
|
||||||
AstTextureOperation texOp = (AstTextureOperation)operation;
|
AstTextureOperation texOp = (AstTextureOperation)operation;
|
||||||
|
|
||||||
var componentType = texOp.Format.GetComponentType();
|
AggregateType componentType = texOp.Format.GetComponentType();
|
||||||
|
|
||||||
bool isArray = (texOp.Type & SamplerType.Array) != 0;
|
bool isArray = (texOp.Type & SamplerType.Array) != 0;
|
||||||
|
|
||||||
@ -708,7 +708,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
elems[i] = Src(AggregateType.S32);
|
elems[i] = Src(AggregateType.S32);
|
||||||
}
|
}
|
||||||
|
|
||||||
var vectorType = context.TypeVector(context.TypeS32(), pCount);
|
SpvInstruction vectorType = context.TypeVector(context.TypeS32(), pCount);
|
||||||
pCoords = context.CompositeConstruct(vectorType, elems);
|
pCoords = context.CompositeConstruct(vectorType, elems);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -716,11 +716,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
pCoords = Src(AggregateType.S32);
|
pCoords = Src(AggregateType.S32);
|
||||||
}
|
}
|
||||||
|
|
||||||
var imageComponentType = context.GetType(componentType);
|
SpvInstruction imageComponentType = context.GetType(componentType);
|
||||||
var swizzledResultType = texOp.GetVectorType(componentType);
|
AggregateType swizzledResultType = texOp.GetVectorType(componentType);
|
||||||
|
|
||||||
var texel = context.ImageRead(context.TypeVector(imageComponentType, 4), image, pCoords, ImageOperandsMask.MaskNone);
|
SpvInstruction texel = context.ImageRead(context.TypeVector(imageComponentType, 4), image, pCoords, ImageOperandsMask.MaskNone);
|
||||||
var result = GetSwizzledResult(context, texel, swizzledResultType, texOp.Index);
|
SpvInstruction result = GetSwizzledResult(context, texel, swizzledResultType, texOp.Index);
|
||||||
|
|
||||||
return new OperationResult(componentType, result);
|
return new OperationResult(componentType, result);
|
||||||
}
|
}
|
||||||
@ -765,7 +765,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
elems[i] = Src(AggregateType.S32);
|
elems[i] = Src(AggregateType.S32);
|
||||||
}
|
}
|
||||||
|
|
||||||
var vectorType = context.TypeVector(context.TypeS32(), pCount);
|
SpvInstruction vectorType = context.TypeVector(context.TypeS32(), pCount);
|
||||||
pCoords = context.CompositeConstruct(vectorType, elems);
|
pCoords = context.CompositeConstruct(vectorType, elems);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -773,7 +773,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
pCoords = Src(AggregateType.S32);
|
pCoords = Src(AggregateType.S32);
|
||||||
}
|
}
|
||||||
|
|
||||||
var componentType = texOp.Format.GetComponentType();
|
AggregateType componentType = texOp.Format.GetComponentType();
|
||||||
|
|
||||||
const int ComponentsCount = 4;
|
const int ComponentsCount = 4;
|
||||||
|
|
||||||
@ -796,7 +796,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var texel = context.CompositeConstruct(context.TypeVector(context.GetType(componentType), ComponentsCount), cElems);
|
SpvInstruction texel = context.CompositeConstruct(context.TypeVector(context.GetType(componentType), ComponentsCount), cElems);
|
||||||
|
|
||||||
context.ImageWrite(image, pCoords, texel, ImageOperandsMask.MaskNone);
|
context.ImageWrite(image, pCoords, texel, ImageOperandsMask.MaskNone);
|
||||||
|
|
||||||
@ -805,7 +805,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
private static OperationResult GenerateIsNan(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateIsNan(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var source = operation.GetSource(0);
|
IAstNode source = operation.GetSource(0);
|
||||||
|
|
||||||
SpvInstruction result;
|
SpvInstruction result;
|
||||||
|
|
||||||
@ -853,7 +853,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
elems[i] = Src(AggregateType.FP32);
|
elems[i] = Src(AggregateType.FP32);
|
||||||
}
|
}
|
||||||
|
|
||||||
var vectorType = context.TypeVector(context.TypeFP32(), pCount);
|
SpvInstruction vectorType = context.TypeVector(context.TypeFP32(), pCount);
|
||||||
pCoords = context.CompositeConstruct(vectorType, elems);
|
pCoords = context.CompositeConstruct(vectorType, elems);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -861,9 +861,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
pCoords = Src(AggregateType.FP32);
|
pCoords = Src(AggregateType.FP32);
|
||||||
}
|
}
|
||||||
|
|
||||||
var resultType = context.TypeVector(context.TypeFP32(), 2);
|
SpvInstruction resultType = context.TypeVector(context.TypeFP32(), 2);
|
||||||
var packed = context.ImageQueryLod(resultType, image, pCoords);
|
SpvInstruction packed = context.ImageQueryLod(resultType, image, pCoords);
|
||||||
var result = context.CompositeExtract(context.TypeFP32(), packed, (SpvLiteralInteger)texOp.Index);
|
SpvInstruction result = context.CompositeExtract(context.TypeFP32(), packed, (SpvLiteralInteger)texOp.Index);
|
||||||
|
|
||||||
return new OperationResult(AggregateType.FP32, result);
|
return new OperationResult(AggregateType.FP32, result);
|
||||||
}
|
}
|
||||||
@ -959,11 +959,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
private static OperationResult GenerateMultiplyHighS32(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateMultiplyHighS32(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var src1 = operation.GetSource(0);
|
IAstNode src1 = operation.GetSource(0);
|
||||||
var src2 = operation.GetSource(1);
|
IAstNode src2 = operation.GetSource(1);
|
||||||
|
|
||||||
var resultType = context.TypeStruct(false, context.TypeS32(), context.TypeS32());
|
SpvInstruction resultType = context.TypeStruct(false, context.TypeS32(), context.TypeS32());
|
||||||
var result = context.SMulExtended(resultType, context.GetS32(src1), context.GetS32(src2));
|
SpvInstruction result = context.SMulExtended(resultType, context.GetS32(src1), context.GetS32(src2));
|
||||||
result = context.CompositeExtract(context.TypeS32(), result, 1);
|
result = context.CompositeExtract(context.TypeS32(), result, 1);
|
||||||
|
|
||||||
return new OperationResult(AggregateType.S32, result);
|
return new OperationResult(AggregateType.S32, result);
|
||||||
@ -971,11 +971,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
private static OperationResult GenerateMultiplyHighU32(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateMultiplyHighU32(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var src1 = operation.GetSource(0);
|
IAstNode src1 = operation.GetSource(0);
|
||||||
var src2 = operation.GetSource(1);
|
IAstNode src2 = operation.GetSource(1);
|
||||||
|
|
||||||
var resultType = context.TypeStruct(false, context.TypeU32(), context.TypeU32());
|
SpvInstruction resultType = context.TypeStruct(false, context.TypeU32(), context.TypeU32());
|
||||||
var result = context.UMulExtended(resultType, context.GetU32(src1), context.GetU32(src2));
|
SpvInstruction result = context.UMulExtended(resultType, context.GetU32(src1), context.GetU32(src2));
|
||||||
result = context.CompositeExtract(context.TypeU32(), result, 1);
|
result = context.CompositeExtract(context.TypeU32(), result, 1);
|
||||||
|
|
||||||
return new OperationResult(AggregateType.U32, result);
|
return new OperationResult(AggregateType.U32, result);
|
||||||
@ -988,20 +988,20 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
private static OperationResult GeneratePackDouble2x32(CodeGenContext context, AstOperation operation)
|
private static OperationResult GeneratePackDouble2x32(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var value0 = context.GetU32(operation.GetSource(0));
|
SpvInstruction value0 = context.GetU32(operation.GetSource(0));
|
||||||
var value1 = context.GetU32(operation.GetSource(1));
|
SpvInstruction value1 = context.GetU32(operation.GetSource(1));
|
||||||
var vector = context.CompositeConstruct(context.TypeVector(context.TypeU32(), 2), value0, value1);
|
SpvInstruction vector = context.CompositeConstruct(context.TypeVector(context.TypeU32(), 2), value0, value1);
|
||||||
var result = context.GlslPackDouble2x32(context.TypeFP64(), vector);
|
SpvInstruction result = context.GlslPackDouble2x32(context.TypeFP64(), vector);
|
||||||
|
|
||||||
return new OperationResult(AggregateType.FP64, result);
|
return new OperationResult(AggregateType.FP64, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OperationResult GeneratePackHalf2x16(CodeGenContext context, AstOperation operation)
|
private static OperationResult GeneratePackHalf2x16(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var value0 = context.GetFP32(operation.GetSource(0));
|
SpvInstruction value0 = context.GetFP32(operation.GetSource(0));
|
||||||
var value1 = context.GetFP32(operation.GetSource(1));
|
SpvInstruction value1 = context.GetFP32(operation.GetSource(1));
|
||||||
var vector = context.CompositeConstruct(context.TypeVector(context.TypeFP32(), 2), value0, value1);
|
SpvInstruction vector = context.CompositeConstruct(context.TypeVector(context.TypeFP32(), 2), value0, value1);
|
||||||
var result = context.GlslPackHalf2x16(context.TypeU32(), vector);
|
SpvInstruction result = context.GlslPackHalf2x16(context.TypeU32(), vector);
|
||||||
|
|
||||||
return new OperationResult(AggregateType.U32, result);
|
return new OperationResult(AggregateType.U32, result);
|
||||||
}
|
}
|
||||||
@ -1049,40 +1049,40 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
private static OperationResult GenerateShuffle(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateShuffle(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var value = context.GetFP32(operation.GetSource(0));
|
SpvInstruction value = context.GetFP32(operation.GetSource(0));
|
||||||
var index = context.GetU32(operation.GetSource(1));
|
SpvInstruction index = context.GetU32(operation.GetSource(1));
|
||||||
|
|
||||||
var result = context.GroupNonUniformShuffle(context.TypeFP32(), context.Constant(context.TypeU32(), (int)Scope.Subgroup), value, index);
|
SpvInstruction result = context.GroupNonUniformShuffle(context.TypeFP32(), context.Constant(context.TypeU32(), (int)Scope.Subgroup), value, index);
|
||||||
|
|
||||||
return new OperationResult(AggregateType.FP32, result);
|
return new OperationResult(AggregateType.FP32, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OperationResult GenerateShuffleDown(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateShuffleDown(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var value = context.GetFP32(operation.GetSource(0));
|
SpvInstruction value = context.GetFP32(operation.GetSource(0));
|
||||||
var index = context.GetU32(operation.GetSource(1));
|
SpvInstruction index = context.GetU32(operation.GetSource(1));
|
||||||
|
|
||||||
var result = context.GroupNonUniformShuffleDown(context.TypeFP32(), context.Constant(context.TypeU32(), (int)Scope.Subgroup), value, index);
|
SpvInstruction result = context.GroupNonUniformShuffleDown(context.TypeFP32(), context.Constant(context.TypeU32(), (int)Scope.Subgroup), value, index);
|
||||||
|
|
||||||
return new OperationResult(AggregateType.FP32, result);
|
return new OperationResult(AggregateType.FP32, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OperationResult GenerateShuffleUp(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateShuffleUp(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var value = context.GetFP32(operation.GetSource(0));
|
SpvInstruction value = context.GetFP32(operation.GetSource(0));
|
||||||
var index = context.GetU32(operation.GetSource(1));
|
SpvInstruction index = context.GetU32(operation.GetSource(1));
|
||||||
|
|
||||||
var result = context.GroupNonUniformShuffleUp(context.TypeFP32(), context.Constant(context.TypeU32(), (int)Scope.Subgroup), value, index);
|
SpvInstruction result = context.GroupNonUniformShuffleUp(context.TypeFP32(), context.Constant(context.TypeU32(), (int)Scope.Subgroup), value, index);
|
||||||
|
|
||||||
return new OperationResult(AggregateType.FP32, result);
|
return new OperationResult(AggregateType.FP32, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OperationResult GenerateShuffleXor(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateShuffleXor(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var value = context.GetFP32(operation.GetSource(0));
|
SpvInstruction value = context.GetFP32(operation.GetSource(0));
|
||||||
var index = context.GetU32(operation.GetSource(1));
|
SpvInstruction index = context.GetU32(operation.GetSource(1));
|
||||||
|
|
||||||
var result = context.GroupNonUniformShuffleXor(context.TypeFP32(), context.Constant(context.TypeU32(), (int)Scope.Subgroup), value, index);
|
SpvInstruction result = context.GroupNonUniformShuffleXor(context.TypeFP32(), context.Constant(context.TypeU32(), (int)Scope.Subgroup), value, index);
|
||||||
|
|
||||||
return new OperationResult(AggregateType.FP32, result);
|
return new OperationResult(AggregateType.FP32, result);
|
||||||
}
|
}
|
||||||
@ -1109,31 +1109,31 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
private static OperationResult GenerateSwizzleAdd(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateSwizzleAdd(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var x = context.Get(AggregateType.FP32, operation.GetSource(0));
|
SpvInstruction x = context.Get(AggregateType.FP32, operation.GetSource(0));
|
||||||
var y = context.Get(AggregateType.FP32, operation.GetSource(1));
|
SpvInstruction y = context.Get(AggregateType.FP32, operation.GetSource(1));
|
||||||
var mask = context.Get(AggregateType.U32, operation.GetSource(2));
|
SpvInstruction mask = context.Get(AggregateType.U32, operation.GetSource(2));
|
||||||
|
|
||||||
var v4float = context.TypeVector(context.TypeFP32(), 4);
|
SpvInstruction v4float = context.TypeVector(context.TypeFP32(), 4);
|
||||||
var one = context.Constant(context.TypeFP32(), 1.0f);
|
SpvInstruction one = context.Constant(context.TypeFP32(), 1.0f);
|
||||||
var minusOne = context.Constant(context.TypeFP32(), -1.0f);
|
SpvInstruction minusOne = context.Constant(context.TypeFP32(), -1.0f);
|
||||||
var zero = context.Constant(context.TypeFP32(), 0.0f);
|
SpvInstruction zero = context.Constant(context.TypeFP32(), 0.0f);
|
||||||
var xLut = context.ConstantComposite(v4float, one, minusOne, one, zero);
|
SpvInstruction xLut = context.ConstantComposite(v4float, one, minusOne, one, zero);
|
||||||
var yLut = context.ConstantComposite(v4float, one, one, minusOne, one);
|
SpvInstruction yLut = context.ConstantComposite(v4float, one, one, minusOne, one);
|
||||||
|
|
||||||
var three = context.Constant(context.TypeU32(), 3);
|
SpvInstruction three = context.Constant(context.TypeU32(), 3);
|
||||||
|
|
||||||
var threadId = GetScalarInput(context, IoVariable.SubgroupLaneId);
|
SpvInstruction threadId = GetScalarInput(context, IoVariable.SubgroupLaneId);
|
||||||
var shift = context.BitwiseAnd(context.TypeU32(), threadId, three);
|
SpvInstruction shift = context.BitwiseAnd(context.TypeU32(), threadId, three);
|
||||||
shift = context.ShiftLeftLogical(context.TypeU32(), shift, context.Constant(context.TypeU32(), 1));
|
shift = context.ShiftLeftLogical(context.TypeU32(), shift, context.Constant(context.TypeU32(), 1));
|
||||||
var lutIdx = context.ShiftRightLogical(context.TypeU32(), mask, shift);
|
SpvInstruction lutIdx = context.ShiftRightLogical(context.TypeU32(), mask, shift);
|
||||||
lutIdx = context.BitwiseAnd(context.TypeU32(), lutIdx, three);
|
lutIdx = context.BitwiseAnd(context.TypeU32(), lutIdx, three);
|
||||||
|
|
||||||
var xLutValue = context.VectorExtractDynamic(context.TypeFP32(), xLut, lutIdx);
|
SpvInstruction xLutValue = context.VectorExtractDynamic(context.TypeFP32(), xLut, lutIdx);
|
||||||
var yLutValue = context.VectorExtractDynamic(context.TypeFP32(), yLut, lutIdx);
|
SpvInstruction yLutValue = context.VectorExtractDynamic(context.TypeFP32(), yLut, lutIdx);
|
||||||
|
|
||||||
var xResult = context.FMul(context.TypeFP32(), x, xLutValue);
|
SpvInstruction xResult = context.FMul(context.TypeFP32(), x, xLutValue);
|
||||||
var yResult = context.FMul(context.TypeFP32(), y, yLutValue);
|
SpvInstruction yResult = context.FMul(context.TypeFP32(), y, yLutValue);
|
||||||
var result = context.FAdd(context.TypeFP32(), xResult, yResult);
|
SpvInstruction result = context.FAdd(context.TypeFP32(), xResult, yResult);
|
||||||
|
|
||||||
return new OperationResult(AggregateType.FP32, result);
|
return new OperationResult(AggregateType.FP32, result);
|
||||||
}
|
}
|
||||||
@ -1200,7 +1200,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var vectorType = context.TypeVector(intCoords ? context.TypeS32() : context.TypeFP32(), count);
|
SpvInstruction vectorType = context.TypeVector(intCoords ? context.TypeS32() : context.TypeFP32(), count);
|
||||||
return context.CompositeConstruct(vectorType, elems);
|
return context.CompositeConstruct(vectorType, elems);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1222,7 +1222,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
elems[index] = Src(AggregateType.FP32);
|
elems[index] = Src(AggregateType.FP32);
|
||||||
}
|
}
|
||||||
|
|
||||||
var vectorType = context.TypeVector(context.TypeFP32(), count);
|
SpvInstruction vectorType = context.TypeVector(context.TypeFP32(), count);
|
||||||
return context.CompositeConstruct(vectorType, elems);
|
return context.CompositeConstruct(vectorType, elems);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1272,7 +1272,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
elems[index] = Src(AggregateType.S32);
|
elems[index] = Src(AggregateType.S32);
|
||||||
}
|
}
|
||||||
|
|
||||||
var vectorType = context.TypeVector(context.TypeS32(), count);
|
SpvInstruction vectorType = context.TypeVector(context.TypeS32(), count);
|
||||||
|
|
||||||
return context.ConstantComposite(vectorType, elems);
|
return context.ConstantComposite(vectorType, elems);
|
||||||
}
|
}
|
||||||
@ -1327,8 +1327,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
compIdx = Src(AggregateType.S32);
|
compIdx = Src(AggregateType.S32);
|
||||||
}
|
}
|
||||||
|
|
||||||
var operandsList = new List<SpvInstruction>();
|
List<SpvInstruction> operandsList = new List<SpvInstruction>();
|
||||||
var operandsMask = ImageOperandsMask.MaskNone;
|
ImageOperandsMask operandsMask = ImageOperandsMask.MaskNone;
|
||||||
|
|
||||||
if (hasLodBias)
|
if (hasLodBias)
|
||||||
{
|
{
|
||||||
@ -1369,14 +1369,14 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
bool colorIsVector = isGather || !isShadow;
|
bool colorIsVector = isGather || !isShadow;
|
||||||
|
|
||||||
var resultType = colorIsVector ? context.TypeVector(context.TypeFP32(), 4) : context.TypeFP32();
|
SpvInstruction resultType = colorIsVector ? context.TypeVector(context.TypeFP32(), 4) : context.TypeFP32();
|
||||||
|
|
||||||
if (intCoords)
|
if (intCoords)
|
||||||
{
|
{
|
||||||
image = context.Image(declaration.ImageType, image);
|
image = context.Image(declaration.ImageType, image);
|
||||||
}
|
}
|
||||||
|
|
||||||
var operands = operandsList.ToArray();
|
SpvInstruction[] operands = operandsList.ToArray();
|
||||||
|
|
||||||
SpvInstruction result;
|
SpvInstruction result;
|
||||||
|
|
||||||
@ -1415,7 +1415,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
result = context.ImageSampleImplicitLod(resultType, image, pCoords, operandsMask, operands);
|
result = context.ImageSampleImplicitLod(resultType, image, pCoords, operandsMask, operands);
|
||||||
}
|
}
|
||||||
|
|
||||||
var swizzledResultType = AggregateType.FP32;
|
AggregateType swizzledResultType = AggregateType.FP32;
|
||||||
|
|
||||||
if (colorIsVector)
|
if (colorIsVector)
|
||||||
{
|
{
|
||||||
@ -1460,7 +1460,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var type = context.SamplersTypes[texOp.GetTextureSetAndBinding()];
|
SamplerType type = context.SamplersTypes[texOp.GetTextureSetAndBinding()];
|
||||||
bool hasLod = !type.HasFlag(SamplerType.Multisample) && type != SamplerType.TextureBuffer;
|
bool hasLod = !type.HasFlag(SamplerType.Multisample) && type != SamplerType.TextureBuffer;
|
||||||
|
|
||||||
int dimensions = (type & SamplerType.Mask) == SamplerType.TextureCube ? 2 : type.GetDimensions();
|
int dimensions = (type & SamplerType.Mask) == SamplerType.TextureCube ? 2 : type.GetDimensions();
|
||||||
@ -1470,13 +1470,13 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
dimensions++;
|
dimensions++;
|
||||||
}
|
}
|
||||||
|
|
||||||
var resultType = dimensions == 1 ? context.TypeS32() : context.TypeVector(context.TypeS32(), dimensions);
|
SpvInstruction resultType = dimensions == 1 ? context.TypeS32() : context.TypeVector(context.TypeS32(), dimensions);
|
||||||
|
|
||||||
SpvInstruction result;
|
SpvInstruction result;
|
||||||
|
|
||||||
if (hasLod)
|
if (hasLod)
|
||||||
{
|
{
|
||||||
var lod = context.GetS32(operation.GetSource(srcIndex));
|
SpvInstruction lod = context.GetS32(operation.GetSource(srcIndex));
|
||||||
result = context.ImageQuerySizeLod(resultType, image, lod);
|
result = context.ImageQuerySizeLod(resultType, image, lod);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1500,27 +1500,27 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
private static OperationResult GenerateUnpackDouble2x32(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateUnpackDouble2x32(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var value = context.GetFP64(operation.GetSource(0));
|
SpvInstruction value = context.GetFP64(operation.GetSource(0));
|
||||||
var vector = context.GlslUnpackDouble2x32(context.TypeVector(context.TypeU32(), 2), value);
|
SpvInstruction vector = context.GlslUnpackDouble2x32(context.TypeVector(context.TypeU32(), 2), value);
|
||||||
var result = context.CompositeExtract(context.TypeU32(), vector, operation.Index);
|
SpvInstruction result = context.CompositeExtract(context.TypeU32(), vector, operation.Index);
|
||||||
|
|
||||||
return new OperationResult(AggregateType.U32, result);
|
return new OperationResult(AggregateType.U32, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OperationResult GenerateUnpackHalf2x16(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateUnpackHalf2x16(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var value = context.GetU32(operation.GetSource(0));
|
SpvInstruction value = context.GetU32(operation.GetSource(0));
|
||||||
var vector = context.GlslUnpackHalf2x16(context.TypeVector(context.TypeFP32(), 2), value);
|
SpvInstruction vector = context.GlslUnpackHalf2x16(context.TypeVector(context.TypeFP32(), 2), value);
|
||||||
var result = context.CompositeExtract(context.TypeFP32(), vector, operation.Index);
|
SpvInstruction result = context.CompositeExtract(context.TypeFP32(), vector, operation.Index);
|
||||||
|
|
||||||
return new OperationResult(AggregateType.FP32, result);
|
return new OperationResult(AggregateType.FP32, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OperationResult GenerateVectorExtract(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateVectorExtract(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var vector = context.GetWithType(operation.GetSource(0), out AggregateType vectorType);
|
SpvInstruction vector = context.GetWithType(operation.GetSource(0), out AggregateType vectorType);
|
||||||
var scalarType = vectorType & ~AggregateType.ElementCountMask;
|
AggregateType scalarType = vectorType & ~AggregateType.ElementCountMask;
|
||||||
var resultType = context.GetType(scalarType);
|
SpvInstruction resultType = context.GetType(scalarType);
|
||||||
SpvInstruction result;
|
SpvInstruction result;
|
||||||
|
|
||||||
if (operation.GetSource(1) is AstOperand indexOperand && indexOperand.Type == OperandType.Constant)
|
if (operation.GetSource(1) is AstOperand indexOperand && indexOperand.Type == OperandType.Constant)
|
||||||
@ -1529,7 +1529,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var index = context.Get(AggregateType.S32, operation.GetSource(1));
|
SpvInstruction index = context.Get(AggregateType.S32, operation.GetSource(1));
|
||||||
result = context.VectorExtractDynamic(resultType, vector, index);
|
result = context.VectorExtractDynamic(resultType, vector, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1538,22 +1538,22 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
private static OperationResult GenerateVoteAll(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateVoteAll(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var execution = context.Constant(context.TypeU32(), Scope.Subgroup);
|
SpvInstruction execution = context.Constant(context.TypeU32(), Scope.Subgroup);
|
||||||
var result = context.GroupNonUniformAll(context.TypeBool(), execution, context.Get(AggregateType.Bool, operation.GetSource(0)));
|
SpvInstruction result = context.GroupNonUniformAll(context.TypeBool(), execution, context.Get(AggregateType.Bool, operation.GetSource(0)));
|
||||||
return new OperationResult(AggregateType.Bool, result);
|
return new OperationResult(AggregateType.Bool, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OperationResult GenerateVoteAllEqual(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateVoteAllEqual(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var execution = context.Constant(context.TypeU32(), Scope.Subgroup);
|
SpvInstruction execution = context.Constant(context.TypeU32(), Scope.Subgroup);
|
||||||
var result = context.GroupNonUniformAllEqual(context.TypeBool(), execution, context.Get(AggregateType.Bool, operation.GetSource(0)));
|
SpvInstruction result = context.GroupNonUniformAllEqual(context.TypeBool(), execution, context.Get(AggregateType.Bool, operation.GetSource(0)));
|
||||||
return new OperationResult(AggregateType.Bool, result);
|
return new OperationResult(AggregateType.Bool, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OperationResult GenerateVoteAny(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateVoteAny(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var execution = context.Constant(context.TypeU32(), Scope.Subgroup);
|
SpvInstruction execution = context.Constant(context.TypeU32(), Scope.Subgroup);
|
||||||
var result = context.GroupNonUniformAny(context.TypeBool(), execution, context.Get(AggregateType.Bool, operation.GetSource(0)));
|
SpvInstruction result = context.GroupNonUniformAny(context.TypeBool(), execution, context.Get(AggregateType.Bool, operation.GetSource(0)));
|
||||||
return new OperationResult(AggregateType.Bool, result);
|
return new OperationResult(AggregateType.Bool, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1563,8 +1563,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
Func<SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction> emitF,
|
Func<SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction> emitF,
|
||||||
Func<SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction> emitI)
|
Func<SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction> emitI)
|
||||||
{
|
{
|
||||||
var src1 = operation.GetSource(0);
|
IAstNode src1 = operation.GetSource(0);
|
||||||
var src2 = operation.GetSource(1);
|
IAstNode src2 = operation.GetSource(1);
|
||||||
|
|
||||||
SpvInstruction result;
|
SpvInstruction result;
|
||||||
|
|
||||||
@ -1589,10 +1589,10 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
AstOperation operation,
|
AstOperation operation,
|
||||||
Func<SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction> emitU)
|
Func<SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction> emitU)
|
||||||
{
|
{
|
||||||
var src1 = operation.GetSource(0);
|
IAstNode src1 = operation.GetSource(0);
|
||||||
var src2 = operation.GetSource(1);
|
IAstNode src2 = operation.GetSource(1);
|
||||||
|
|
||||||
var result = emitU(context.TypeBool(), context.GetU32(src1), context.GetU32(src2));
|
SpvInstruction result = emitU(context.TypeBool(), context.GetU32(src1), context.GetU32(src2));
|
||||||
|
|
||||||
return new OperationResult(AggregateType.Bool, result);
|
return new OperationResult(AggregateType.Bool, result);
|
||||||
}
|
}
|
||||||
@ -1604,10 +1604,10 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
{
|
{
|
||||||
SpvInstruction elemPointer = GetStoragePointer(context, operation, out AggregateType varType);
|
SpvInstruction elemPointer = GetStoragePointer(context, operation, out AggregateType varType);
|
||||||
|
|
||||||
var value = context.Get(varType, operation.GetSource(operation.SourcesCount - 1));
|
SpvInstruction value = context.Get(varType, operation.GetSource(operation.SourcesCount - 1));
|
||||||
|
|
||||||
var one = context.Constant(context.TypeU32(), 1);
|
SpvInstruction one = context.Constant(context.TypeU32(), 1);
|
||||||
var zero = context.Constant(context.TypeU32(), 0);
|
SpvInstruction zero = context.Constant(context.TypeU32(), 0);
|
||||||
|
|
||||||
return new OperationResult(varType, emitU(context.GetType(varType), elemPointer, one, zero, value));
|
return new OperationResult(varType, emitU(context.GetType(varType), elemPointer, one, zero, value));
|
||||||
}
|
}
|
||||||
@ -1616,11 +1616,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
{
|
{
|
||||||
SpvInstruction elemPointer = GetStoragePointer(context, operation, out AggregateType varType);
|
SpvInstruction elemPointer = GetStoragePointer(context, operation, out AggregateType varType);
|
||||||
|
|
||||||
var value0 = context.Get(varType, operation.GetSource(operation.SourcesCount - 2));
|
SpvInstruction value0 = context.Get(varType, operation.GetSource(operation.SourcesCount - 2));
|
||||||
var value1 = context.Get(varType, operation.GetSource(operation.SourcesCount - 1));
|
SpvInstruction value1 = context.Get(varType, operation.GetSource(operation.SourcesCount - 1));
|
||||||
|
|
||||||
var one = context.Constant(context.TypeU32(), 1);
|
SpvInstruction one = context.Constant(context.TypeU32(), 1);
|
||||||
var zero = context.Constant(context.TypeU32(), 0);
|
SpvInstruction zero = context.Constant(context.TypeU32(), 0);
|
||||||
|
|
||||||
return new OperationResult(varType, context.AtomicCompareExchange(context.GetType(varType), elemPointer, one, zero, zero, value1, value0));
|
return new OperationResult(varType, context.AtomicCompareExchange(context.GetType(varType), elemPointer, one, zero, zero, value1, value0));
|
||||||
}
|
}
|
||||||
@ -1636,7 +1636,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var result = context.Load(context.GetType(varType), pointer);
|
SpvInstruction result = context.Load(context.GetType(varType), pointer);
|
||||||
return new OperationResult(varType, result);
|
return new OperationResult(varType, result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1754,8 +1754,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
storageClass = isOutput ? StorageClass.Output : StorageClass.Input;
|
storageClass = isOutput ? StorageClass.Output : StorageClass.Input;
|
||||||
|
|
||||||
var ioDefinition = new IoDefinition(storageKind, ioVariable, location, component);
|
IoDefinition ioDefinition = new IoDefinition(storageKind, ioVariable, location, component);
|
||||||
var dict = isPerPatch
|
Dictionary<IoDefinition, SpvInstruction> dict = isPerPatch
|
||||||
? (isOutput ? context.OutputsPerPatch : context.InputsPerPatch)
|
? (isOutput ? context.OutputsPerPatch : context.InputsPerPatch)
|
||||||
: (isOutput ? context.Outputs : context.Inputs);
|
: (isOutput ? context.Outputs : context.Inputs);
|
||||||
|
|
||||||
@ -1773,7 +1773,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
{
|
{
|
||||||
int fieldIndex = IoMap.GetPerVertexStructFieldIndex(perVertexBuiltIn.Value);
|
int fieldIndex = IoMap.GetPerVertexStructFieldIndex(perVertexBuiltIn.Value);
|
||||||
|
|
||||||
var indexes = new SpvInstruction[inputsCount + 1];
|
SpvInstruction[] indexes = new SpvInstruction[inputsCount + 1];
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
||||||
if (IoMap.IsPerVertexArrayBuiltIn(storageKind, context.Definitions.Stage))
|
if (IoMap.IsPerVertexArrayBuiltIn(storageKind, context.Definitions.Stage))
|
||||||
@ -1823,7 +1823,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
pointer = context.AccessChain(context.TypePointer(storageClass, context.GetType(varType)), baseObj, e0, e1, e2);
|
pointer = context.AccessChain(context.TypePointer(storageClass, context.GetType(varType)), baseObj, e0, e1, e2);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
var indexes = new SpvInstruction[inputsCount];
|
SpvInstruction[] indexes = new SpvInstruction[inputsCount];
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
||||||
for (; index < inputsCount; srcIndex++, index++)
|
for (; index < inputsCount; srcIndex++, index++)
|
||||||
@ -1840,10 +1840,10 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
private static SpvInstruction GetScalarInput(CodeGenContext context, IoVariable ioVariable)
|
private static SpvInstruction GetScalarInput(CodeGenContext context, IoVariable ioVariable)
|
||||||
{
|
{
|
||||||
var (_, varType) = IoMap.GetSpirvBuiltIn(ioVariable);
|
(_, AggregateType varType) = IoMap.GetSpirvBuiltIn(ioVariable);
|
||||||
varType &= AggregateType.ElementTypeMask;
|
varType &= AggregateType.ElementTypeMask;
|
||||||
|
|
||||||
var ioDefinition = new IoDefinition(StorageKind.Input, ioVariable);
|
IoDefinition ioDefinition = new IoDefinition(StorageKind.Input, ioVariable);
|
||||||
|
|
||||||
return context.Load(context.GetType(varType), context.Inputs[ioDefinition]);
|
return context.Load(context.GetType(varType), context.Inputs[ioDefinition]);
|
||||||
}
|
}
|
||||||
@ -1917,7 +1917,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
Func<SpvInstruction, SpvInstruction, SpvInstruction> emitF,
|
Func<SpvInstruction, SpvInstruction, SpvInstruction> emitF,
|
||||||
Func<SpvInstruction, SpvInstruction, SpvInstruction> emitI)
|
Func<SpvInstruction, SpvInstruction, SpvInstruction> emitI)
|
||||||
{
|
{
|
||||||
var source = operation.GetSource(0);
|
IAstNode source = operation.GetSource(0);
|
||||||
|
|
||||||
if (operation.Inst.HasFlag(Instruction.FP64))
|
if (operation.Inst.HasFlag(Instruction.FP64))
|
||||||
{
|
{
|
||||||
@ -1938,7 +1938,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
AstOperation operation,
|
AstOperation operation,
|
||||||
Func<SpvInstruction, SpvInstruction, SpvInstruction> emitB)
|
Func<SpvInstruction, SpvInstruction, SpvInstruction> emitB)
|
||||||
{
|
{
|
||||||
var source = operation.GetSource(0);
|
IAstNode source = operation.GetSource(0);
|
||||||
return new OperationResult(AggregateType.Bool, emitB(context.TypeBool(), context.Get(AggregateType.Bool, source)));
|
return new OperationResult(AggregateType.Bool, emitB(context.TypeBool(), context.Get(AggregateType.Bool, source)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1947,7 +1947,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
AstOperation operation,
|
AstOperation operation,
|
||||||
Func<SpvInstruction, SpvInstruction, SpvInstruction> emit)
|
Func<SpvInstruction, SpvInstruction, SpvInstruction> emit)
|
||||||
{
|
{
|
||||||
var source = operation.GetSource(0);
|
IAstNode source = operation.GetSource(0);
|
||||||
return new OperationResult(AggregateType.FP32, emit(context.TypeFP32(), context.GetFP32(source)));
|
return new OperationResult(AggregateType.FP32, emit(context.TypeFP32(), context.GetFP32(source)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1956,7 +1956,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
AstOperation operation,
|
AstOperation operation,
|
||||||
Func<SpvInstruction, SpvInstruction, SpvInstruction> emitS)
|
Func<SpvInstruction, SpvInstruction, SpvInstruction> emitS)
|
||||||
{
|
{
|
||||||
var source = operation.GetSource(0);
|
IAstNode source = operation.GetSource(0);
|
||||||
return new OperationResult(AggregateType.S32, emitS(context.TypeS32(), context.GetS32(source)));
|
return new OperationResult(AggregateType.S32, emitS(context.TypeS32(), context.GetS32(source)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1966,12 +1966,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
Func<SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction> emitF,
|
Func<SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction> emitF,
|
||||||
Func<SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction> emitI)
|
Func<SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction> emitI)
|
||||||
{
|
{
|
||||||
var src1 = operation.GetSource(0);
|
IAstNode src1 = operation.GetSource(0);
|
||||||
var src2 = operation.GetSource(1);
|
IAstNode src2 = operation.GetSource(1);
|
||||||
|
|
||||||
if (operation.Inst.HasFlag(Instruction.FP64))
|
if (operation.Inst.HasFlag(Instruction.FP64))
|
||||||
{
|
{
|
||||||
var result = emitF(context.TypeFP64(), context.GetFP64(src1), context.GetFP64(src2));
|
SpvInstruction result = emitF(context.TypeFP64(), context.GetFP64(src1), context.GetFP64(src2));
|
||||||
|
|
||||||
if (!context.HostCapabilities.ReducedPrecision || operation.ForcePrecise)
|
if (!context.HostCapabilities.ReducedPrecision || operation.ForcePrecise)
|
||||||
{
|
{
|
||||||
@ -1982,7 +1982,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
}
|
}
|
||||||
else if (operation.Inst.HasFlag(Instruction.FP32))
|
else if (operation.Inst.HasFlag(Instruction.FP32))
|
||||||
{
|
{
|
||||||
var result = emitF(context.TypeFP32(), context.GetFP32(src1), context.GetFP32(src2));
|
SpvInstruction result = emitF(context.TypeFP32(), context.GetFP32(src1), context.GetFP32(src2));
|
||||||
|
|
||||||
if (!context.HostCapabilities.ReducedPrecision || operation.ForcePrecise)
|
if (!context.HostCapabilities.ReducedPrecision || operation.ForcePrecise)
|
||||||
{
|
{
|
||||||
@ -2002,8 +2002,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
AstOperation operation,
|
AstOperation operation,
|
||||||
Func<SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction> emitB)
|
Func<SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction> emitB)
|
||||||
{
|
{
|
||||||
var src1 = operation.GetSource(0);
|
IAstNode src1 = operation.GetSource(0);
|
||||||
var src2 = operation.GetSource(1);
|
IAstNode src2 = operation.GetSource(1);
|
||||||
|
|
||||||
return new OperationResult(AggregateType.Bool, emitB(context.TypeBool(), context.Get(AggregateType.Bool, src1), context.Get(AggregateType.Bool, src2)));
|
return new OperationResult(AggregateType.Bool, emitB(context.TypeBool(), context.Get(AggregateType.Bool, src1), context.Get(AggregateType.Bool, src2)));
|
||||||
}
|
}
|
||||||
@ -2013,8 +2013,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
AstOperation operation,
|
AstOperation operation,
|
||||||
Func<SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction> emitS)
|
Func<SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction> emitS)
|
||||||
{
|
{
|
||||||
var src1 = operation.GetSource(0);
|
IAstNode src1 = operation.GetSource(0);
|
||||||
var src2 = operation.GetSource(1);
|
IAstNode src2 = operation.GetSource(1);
|
||||||
|
|
||||||
return new OperationResult(AggregateType.S32, emitS(context.TypeS32(), context.GetS32(src1), context.GetS32(src2)));
|
return new OperationResult(AggregateType.S32, emitS(context.TypeS32(), context.GetS32(src1), context.GetS32(src2)));
|
||||||
}
|
}
|
||||||
@ -2024,8 +2024,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
AstOperation operation,
|
AstOperation operation,
|
||||||
Func<SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction> emitU)
|
Func<SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction> emitU)
|
||||||
{
|
{
|
||||||
var src1 = operation.GetSource(0);
|
IAstNode src1 = operation.GetSource(0);
|
||||||
var src2 = operation.GetSource(1);
|
IAstNode src2 = operation.GetSource(1);
|
||||||
|
|
||||||
return new OperationResult(AggregateType.U32, emitU(context.TypeU32(), context.GetU32(src1), context.GetU32(src2)));
|
return new OperationResult(AggregateType.U32, emitU(context.TypeU32(), context.GetU32(src1), context.GetU32(src2)));
|
||||||
}
|
}
|
||||||
@ -2036,13 +2036,13 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
Func<SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction> emitF,
|
Func<SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction> emitF,
|
||||||
Func<SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction> emitI)
|
Func<SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction> emitI)
|
||||||
{
|
{
|
||||||
var src1 = operation.GetSource(0);
|
IAstNode src1 = operation.GetSource(0);
|
||||||
var src2 = operation.GetSource(1);
|
IAstNode src2 = operation.GetSource(1);
|
||||||
var src3 = operation.GetSource(2);
|
IAstNode src3 = operation.GetSource(2);
|
||||||
|
|
||||||
if (operation.Inst.HasFlag(Instruction.FP64))
|
if (operation.Inst.HasFlag(Instruction.FP64))
|
||||||
{
|
{
|
||||||
var result = emitF(context.TypeFP64(), context.GetFP64(src1), context.GetFP64(src2), context.GetFP64(src3));
|
SpvInstruction result = emitF(context.TypeFP64(), context.GetFP64(src1), context.GetFP64(src2), context.GetFP64(src3));
|
||||||
|
|
||||||
if (!context.HostCapabilities.ReducedPrecision || operation.ForcePrecise)
|
if (!context.HostCapabilities.ReducedPrecision || operation.ForcePrecise)
|
||||||
{
|
{
|
||||||
@ -2053,7 +2053,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
}
|
}
|
||||||
else if (operation.Inst.HasFlag(Instruction.FP32))
|
else if (operation.Inst.HasFlag(Instruction.FP32))
|
||||||
{
|
{
|
||||||
var result = emitF(context.TypeFP32(), context.GetFP32(src1), context.GetFP32(src2), context.GetFP32(src3));
|
SpvInstruction result = emitF(context.TypeFP32(), context.GetFP32(src1), context.GetFP32(src2), context.GetFP32(src3));
|
||||||
|
|
||||||
if (!context.HostCapabilities.ReducedPrecision || operation.ForcePrecise)
|
if (!context.HostCapabilities.ReducedPrecision || operation.ForcePrecise)
|
||||||
{
|
{
|
||||||
@ -2073,9 +2073,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
AstOperation operation,
|
AstOperation operation,
|
||||||
Func<SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction> emitU)
|
Func<SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction> emitU)
|
||||||
{
|
{
|
||||||
var src1 = operation.GetSource(0);
|
IAstNode src1 = operation.GetSource(0);
|
||||||
var src2 = operation.GetSource(1);
|
IAstNode src2 = operation.GetSource(1);
|
||||||
var src3 = operation.GetSource(2);
|
IAstNode src3 = operation.GetSource(2);
|
||||||
|
|
||||||
return new OperationResult(AggregateType.U32, emitU(
|
return new OperationResult(AggregateType.U32, emitU(
|
||||||
context.TypeU32(),
|
context.TypeU32(),
|
||||||
@ -2089,9 +2089,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
AstOperation operation,
|
AstOperation operation,
|
||||||
Func<SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction> emitS)
|
Func<SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction> emitS)
|
||||||
{
|
{
|
||||||
var src1 = operation.GetSource(0);
|
IAstNode src1 = operation.GetSource(0);
|
||||||
var src2 = operation.GetSource(1);
|
IAstNode src2 = operation.GetSource(1);
|
||||||
var src3 = operation.GetSource(2);
|
IAstNode src3 = operation.GetSource(2);
|
||||||
|
|
||||||
return new OperationResult(AggregateType.S32, emitS(
|
return new OperationResult(AggregateType.S32, emitS(
|
||||||
context.TypeS32(),
|
context.TypeS32(),
|
||||||
@ -2105,10 +2105,10 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
AstOperation operation,
|
AstOperation operation,
|
||||||
Func<SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction> emitS)
|
Func<SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction> emitS)
|
||||||
{
|
{
|
||||||
var src1 = operation.GetSource(0);
|
IAstNode src1 = operation.GetSource(0);
|
||||||
var src2 = operation.GetSource(1);
|
IAstNode src2 = operation.GetSource(1);
|
||||||
var src3 = operation.GetSource(2);
|
IAstNode src3 = operation.GetSource(2);
|
||||||
var src4 = operation.GetSource(3);
|
IAstNode src4 = operation.GetSource(3);
|
||||||
|
|
||||||
return new OperationResult(AggregateType.U32, emitS(
|
return new OperationResult(AggregateType.U32, emitS(
|
||||||
context.TypeU32(),
|
context.TypeU32(),
|
||||||
|
@ -124,20 +124,20 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
for (int funcIndex = 0; funcIndex < info.Functions.Count; funcIndex++)
|
for (int funcIndex = 0; funcIndex < info.Functions.Count; funcIndex++)
|
||||||
{
|
{
|
||||||
var function = info.Functions[funcIndex];
|
StructuredFunction function = info.Functions[funcIndex];
|
||||||
var retType = context.GetType(function.ReturnType);
|
SpvInstruction retType = context.GetType(function.ReturnType);
|
||||||
|
|
||||||
var funcArgs = new SpvInstruction[function.InArguments.Length + function.OutArguments.Length];
|
SpvInstruction[] funcArgs = new SpvInstruction[function.InArguments.Length + function.OutArguments.Length];
|
||||||
|
|
||||||
for (int argIndex = 0; argIndex < funcArgs.Length; argIndex++)
|
for (int argIndex = 0; argIndex < funcArgs.Length; argIndex++)
|
||||||
{
|
{
|
||||||
var argType = context.GetType(function.GetArgumentType(argIndex));
|
SpvInstruction argType = context.GetType(function.GetArgumentType(argIndex));
|
||||||
var argPointerType = context.TypePointer(StorageClass.Function, argType);
|
SpvInstruction argPointerType = context.TypePointer(StorageClass.Function, argType);
|
||||||
funcArgs[argIndex] = argPointerType;
|
funcArgs[argIndex] = argPointerType;
|
||||||
}
|
}
|
||||||
|
|
||||||
var funcType = context.TypeFunction(retType, false, funcArgs);
|
SpvInstruction funcType = context.TypeFunction(retType, false, funcArgs);
|
||||||
var spvFunc = context.Function(retType, FunctionControlMask.MaskNone, funcType);
|
SpvInstruction spvFunc = context.Function(retType, FunctionControlMask.MaskNone, funcType);
|
||||||
|
|
||||||
context.DeclareFunction(funcIndex, function, spvFunc);
|
context.DeclareFunction(funcIndex, function, spvFunc);
|
||||||
}
|
}
|
||||||
@ -160,7 +160,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
private static void Generate(CodeGenContext context, StructuredProgramInfo info, int funcIndex)
|
private static void Generate(CodeGenContext context, StructuredProgramInfo info, int funcIndex)
|
||||||
{
|
{
|
||||||
var (function, spvFunc) = context.GetFunction(funcIndex);
|
(StructuredFunction function, SpvInstruction spvFunc) = context.GetFunction(funcIndex);
|
||||||
|
|
||||||
context.CurrentFunction = function;
|
context.CurrentFunction = function;
|
||||||
context.AddFunction(spvFunc);
|
context.AddFunction(spvFunc);
|
||||||
@ -284,9 +284,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
}
|
}
|
||||||
else if (context.Definitions.Stage == ShaderStage.Compute)
|
else if (context.Definitions.Stage == ShaderStage.Compute)
|
||||||
{
|
{
|
||||||
var localSizeX = (SpvLiteralInteger)context.Definitions.ComputeLocalSizeX;
|
SpvLiteralInteger localSizeX = (SpvLiteralInteger)context.Definitions.ComputeLocalSizeX;
|
||||||
var localSizeY = (SpvLiteralInteger)context.Definitions.ComputeLocalSizeY;
|
SpvLiteralInteger localSizeY = (SpvLiteralInteger)context.Definitions.ComputeLocalSizeY;
|
||||||
var localSizeZ = (SpvLiteralInteger)context.Definitions.ComputeLocalSizeZ;
|
SpvLiteralInteger localSizeZ = (SpvLiteralInteger)context.Definitions.ComputeLocalSizeZ;
|
||||||
|
|
||||||
context.AddExecutionMode(
|
context.AddExecutionMode(
|
||||||
spvFunc,
|
spvFunc,
|
||||||
@ -307,7 +307,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
{
|
{
|
||||||
AstBlockVisitor visitor = new(block);
|
AstBlockVisitor visitor = new(block);
|
||||||
|
|
||||||
var loopTargets = new Dictionary<AstBlock, (SpvInstruction, SpvInstruction)>();
|
Dictionary<AstBlock, (SpvInstruction, SpvInstruction)> loopTargets = new Dictionary<AstBlock, (SpvInstruction, SpvInstruction)>();
|
||||||
|
|
||||||
context.LoopTargets = loopTargets;
|
context.LoopTargets = loopTargets;
|
||||||
|
|
||||||
@ -329,14 +329,14 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
ifFalseBlock = mergeBlock;
|
ifFalseBlock = mergeBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
var condition = context.Get(AggregateType.Bool, e.Block.Condition);
|
SpvInstruction condition = context.Get(AggregateType.Bool, e.Block.Condition);
|
||||||
|
|
||||||
context.SelectionMerge(context.GetNextLabel(mergeBlock), SelectionControlMask.MaskNone);
|
context.SelectionMerge(context.GetNextLabel(mergeBlock), SelectionControlMask.MaskNone);
|
||||||
context.BranchConditional(condition, context.GetNextLabel(ifTrueBlock), context.GetNextLabel(ifFalseBlock));
|
context.BranchConditional(condition, context.GetNextLabel(ifTrueBlock), context.GetNextLabel(ifFalseBlock));
|
||||||
}
|
}
|
||||||
else if (e.Block.Type == AstBlockType.DoWhile)
|
else if (e.Block.Type == AstBlockType.DoWhile)
|
||||||
{
|
{
|
||||||
var continueTarget = context.Label();
|
SpvInstruction continueTarget = context.Label();
|
||||||
|
|
||||||
loopTargets.Add(e.Block, (context.NewBlock(), continueTarget));
|
loopTargets.Add(e.Block, (context.NewBlock(), continueTarget));
|
||||||
|
|
||||||
@ -357,12 +357,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
// if the condition is true.
|
// if the condition is true.
|
||||||
AstBlock mergeBlock = e.Block.Parent;
|
AstBlock mergeBlock = e.Block.Parent;
|
||||||
|
|
||||||
var (loopTarget, continueTarget) = loopTargets[e.Block];
|
(SpvInstruction loopTarget, SpvInstruction continueTarget) = loopTargets[e.Block];
|
||||||
|
|
||||||
context.Branch(continueTarget);
|
context.Branch(continueTarget);
|
||||||
context.AddLabel(continueTarget);
|
context.AddLabel(continueTarget);
|
||||||
|
|
||||||
var condition = context.Get(AggregateType.Bool, e.Block.Condition);
|
SpvInstruction condition = context.Get(AggregateType.Bool, e.Block.Condition);
|
||||||
|
|
||||||
context.BranchConditional(condition, loopTarget, context.GetNextLabel(mergeBlock));
|
context.BranchConditional(condition, loopTarget, context.GetNextLabel(mergeBlock));
|
||||||
}
|
}
|
||||||
@ -398,16 +398,16 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
{
|
{
|
||||||
if (node is AstAssignment assignment)
|
if (node is AstAssignment assignment)
|
||||||
{
|
{
|
||||||
var dest = (AstOperand)assignment.Destination;
|
AstOperand dest = (AstOperand)assignment.Destination;
|
||||||
|
|
||||||
if (dest.Type == OperandType.LocalVariable)
|
if (dest.Type == OperandType.LocalVariable)
|
||||||
{
|
{
|
||||||
var source = context.Get(dest.VarType, assignment.Source);
|
SpvInstruction source = context.Get(dest.VarType, assignment.Source);
|
||||||
context.Store(context.GetLocalPointer(dest), source);
|
context.Store(context.GetLocalPointer(dest), source);
|
||||||
}
|
}
|
||||||
else if (dest.Type == OperandType.Argument)
|
else if (dest.Type == OperandType.Argument)
|
||||||
{
|
{
|
||||||
var source = context.Get(dest.VarType, assignment.Source);
|
SpvInstruction source = context.Get(dest.VarType, assignment.Source);
|
||||||
context.Store(context.GetArgumentPointer(dest), source);
|
context.Store(context.GetArgumentPointer(dest), source);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -568,39 +568,39 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||||||
|
|
||||||
HashSet<Block> visited = new();
|
HashSet<Block> visited = new();
|
||||||
|
|
||||||
var ldcLocation = FindFirstRegWrite(visited, new BlockLocation(block, block.OpCodes.Count - 1), brxReg);
|
BlockLocation ldcLocation = FindFirstRegWrite(visited, new BlockLocation(block, block.OpCodes.Count - 1), brxReg);
|
||||||
if (ldcLocation.Block == null || ldcLocation.Block.OpCodes[ldcLocation.Index].Name != InstName.Ldc)
|
if (ldcLocation.Block == null || ldcLocation.Block.OpCodes[ldcLocation.Index].Name != InstName.Ldc)
|
||||||
{
|
{
|
||||||
return (0, 0);
|
return (0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
GetOp<InstLdc>(ldcLocation, out var opLdc);
|
GetOp<InstLdc>(ldcLocation, out InstLdc opLdc);
|
||||||
|
|
||||||
if (opLdc.CbufSlot != 1 || opLdc.AddressMode != 0)
|
if (opLdc.CbufSlot != 1 || opLdc.AddressMode != 0)
|
||||||
{
|
{
|
||||||
return (0, 0);
|
return (0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
var shlLocation = FindFirstRegWrite(visited, ldcLocation, opLdc.SrcA);
|
BlockLocation shlLocation = FindFirstRegWrite(visited, ldcLocation, opLdc.SrcA);
|
||||||
if (shlLocation.Block == null || !shlLocation.IsImmInst(InstName.Shl))
|
if (shlLocation.Block == null || !shlLocation.IsImmInst(InstName.Shl))
|
||||||
{
|
{
|
||||||
return (0, 0);
|
return (0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
GetOp<InstShlI>(shlLocation, out var opShl);
|
GetOp<InstShlI>(shlLocation, out InstShlI opShl);
|
||||||
|
|
||||||
if (opShl.Imm20 != 2)
|
if (opShl.Imm20 != 2)
|
||||||
{
|
{
|
||||||
return (0, 0);
|
return (0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
var imnmxLocation = FindFirstRegWrite(visited, shlLocation, opShl.SrcA);
|
BlockLocation imnmxLocation = FindFirstRegWrite(visited, shlLocation, opShl.SrcA);
|
||||||
if (imnmxLocation.Block == null || !imnmxLocation.IsImmInst(InstName.Imnmx))
|
if (imnmxLocation.Block == null || !imnmxLocation.IsImmInst(InstName.Imnmx))
|
||||||
{
|
{
|
||||||
return (0, 0);
|
return (0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
GetOp<InstImnmxI>(imnmxLocation, out var opImnmx);
|
GetOp<InstImnmxI>(imnmxLocation, out InstImnmxI opImnmx);
|
||||||
|
|
||||||
if (opImnmx.Signed || opImnmx.SrcPred != RegisterConsts.PredicateTrueIndex || opImnmx.SrcPredInv)
|
if (opImnmx.Signed || opImnmx.SrcPred != RegisterConsts.PredicateTrueIndex || opImnmx.SrcPredInv)
|
||||||
{
|
{
|
||||||
@ -640,7 +640,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||||||
toVisit.Enqueue(location);
|
toVisit.Enqueue(location);
|
||||||
visited.Add(location.Block);
|
visited.Add(location.Block);
|
||||||
|
|
||||||
while (toVisit.TryDequeue(out var currentLocation))
|
while (toVisit.TryDequeue(out BlockLocation currentLocation))
|
||||||
{
|
{
|
||||||
Block block = currentLocation.Block;
|
Block block = currentLocation.Block;
|
||||||
for (int i = currentLocation.Index - 1; i >= 0; i--)
|
for (int i = currentLocation.Index - 1; i >= 0; i--)
|
||||||
|
@ -57,7 +57,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
|
|
||||||
private static IReadOnlyDictionary<int, AttributeEntry> CreateMap()
|
private static IReadOnlyDictionary<int, AttributeEntry> CreateMap()
|
||||||
{
|
{
|
||||||
var map = new Dictionary<int, AttributeEntry>();
|
Dictionary<int, AttributeEntry> map = new Dictionary<int, AttributeEntry>();
|
||||||
|
|
||||||
Add(map, 0x060, AggregateType.S32, IoVariable.PrimitiveId, StagesMask.TessellationGeometryFragment, StagesMask.Geometry);
|
Add(map, 0x060, AggregateType.S32, IoVariable.PrimitiveId, StagesMask.TessellationGeometryFragment, StagesMask.Geometry);
|
||||||
Add(map, 0x064, AggregateType.S32, IoVariable.Layer, StagesMask.Fragment, StagesMask.VertexTessellationGeometry);
|
Add(map, 0x064, AggregateType.S32, IoVariable.Layer, StagesMask.Fragment, StagesMask.VertexTessellationGeometry);
|
||||||
@ -84,7 +84,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
|
|
||||||
private static IReadOnlyDictionary<int, AttributeEntry> CreatePerPatchMap()
|
private static IReadOnlyDictionary<int, AttributeEntry> CreatePerPatchMap()
|
||||||
{
|
{
|
||||||
var map = new Dictionary<int, AttributeEntry>();
|
Dictionary<int, AttributeEntry> map = new Dictionary<int, AttributeEntry>();
|
||||||
|
|
||||||
Add(map, 0x000, AggregateType.Vector4 | AggregateType.FP32, IoVariable.TessellationLevelOuter, StagesMask.TessellationEvaluation, StagesMask.TessellationControl);
|
Add(map, 0x000, AggregateType.Vector4 | AggregateType.FP32, IoVariable.TessellationLevelOuter, StagesMask.TessellationEvaluation, StagesMask.TessellationControl);
|
||||||
Add(map, 0x010, AggregateType.Vector2 | AggregateType.FP32, IoVariable.TessellationLevelInner, StagesMask.TessellationEvaluation, StagesMask.TessellationControl);
|
Add(map, 0x010, AggregateType.Vector2 | AggregateType.FP32, IoVariable.TessellationLevelInner, StagesMask.TessellationEvaluation, StagesMask.TessellationControl);
|
||||||
|
@ -261,7 +261,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
if (context.TranslatorContext.Definitions.LastInVertexPipeline)
|
if (context.TranslatorContext.Definitions.LastInVertexPipeline)
|
||||||
{
|
{
|
||||||
context.PrepareForVertexReturn(out var tempXLocal, out var tempYLocal, out var tempZLocal);
|
context.PrepareForVertexReturn(out Operand tempXLocal, out Operand tempYLocal, out Operand tempZLocal);
|
||||||
|
|
||||||
context.EmitVertex();
|
context.EmitVertex();
|
||||||
|
|
||||||
|
@ -13,8 +13,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstBfeR op = context.GetOp<InstBfeR>();
|
InstBfeR op = context.GetOp<InstBfeR>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcReg(context, op.SrcB);
|
Operand srcB = GetSrcReg(context, op.SrcB);
|
||||||
|
|
||||||
EmitBfe(context, srcA, srcB, op.Dest, op.Brev, op.Signed);
|
EmitBfe(context, srcA, srcB, op.Dest, op.Brev, op.Signed);
|
||||||
}
|
}
|
||||||
@ -23,8 +23,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstBfeI op = context.GetOp<InstBfeI>();
|
InstBfeI op = context.GetOp<InstBfeI>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
|
Operand srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
|
||||||
|
|
||||||
EmitBfe(context, srcA, srcB, op.Dest, op.Brev, op.Signed);
|
EmitBfe(context, srcA, srcB, op.Dest, op.Brev, op.Signed);
|
||||||
}
|
}
|
||||||
@ -33,8 +33,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstBfeC op = context.GetOp<InstBfeC>();
|
InstBfeC op = context.GetOp<InstBfeC>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
Operand srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
||||||
|
|
||||||
EmitBfe(context, srcA, srcB, op.Dest, op.Brev, op.Signed);
|
EmitBfe(context, srcA, srcB, op.Dest, op.Brev, op.Signed);
|
||||||
}
|
}
|
||||||
@ -43,9 +43,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstBfiR op = context.GetOp<InstBfiR>();
|
InstBfiR op = context.GetOp<InstBfiR>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcReg(context, op.SrcB);
|
Operand srcB = GetSrcReg(context, op.SrcB);
|
||||||
var srcC = GetSrcReg(context, op.SrcC);
|
Operand srcC = GetSrcReg(context, op.SrcC);
|
||||||
|
|
||||||
EmitBfi(context, srcA, srcB, srcC, op.Dest);
|
EmitBfi(context, srcA, srcB, srcC, op.Dest);
|
||||||
}
|
}
|
||||||
@ -54,9 +54,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstBfiI op = context.GetOp<InstBfiI>();
|
InstBfiI op = context.GetOp<InstBfiI>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
|
Operand srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
|
||||||
var srcC = GetSrcReg(context, op.SrcC);
|
Operand srcC = GetSrcReg(context, op.SrcC);
|
||||||
|
|
||||||
EmitBfi(context, srcA, srcB, srcC, op.Dest);
|
EmitBfi(context, srcA, srcB, srcC, op.Dest);
|
||||||
}
|
}
|
||||||
@ -65,9 +65,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstBfiC op = context.GetOp<InstBfiC>();
|
InstBfiC op = context.GetOp<InstBfiC>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
Operand srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
||||||
var srcC = GetSrcReg(context, op.SrcC);
|
Operand srcC = GetSrcReg(context, op.SrcC);
|
||||||
|
|
||||||
EmitBfi(context, srcA, srcB, srcC, op.Dest);
|
EmitBfi(context, srcA, srcB, srcC, op.Dest);
|
||||||
}
|
}
|
||||||
@ -76,9 +76,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstBfiRc op = context.GetOp<InstBfiRc>();
|
InstBfiRc op = context.GetOp<InstBfiRc>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcReg(context, op.SrcC);
|
Operand srcB = GetSrcReg(context, op.SrcC);
|
||||||
var srcC = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
Operand srcC = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
||||||
|
|
||||||
EmitBfi(context, srcA, srcB, srcC, op.Dest);
|
EmitBfi(context, srcA, srcB, srcC, op.Dest);
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstF2fR op = context.GetOp<InstF2fR>();
|
InstF2fR op = context.GetOp<InstF2fR>();
|
||||||
|
|
||||||
var src = UnpackReg(context, op.SrcFmt, op.Sh, op.SrcB);
|
Operand src = UnpackReg(context, op.SrcFmt, op.Sh, op.SrcB);
|
||||||
|
|
||||||
EmitF2F(context, op.SrcFmt, op.DstFmt, op.RoundMode, src, op.Dest, op.AbsB, op.NegB, op.Sat);
|
EmitF2F(context, op.SrcFmt, op.DstFmt, op.RoundMode, src, op.Dest, op.AbsB, op.NegB, op.Sat);
|
||||||
}
|
}
|
||||||
@ -23,7 +23,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstF2fI op = context.GetOp<InstF2fI>();
|
InstF2fI op = context.GetOp<InstF2fI>();
|
||||||
|
|
||||||
var src = UnpackImm(context, op.SrcFmt, op.Sh, Imm20ToFloat(op.Imm20));
|
Operand src = UnpackImm(context, op.SrcFmt, op.Sh, Imm20ToFloat(op.Imm20));
|
||||||
|
|
||||||
EmitF2F(context, op.SrcFmt, op.DstFmt, op.RoundMode, src, op.Dest, op.AbsB, op.NegB, op.Sat);
|
EmitF2F(context, op.SrcFmt, op.DstFmt, op.RoundMode, src, op.Dest, op.AbsB, op.NegB, op.Sat);
|
||||||
}
|
}
|
||||||
@ -32,7 +32,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstF2fC op = context.GetOp<InstF2fC>();
|
InstF2fC op = context.GetOp<InstF2fC>();
|
||||||
|
|
||||||
var src = UnpackCbuf(context, op.SrcFmt, op.Sh, op.CbufSlot, op.CbufOffset);
|
Operand src = UnpackCbuf(context, op.SrcFmt, op.Sh, op.CbufSlot, op.CbufOffset);
|
||||||
|
|
||||||
EmitF2F(context, op.SrcFmt, op.DstFmt, op.RoundMode, src, op.Dest, op.AbsB, op.NegB, op.Sat);
|
EmitF2F(context, op.SrcFmt, op.DstFmt, op.RoundMode, src, op.Dest, op.AbsB, op.NegB, op.Sat);
|
||||||
}
|
}
|
||||||
@ -41,7 +41,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstF2iR op = context.GetOp<InstF2iR>();
|
InstF2iR op = context.GetOp<InstF2iR>();
|
||||||
|
|
||||||
var src = UnpackReg(context, op.SrcFmt, op.Sh, op.SrcB);
|
Operand src = UnpackReg(context, op.SrcFmt, op.Sh, op.SrcB);
|
||||||
|
|
||||||
EmitF2I(context, op.SrcFmt, op.IDstFmt, op.RoundMode, src, op.Dest, op.AbsB, op.NegB);
|
EmitF2I(context, op.SrcFmt, op.IDstFmt, op.RoundMode, src, op.Dest, op.AbsB, op.NegB);
|
||||||
}
|
}
|
||||||
@ -50,7 +50,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstF2iI op = context.GetOp<InstF2iI>();
|
InstF2iI op = context.GetOp<InstF2iI>();
|
||||||
|
|
||||||
var src = UnpackImm(context, op.SrcFmt, op.Sh, Imm20ToFloat(op.Imm20));
|
Operand src = UnpackImm(context, op.SrcFmt, op.Sh, Imm20ToFloat(op.Imm20));
|
||||||
|
|
||||||
EmitF2I(context, op.SrcFmt, op.IDstFmt, op.RoundMode, src, op.Dest, op.AbsB, op.NegB);
|
EmitF2I(context, op.SrcFmt, op.IDstFmt, op.RoundMode, src, op.Dest, op.AbsB, op.NegB);
|
||||||
}
|
}
|
||||||
@ -59,7 +59,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstF2iC op = context.GetOp<InstF2iC>();
|
InstF2iC op = context.GetOp<InstF2iC>();
|
||||||
|
|
||||||
var src = UnpackCbuf(context, op.SrcFmt, op.Sh, op.CbufSlot, op.CbufOffset);
|
Operand src = UnpackCbuf(context, op.SrcFmt, op.Sh, op.CbufSlot, op.CbufOffset);
|
||||||
|
|
||||||
EmitF2I(context, op.SrcFmt, op.IDstFmt, op.RoundMode, src, op.Dest, op.AbsB, op.NegB);
|
EmitF2I(context, op.SrcFmt, op.IDstFmt, op.RoundMode, src, op.Dest, op.AbsB, op.NegB);
|
||||||
}
|
}
|
||||||
@ -68,7 +68,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstI2fR op = context.GetOp<InstI2fR>();
|
InstI2fR op = context.GetOp<InstI2fR>();
|
||||||
|
|
||||||
var src = GetSrcReg(context, op.SrcB);
|
Operand src = GetSrcReg(context, op.SrcB);
|
||||||
|
|
||||||
EmitI2F(context, op.ISrcFmt, op.DstFmt, src, op.ByteSel, op.Dest, op.AbsB, op.NegB);
|
EmitI2F(context, op.ISrcFmt, op.DstFmt, src, op.ByteSel, op.Dest, op.AbsB, op.NegB);
|
||||||
}
|
}
|
||||||
@ -77,7 +77,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstI2fI op = context.GetOp<InstI2fI>();
|
InstI2fI op = context.GetOp<InstI2fI>();
|
||||||
|
|
||||||
var src = GetSrcImm(context, Imm20ToSInt(op.Imm20));
|
Operand src = GetSrcImm(context, Imm20ToSInt(op.Imm20));
|
||||||
|
|
||||||
EmitI2F(context, op.ISrcFmt, op.DstFmt, src, op.ByteSel, op.Dest, op.AbsB, op.NegB);
|
EmitI2F(context, op.ISrcFmt, op.DstFmt, src, op.ByteSel, op.Dest, op.AbsB, op.NegB);
|
||||||
}
|
}
|
||||||
@ -86,7 +86,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstI2fC op = context.GetOp<InstI2fC>();
|
InstI2fC op = context.GetOp<InstI2fC>();
|
||||||
|
|
||||||
var src = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
Operand src = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
||||||
|
|
||||||
EmitI2F(context, op.ISrcFmt, op.DstFmt, src, op.ByteSel, op.Dest, op.AbsB, op.NegB);
|
EmitI2F(context, op.ISrcFmt, op.DstFmt, src, op.ByteSel, op.Dest, op.AbsB, op.NegB);
|
||||||
}
|
}
|
||||||
@ -95,7 +95,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstI2iR op = context.GetOp<InstI2iR>();
|
InstI2iR op = context.GetOp<InstI2iR>();
|
||||||
|
|
||||||
var src = GetSrcReg(context, op.SrcB);
|
Operand src = GetSrcReg(context, op.SrcB);
|
||||||
|
|
||||||
EmitI2I(context, op.ISrcFmt, op.IDstFmt, src, op.ByteSel, op.Dest, op.AbsB, op.NegB, op.Sat, op.WriteCC);
|
EmitI2I(context, op.ISrcFmt, op.IDstFmt, src, op.ByteSel, op.Dest, op.AbsB, op.NegB, op.Sat, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -104,7 +104,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstI2iI op = context.GetOp<InstI2iI>();
|
InstI2iI op = context.GetOp<InstI2iI>();
|
||||||
|
|
||||||
var src = GetSrcImm(context, Imm20ToSInt(op.Imm20));
|
Operand src = GetSrcImm(context, Imm20ToSInt(op.Imm20));
|
||||||
|
|
||||||
EmitI2I(context, op.ISrcFmt, op.IDstFmt, src, op.ByteSel, op.Dest, op.AbsB, op.NegB, op.Sat, op.WriteCC);
|
EmitI2I(context, op.ISrcFmt, op.IDstFmt, src, op.ByteSel, op.Dest, op.AbsB, op.NegB, op.Sat, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -113,7 +113,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstI2iC op = context.GetOp<InstI2iC>();
|
InstI2iC op = context.GetOp<InstI2iC>();
|
||||||
|
|
||||||
var src = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
Operand src = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
||||||
|
|
||||||
EmitI2I(context, op.ISrcFmt, op.IDstFmt, src, op.ByteSel, op.Dest, op.AbsB, op.NegB, op.Sat, op.WriteCC);
|
EmitI2I(context, op.ISrcFmt, op.IDstFmt, src, op.ByteSel, op.Dest, op.AbsB, op.NegB, op.Sat, op.WriteCC);
|
||||||
}
|
}
|
||||||
|
@ -13,8 +13,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstDaddR op = context.GetOp<InstDaddR>();
|
InstDaddR op = context.GetOp<InstDaddR>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
Operand srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
||||||
var srcB = GetSrcReg(context, op.SrcB, isFP64: true);
|
Operand srcB = GetSrcReg(context, op.SrcB, isFP64: true);
|
||||||
|
|
||||||
EmitFadd(context, Instruction.FP64, srcA, srcB, op.Dest, op.NegA, op.NegB, op.AbsA, op.AbsB, false, op.WriteCC);
|
EmitFadd(context, Instruction.FP64, srcA, srcB, op.Dest, op.NegA, op.NegB, op.AbsA, op.AbsB, false, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -23,8 +23,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstDaddI op = context.GetOp<InstDaddI>();
|
InstDaddI op = context.GetOp<InstDaddI>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
Operand srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
||||||
var srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20), isFP64: true);
|
Operand srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20), isFP64: true);
|
||||||
|
|
||||||
EmitFadd(context, Instruction.FP64, srcA, srcB, op.Dest, op.NegA, op.NegB, op.AbsA, op.AbsB, false, op.WriteCC);
|
EmitFadd(context, Instruction.FP64, srcA, srcB, op.Dest, op.NegA, op.NegB, op.AbsA, op.AbsB, false, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -33,8 +33,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstDaddC op = context.GetOp<InstDaddC>();
|
InstDaddC op = context.GetOp<InstDaddC>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
Operand srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
||||||
var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset, isFP64: true);
|
Operand srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset, isFP64: true);
|
||||||
|
|
||||||
EmitFadd(context, Instruction.FP64, srcA, srcB, op.Dest, op.NegA, op.NegB, op.AbsA, op.AbsB, false, op.WriteCC);
|
EmitFadd(context, Instruction.FP64, srcA, srcB, op.Dest, op.NegA, op.NegB, op.AbsA, op.AbsB, false, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -43,9 +43,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstDfmaR op = context.GetOp<InstDfmaR>();
|
InstDfmaR op = context.GetOp<InstDfmaR>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
Operand srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
||||||
var srcB = GetSrcReg(context, op.SrcB, isFP64: true);
|
Operand srcB = GetSrcReg(context, op.SrcB, isFP64: true);
|
||||||
var srcC = GetSrcReg(context, op.SrcC, isFP64: true);
|
Operand srcC = GetSrcReg(context, op.SrcC, isFP64: true);
|
||||||
|
|
||||||
EmitFfma(context, Instruction.FP64, srcA, srcB, srcC, op.Dest, op.NegA, op.NegC, false, op.WriteCC);
|
EmitFfma(context, Instruction.FP64, srcA, srcB, srcC, op.Dest, op.NegA, op.NegC, false, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -54,9 +54,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstDfmaI op = context.GetOp<InstDfmaI>();
|
InstDfmaI op = context.GetOp<InstDfmaI>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
Operand srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
||||||
var srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20), isFP64: true);
|
Operand srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20), isFP64: true);
|
||||||
var srcC = GetSrcReg(context, op.SrcC, isFP64: true);
|
Operand srcC = GetSrcReg(context, op.SrcC, isFP64: true);
|
||||||
|
|
||||||
EmitFfma(context, Instruction.FP64, srcA, srcB, srcC, op.Dest, op.NegA, op.NegC, false, op.WriteCC);
|
EmitFfma(context, Instruction.FP64, srcA, srcB, srcC, op.Dest, op.NegA, op.NegC, false, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -65,9 +65,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstDfmaC op = context.GetOp<InstDfmaC>();
|
InstDfmaC op = context.GetOp<InstDfmaC>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
Operand srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
||||||
var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset, isFP64: true);
|
Operand srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset, isFP64: true);
|
||||||
var srcC = GetSrcReg(context, op.SrcC, isFP64: true);
|
Operand srcC = GetSrcReg(context, op.SrcC, isFP64: true);
|
||||||
|
|
||||||
EmitFfma(context, Instruction.FP64, srcA, srcB, srcC, op.Dest, op.NegA, op.NegC, false, op.WriteCC);
|
EmitFfma(context, Instruction.FP64, srcA, srcB, srcC, op.Dest, op.NegA, op.NegC, false, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -76,9 +76,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstDfmaRc op = context.GetOp<InstDfmaRc>();
|
InstDfmaRc op = context.GetOp<InstDfmaRc>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
Operand srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
||||||
var srcB = GetSrcReg(context, op.SrcC, isFP64: true);
|
Operand srcB = GetSrcReg(context, op.SrcC, isFP64: true);
|
||||||
var srcC = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset, isFP64: true);
|
Operand srcC = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset, isFP64: true);
|
||||||
|
|
||||||
EmitFfma(context, Instruction.FP64, srcA, srcB, srcC, op.Dest, op.NegA, op.NegC, false, op.WriteCC);
|
EmitFfma(context, Instruction.FP64, srcA, srcB, srcC, op.Dest, op.NegA, op.NegC, false, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -87,8 +87,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstDmulR op = context.GetOp<InstDmulR>();
|
InstDmulR op = context.GetOp<InstDmulR>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
Operand srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
||||||
var srcB = GetSrcReg(context, op.SrcB, isFP64: true);
|
Operand srcB = GetSrcReg(context, op.SrcB, isFP64: true);
|
||||||
|
|
||||||
EmitFmul(context, Instruction.FP64, MultiplyScale.NoScale, srcA, srcB, op.Dest, op.NegA, false, op.WriteCC);
|
EmitFmul(context, Instruction.FP64, MultiplyScale.NoScale, srcA, srcB, op.Dest, op.NegA, false, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -97,8 +97,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstDmulI op = context.GetOp<InstDmulI>();
|
InstDmulI op = context.GetOp<InstDmulI>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
Operand srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
||||||
var srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20), isFP64: true);
|
Operand srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20), isFP64: true);
|
||||||
|
|
||||||
EmitFmul(context, Instruction.FP64, MultiplyScale.NoScale, srcA, srcB, op.Dest, op.NegA, false, op.WriteCC);
|
EmitFmul(context, Instruction.FP64, MultiplyScale.NoScale, srcA, srcB, op.Dest, op.NegA, false, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -107,8 +107,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstDmulC op = context.GetOp<InstDmulC>();
|
InstDmulC op = context.GetOp<InstDmulC>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
Operand srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
||||||
var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset, isFP64: true);
|
Operand srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset, isFP64: true);
|
||||||
|
|
||||||
EmitFmul(context, Instruction.FP64, MultiplyScale.NoScale, srcA, srcB, op.Dest, op.NegA, false, op.WriteCC);
|
EmitFmul(context, Instruction.FP64, MultiplyScale.NoScale, srcA, srcB, op.Dest, op.NegA, false, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -117,8 +117,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstFaddR op = context.GetOp<InstFaddR>();
|
InstFaddR op = context.GetOp<InstFaddR>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcReg(context, op.SrcB);
|
Operand srcB = GetSrcReg(context, op.SrcB);
|
||||||
|
|
||||||
EmitFadd(context, Instruction.FP32, srcA, srcB, op.Dest, op.NegA, op.NegB, op.AbsA, op.AbsB, op.Sat, op.WriteCC);
|
EmitFadd(context, Instruction.FP32, srcA, srcB, op.Dest, op.NegA, op.NegB, op.AbsA, op.AbsB, op.Sat, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -127,8 +127,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstFaddI op = context.GetOp<InstFaddI>();
|
InstFaddI op = context.GetOp<InstFaddI>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20));
|
Operand srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20));
|
||||||
|
|
||||||
EmitFadd(context, Instruction.FP32, srcA, srcB, op.Dest, op.NegA, op.NegB, op.AbsA, op.AbsB, op.Sat, op.WriteCC);
|
EmitFadd(context, Instruction.FP32, srcA, srcB, op.Dest, op.NegA, op.NegB, op.AbsA, op.AbsB, op.Sat, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -137,8 +137,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstFaddC op = context.GetOp<InstFaddC>();
|
InstFaddC op = context.GetOp<InstFaddC>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
Operand srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
||||||
|
|
||||||
EmitFadd(context, Instruction.FP32, srcA, srcB, op.Dest, op.NegA, op.NegB, op.AbsA, op.AbsB, op.Sat, op.WriteCC);
|
EmitFadd(context, Instruction.FP32, srcA, srcB, op.Dest, op.NegA, op.NegB, op.AbsA, op.AbsB, op.Sat, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -147,8 +147,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstFadd32i op = context.GetOp<InstFadd32i>();
|
InstFadd32i op = context.GetOp<InstFadd32i>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcImm(context, op.Imm32);
|
Operand srcB = GetSrcImm(context, op.Imm32);
|
||||||
|
|
||||||
EmitFadd(context, Instruction.FP32, srcA, srcB, op.Dest, op.NegA, op.NegB, op.AbsA, op.AbsB, false, op.WriteCC);
|
EmitFadd(context, Instruction.FP32, srcA, srcB, op.Dest, op.NegA, op.NegB, op.AbsA, op.AbsB, false, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -157,9 +157,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstFfmaR op = context.GetOp<InstFfmaR>();
|
InstFfmaR op = context.GetOp<InstFfmaR>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcReg(context, op.SrcB);
|
Operand srcB = GetSrcReg(context, op.SrcB);
|
||||||
var srcC = GetSrcReg(context, op.SrcC);
|
Operand srcC = GetSrcReg(context, op.SrcC);
|
||||||
|
|
||||||
EmitFfma(context, Instruction.FP32, srcA, srcB, srcC, op.Dest, op.NegA, op.NegC, op.Sat, op.WriteCC);
|
EmitFfma(context, Instruction.FP32, srcA, srcB, srcC, op.Dest, op.NegA, op.NegC, op.Sat, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -168,9 +168,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstFfmaI op = context.GetOp<InstFfmaI>();
|
InstFfmaI op = context.GetOp<InstFfmaI>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20));
|
Operand srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20));
|
||||||
var srcC = GetSrcReg(context, op.SrcC);
|
Operand srcC = GetSrcReg(context, op.SrcC);
|
||||||
|
|
||||||
EmitFfma(context, Instruction.FP32, srcA, srcB, srcC, op.Dest, op.NegA, op.NegC, op.Sat, op.WriteCC);
|
EmitFfma(context, Instruction.FP32, srcA, srcB, srcC, op.Dest, op.NegA, op.NegC, op.Sat, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -179,9 +179,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstFfmaC op = context.GetOp<InstFfmaC>();
|
InstFfmaC op = context.GetOp<InstFfmaC>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
Operand srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
||||||
var srcC = GetSrcReg(context, op.SrcC);
|
Operand srcC = GetSrcReg(context, op.SrcC);
|
||||||
|
|
||||||
EmitFfma(context, Instruction.FP32, srcA, srcB, srcC, op.Dest, op.NegA, op.NegC, op.Sat, op.WriteCC);
|
EmitFfma(context, Instruction.FP32, srcA, srcB, srcC, op.Dest, op.NegA, op.NegC, op.Sat, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -190,9 +190,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstFfmaRc op = context.GetOp<InstFfmaRc>();
|
InstFfmaRc op = context.GetOp<InstFfmaRc>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcReg(context, op.SrcC);
|
Operand srcB = GetSrcReg(context, op.SrcC);
|
||||||
var srcC = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
Operand srcC = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
||||||
|
|
||||||
EmitFfma(context, Instruction.FP32, srcA, srcB, srcC, op.Dest, op.NegA, op.NegC, op.Sat, op.WriteCC);
|
EmitFfma(context, Instruction.FP32, srcA, srcB, srcC, op.Dest, op.NegA, op.NegC, op.Sat, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -201,9 +201,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstFfma32i op = context.GetOp<InstFfma32i>();
|
InstFfma32i op = context.GetOp<InstFfma32i>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcImm(context, op.Imm32);
|
Operand srcB = GetSrcImm(context, op.Imm32);
|
||||||
var srcC = GetSrcReg(context, op.Dest);
|
Operand srcC = GetSrcReg(context, op.Dest);
|
||||||
|
|
||||||
EmitFfma(context, Instruction.FP32, srcA, srcB, srcC, op.Dest, op.NegA, op.NegC, op.Sat, op.WriteCC);
|
EmitFfma(context, Instruction.FP32, srcA, srcB, srcC, op.Dest, op.NegA, op.NegC, op.Sat, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -212,8 +212,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstFmulR op = context.GetOp<InstFmulR>();
|
InstFmulR op = context.GetOp<InstFmulR>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcReg(context, op.SrcB);
|
Operand srcB = GetSrcReg(context, op.SrcB);
|
||||||
|
|
||||||
EmitFmul(context, Instruction.FP32, op.Scale, srcA, srcB, op.Dest, op.NegA, op.Sat, op.WriteCC);
|
EmitFmul(context, Instruction.FP32, op.Scale, srcA, srcB, op.Dest, op.NegA, op.Sat, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -222,8 +222,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstFmulI op = context.GetOp<InstFmulI>();
|
InstFmulI op = context.GetOp<InstFmulI>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20));
|
Operand srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20));
|
||||||
|
|
||||||
EmitFmul(context, Instruction.FP32, op.Scale, srcA, srcB, op.Dest, op.NegA, op.Sat, op.WriteCC);
|
EmitFmul(context, Instruction.FP32, op.Scale, srcA, srcB, op.Dest, op.NegA, op.Sat, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -232,8 +232,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstFmulC op = context.GetOp<InstFmulC>();
|
InstFmulC op = context.GetOp<InstFmulC>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
Operand srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
||||||
|
|
||||||
EmitFmul(context, Instruction.FP32, op.Scale, srcA, srcB, op.Dest, op.NegA, op.Sat, op.WriteCC);
|
EmitFmul(context, Instruction.FP32, op.Scale, srcA, srcB, op.Dest, op.NegA, op.Sat, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -242,8 +242,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstFmul32i op = context.GetOp<InstFmul32i>();
|
InstFmul32i op = context.GetOp<InstFmul32i>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcImm(context, op.Imm32);
|
Operand srcB = GetSrcImm(context, op.Imm32);
|
||||||
|
|
||||||
EmitFmul(context, Instruction.FP32, MultiplyScale.NoScale, srcA, srcB, op.Dest, false, op.Sat, op.WriteCC);
|
EmitFmul(context, Instruction.FP32, MultiplyScale.NoScale, srcA, srcB, op.Dest, false, op.Sat, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -252,8 +252,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstHadd2R op = context.GetOp<InstHadd2R>();
|
InstHadd2R op = context.GetOp<InstHadd2R>();
|
||||||
|
|
||||||
var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, op.NegA, op.AbsA);
|
Operand[] srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, op.NegA, op.AbsA);
|
||||||
var srcB = GetHalfSrc(context, op.BSwizzle, op.SrcB, op.NegB, op.AbsB);
|
Operand[] srcB = GetHalfSrc(context, op.BSwizzle, op.SrcB, op.NegB, op.AbsB);
|
||||||
|
|
||||||
EmitHadd2Hmul2(context, op.OFmt, srcA, srcB, isAdd: true, op.Dest, op.Sat);
|
EmitHadd2Hmul2(context, op.OFmt, srcA, srcB, isAdd: true, op.Dest, op.Sat);
|
||||||
}
|
}
|
||||||
@ -262,8 +262,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstHadd2I op = context.GetOp<InstHadd2I>();
|
InstHadd2I op = context.GetOp<InstHadd2I>();
|
||||||
|
|
||||||
var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, op.NegA, op.AbsA);
|
Operand[] srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, op.NegA, op.AbsA);
|
||||||
var srcB = GetHalfSrc(context, op.BimmH0, op.BimmH1);
|
Operand[] srcB = GetHalfSrc(context, op.BimmH0, op.BimmH1);
|
||||||
|
|
||||||
EmitHadd2Hmul2(context, op.OFmt, srcA, srcB, isAdd: true, op.Dest, op.Sat);
|
EmitHadd2Hmul2(context, op.OFmt, srcA, srcB, isAdd: true, op.Dest, op.Sat);
|
||||||
}
|
}
|
||||||
@ -272,8 +272,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstHadd2C op = context.GetOp<InstHadd2C>();
|
InstHadd2C op = context.GetOp<InstHadd2C>();
|
||||||
|
|
||||||
var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, op.NegA, op.AbsA);
|
Operand[] srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, op.NegA, op.AbsA);
|
||||||
var srcB = GetHalfSrc(context, HalfSwizzle.F32, op.CbufSlot, op.CbufOffset, op.NegB, op.AbsB);
|
Operand[] srcB = GetHalfSrc(context, HalfSwizzle.F32, op.CbufSlot, op.CbufOffset, op.NegB, op.AbsB);
|
||||||
|
|
||||||
EmitHadd2Hmul2(context, op.OFmt, srcA, srcB, isAdd: true, op.Dest, op.Sat);
|
EmitHadd2Hmul2(context, op.OFmt, srcA, srcB, isAdd: true, op.Dest, op.Sat);
|
||||||
}
|
}
|
||||||
@ -282,8 +282,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstHadd232i op = context.GetOp<InstHadd232i>();
|
InstHadd232i op = context.GetOp<InstHadd232i>();
|
||||||
|
|
||||||
var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, op.NegA, false);
|
Operand[] srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, op.NegA, false);
|
||||||
var srcB = GetHalfSrc(context, op.Imm);
|
Operand[] srcB = GetHalfSrc(context, op.Imm);
|
||||||
|
|
||||||
EmitHadd2Hmul2(context, OFmt.F16, srcA, srcB, isAdd: true, op.Dest, op.Sat);
|
EmitHadd2Hmul2(context, OFmt.F16, srcA, srcB, isAdd: true, op.Dest, op.Sat);
|
||||||
}
|
}
|
||||||
@ -292,9 +292,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstHfma2R op = context.GetOp<InstHfma2R>();
|
InstHfma2R op = context.GetOp<InstHfma2R>();
|
||||||
|
|
||||||
var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, false, false);
|
Operand[] srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, false, false);
|
||||||
var srcB = GetHalfSrc(context, op.BSwizzle, op.SrcB, op.NegA, false);
|
Operand[] srcB = GetHalfSrc(context, op.BSwizzle, op.SrcB, op.NegA, false);
|
||||||
var srcC = GetHalfSrc(context, op.CSwizzle, op.SrcC, op.NegC, false);
|
Operand[] srcC = GetHalfSrc(context, op.CSwizzle, op.SrcC, op.NegC, false);
|
||||||
|
|
||||||
EmitHfma2(context, op.OFmt, srcA, srcB, srcC, op.Dest, op.Sat);
|
EmitHfma2(context, op.OFmt, srcA, srcB, srcC, op.Dest, op.Sat);
|
||||||
}
|
}
|
||||||
@ -303,9 +303,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstHfma2I op = context.GetOp<InstHfma2I>();
|
InstHfma2I op = context.GetOp<InstHfma2I>();
|
||||||
|
|
||||||
var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, false, false);
|
Operand[] srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, false, false);
|
||||||
var srcB = GetHalfSrc(context, op.BimmH0, op.BimmH1);
|
Operand[] srcB = GetHalfSrc(context, op.BimmH0, op.BimmH1);
|
||||||
var srcC = GetHalfSrc(context, op.CSwizzle, op.SrcC, op.NegC, false);
|
Operand[] srcC = GetHalfSrc(context, op.CSwizzle, op.SrcC, op.NegC, false);
|
||||||
|
|
||||||
EmitHfma2(context, op.OFmt, srcA, srcB, srcC, op.Dest, op.Sat);
|
EmitHfma2(context, op.OFmt, srcA, srcB, srcC, op.Dest, op.Sat);
|
||||||
}
|
}
|
||||||
@ -314,9 +314,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstHfma2C op = context.GetOp<InstHfma2C>();
|
InstHfma2C op = context.GetOp<InstHfma2C>();
|
||||||
|
|
||||||
var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, false, false);
|
Operand[] srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, false, false);
|
||||||
var srcB = GetHalfSrc(context, HalfSwizzle.F32, op.CbufSlot, op.CbufOffset, op.NegA, false);
|
Operand[] srcB = GetHalfSrc(context, HalfSwizzle.F32, op.CbufSlot, op.CbufOffset, op.NegA, false);
|
||||||
var srcC = GetHalfSrc(context, op.CSwizzle, op.SrcC, op.NegC, false);
|
Operand[] srcC = GetHalfSrc(context, op.CSwizzle, op.SrcC, op.NegC, false);
|
||||||
|
|
||||||
EmitHfma2(context, op.OFmt, srcA, srcB, srcC, op.Dest, op.Sat);
|
EmitHfma2(context, op.OFmt, srcA, srcB, srcC, op.Dest, op.Sat);
|
||||||
}
|
}
|
||||||
@ -325,9 +325,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstHfma2Rc op = context.GetOp<InstHfma2Rc>();
|
InstHfma2Rc op = context.GetOp<InstHfma2Rc>();
|
||||||
|
|
||||||
var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, false, false);
|
Operand[] srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, false, false);
|
||||||
var srcB = GetHalfSrc(context, op.CSwizzle, op.SrcC, op.NegA, false);
|
Operand[] srcB = GetHalfSrc(context, op.CSwizzle, op.SrcC, op.NegA, false);
|
||||||
var srcC = GetHalfSrc(context, HalfSwizzle.F32, op.CbufSlot, op.CbufOffset, op.NegC, false);
|
Operand[] srcC = GetHalfSrc(context, HalfSwizzle.F32, op.CbufSlot, op.CbufOffset, op.NegC, false);
|
||||||
|
|
||||||
EmitHfma2(context, op.OFmt, srcA, srcB, srcC, op.Dest, op.Sat);
|
EmitHfma2(context, op.OFmt, srcA, srcB, srcC, op.Dest, op.Sat);
|
||||||
}
|
}
|
||||||
@ -336,9 +336,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstHfma232i op = context.GetOp<InstHfma232i>();
|
InstHfma232i op = context.GetOp<InstHfma232i>();
|
||||||
|
|
||||||
var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, false, false);
|
Operand[] srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, false, false);
|
||||||
var srcB = GetHalfSrc(context, op.Imm);
|
Operand[] srcB = GetHalfSrc(context, op.Imm);
|
||||||
var srcC = GetHalfSrc(context, HalfSwizzle.F16, op.Dest, op.NegC, false);
|
Operand[] srcC = GetHalfSrc(context, HalfSwizzle.F16, op.Dest, op.NegC, false);
|
||||||
|
|
||||||
EmitHfma2(context, OFmt.F16, srcA, srcB, srcC, op.Dest, saturate: false);
|
EmitHfma2(context, OFmt.F16, srcA, srcB, srcC, op.Dest, saturate: false);
|
||||||
}
|
}
|
||||||
@ -347,8 +347,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstHmul2R op = context.GetOp<InstHmul2R>();
|
InstHmul2R op = context.GetOp<InstHmul2R>();
|
||||||
|
|
||||||
var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, false, op.AbsA);
|
Operand[] srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, false, op.AbsA);
|
||||||
var srcB = GetHalfSrc(context, op.BSwizzle, op.SrcB, op.NegA, op.AbsB);
|
Operand[] srcB = GetHalfSrc(context, op.BSwizzle, op.SrcB, op.NegA, op.AbsB);
|
||||||
|
|
||||||
EmitHadd2Hmul2(context, op.OFmt, srcA, srcB, isAdd: false, op.Dest, op.Sat);
|
EmitHadd2Hmul2(context, op.OFmt, srcA, srcB, isAdd: false, op.Dest, op.Sat);
|
||||||
}
|
}
|
||||||
@ -357,8 +357,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstHmul2I op = context.GetOp<InstHmul2I>();
|
InstHmul2I op = context.GetOp<InstHmul2I>();
|
||||||
|
|
||||||
var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, op.NegA, op.AbsA);
|
Operand[] srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, op.NegA, op.AbsA);
|
||||||
var srcB = GetHalfSrc(context, op.BimmH0, op.BimmH1);
|
Operand[] srcB = GetHalfSrc(context, op.BimmH0, op.BimmH1);
|
||||||
|
|
||||||
EmitHadd2Hmul2(context, op.OFmt, srcA, srcB, isAdd: false, op.Dest, op.Sat);
|
EmitHadd2Hmul2(context, op.OFmt, srcA, srcB, isAdd: false, op.Dest, op.Sat);
|
||||||
}
|
}
|
||||||
@ -367,8 +367,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstHmul2C op = context.GetOp<InstHmul2C>();
|
InstHmul2C op = context.GetOp<InstHmul2C>();
|
||||||
|
|
||||||
var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, false, op.AbsA);
|
Operand[] srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, false, op.AbsA);
|
||||||
var srcB = GetHalfSrc(context, HalfSwizzle.F32, op.CbufSlot, op.CbufOffset, op.NegA, op.AbsB);
|
Operand[] srcB = GetHalfSrc(context, HalfSwizzle.F32, op.CbufSlot, op.CbufOffset, op.NegA, op.AbsB);
|
||||||
|
|
||||||
EmitHadd2Hmul2(context, op.OFmt, srcA, srcB, isAdd: false, op.Dest, op.Sat);
|
EmitHadd2Hmul2(context, op.OFmt, srcA, srcB, isAdd: false, op.Dest, op.Sat);
|
||||||
}
|
}
|
||||||
@ -377,8 +377,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstHmul232i op = context.GetOp<InstHmul232i>();
|
InstHmul232i op = context.GetOp<InstHmul232i>();
|
||||||
|
|
||||||
var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, false, false);
|
Operand[] srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, false, false);
|
||||||
var srcB = GetHalfSrc(context, op.Imm32);
|
Operand[] srcB = GetHalfSrc(context, op.Imm32);
|
||||||
|
|
||||||
EmitHadd2Hmul2(context, OFmt.F16, srcA, srcB, isAdd: false, op.Dest, op.Sat);
|
EmitHadd2Hmul2(context, OFmt.F16, srcA, srcB, isAdd: false, op.Dest, op.Sat);
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstDsetR op = context.GetOp<InstDsetR>();
|
InstDsetR op = context.GetOp<InstDsetR>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
Operand srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
||||||
var srcB = GetSrcReg(context, op.SrcB, isFP64: true);
|
Operand srcB = GetSrcReg(context, op.SrcB, isFP64: true);
|
||||||
|
|
||||||
EmitFset(
|
EmitFset(
|
||||||
context,
|
context,
|
||||||
@ -39,8 +39,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstDsetI op = context.GetOp<InstDsetI>();
|
InstDsetI op = context.GetOp<InstDsetI>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
Operand srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
||||||
var srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20), isFP64: true);
|
Operand srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20), isFP64: true);
|
||||||
|
|
||||||
EmitFset(
|
EmitFset(
|
||||||
context,
|
context,
|
||||||
@ -64,8 +64,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstDsetC op = context.GetOp<InstDsetC>();
|
InstDsetC op = context.GetOp<InstDsetC>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
Operand srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
||||||
var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset, isFP64: true);
|
Operand srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset, isFP64: true);
|
||||||
|
|
||||||
EmitFset(
|
EmitFset(
|
||||||
context,
|
context,
|
||||||
@ -89,8 +89,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstDsetpR op = context.GetOp<InstDsetpR>();
|
InstDsetpR op = context.GetOp<InstDsetpR>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
Operand srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
||||||
var srcB = GetSrcReg(context, op.SrcB, isFP64: true);
|
Operand srcB = GetSrcReg(context, op.SrcB, isFP64: true);
|
||||||
|
|
||||||
EmitFsetp(
|
EmitFsetp(
|
||||||
context,
|
context,
|
||||||
@ -114,8 +114,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstDsetpI op = context.GetOp<InstDsetpI>();
|
InstDsetpI op = context.GetOp<InstDsetpI>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
Operand srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
||||||
var srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20), isFP64: true);
|
Operand srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20), isFP64: true);
|
||||||
|
|
||||||
EmitFsetp(
|
EmitFsetp(
|
||||||
context,
|
context,
|
||||||
@ -139,8 +139,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstDsetpC op = context.GetOp<InstDsetpC>();
|
InstDsetpC op = context.GetOp<InstDsetpC>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
Operand srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
||||||
var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset, isFP64: true);
|
Operand srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset, isFP64: true);
|
||||||
|
|
||||||
EmitFsetp(
|
EmitFsetp(
|
||||||
context,
|
context,
|
||||||
@ -164,9 +164,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstFcmpR op = context.GetOp<InstFcmpR>();
|
InstFcmpR op = context.GetOp<InstFcmpR>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcReg(context, op.SrcB);
|
Operand srcB = GetSrcReg(context, op.SrcB);
|
||||||
var srcC = GetSrcReg(context, op.SrcC);
|
Operand srcC = GetSrcReg(context, op.SrcC);
|
||||||
|
|
||||||
EmitFcmp(context, op.FComp, srcA, srcB, srcC, op.Dest);
|
EmitFcmp(context, op.FComp, srcA, srcB, srcC, op.Dest);
|
||||||
}
|
}
|
||||||
@ -175,9 +175,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstFcmpI op = context.GetOp<InstFcmpI>();
|
InstFcmpI op = context.GetOp<InstFcmpI>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20));
|
Operand srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20));
|
||||||
var srcC = GetSrcReg(context, op.SrcC);
|
Operand srcC = GetSrcReg(context, op.SrcC);
|
||||||
|
|
||||||
EmitFcmp(context, op.FComp, srcA, srcB, srcC, op.Dest);
|
EmitFcmp(context, op.FComp, srcA, srcB, srcC, op.Dest);
|
||||||
}
|
}
|
||||||
@ -186,9 +186,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstFcmpC op = context.GetOp<InstFcmpC>();
|
InstFcmpC op = context.GetOp<InstFcmpC>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
Operand srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
||||||
var srcC = GetSrcReg(context, op.SrcC);
|
Operand srcC = GetSrcReg(context, op.SrcC);
|
||||||
|
|
||||||
EmitFcmp(context, op.FComp, srcA, srcB, srcC, op.Dest);
|
EmitFcmp(context, op.FComp, srcA, srcB, srcC, op.Dest);
|
||||||
}
|
}
|
||||||
@ -197,9 +197,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstFcmpRc op = context.GetOp<InstFcmpRc>();
|
InstFcmpRc op = context.GetOp<InstFcmpRc>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcReg(context, op.SrcC);
|
Operand srcB = GetSrcReg(context, op.SrcC);
|
||||||
var srcC = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
Operand srcC = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
||||||
|
|
||||||
EmitFcmp(context, op.FComp, srcA, srcB, srcC, op.Dest);
|
EmitFcmp(context, op.FComp, srcA, srcB, srcC, op.Dest);
|
||||||
}
|
}
|
||||||
@ -208,8 +208,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstFsetR op = context.GetOp<InstFsetR>();
|
InstFsetR op = context.GetOp<InstFsetR>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcReg(context, op.SrcB);
|
Operand srcB = GetSrcReg(context, op.SrcB);
|
||||||
|
|
||||||
EmitFset(context, op.FComp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.Dest, op.AbsA, op.AbsB, op.NegA, op.NegB, op.BVal, op.WriteCC);
|
EmitFset(context, op.FComp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.Dest, op.AbsA, op.AbsB, op.NegA, op.NegB, op.BVal, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -218,8 +218,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstFsetC op = context.GetOp<InstFsetC>();
|
InstFsetC op = context.GetOp<InstFsetC>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
Operand srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
||||||
|
|
||||||
EmitFset(context, op.FComp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.Dest, op.AbsA, op.AbsB, op.NegA, op.NegB, op.BVal, op.WriteCC);
|
EmitFset(context, op.FComp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.Dest, op.AbsA, op.AbsB, op.NegA, op.NegB, op.BVal, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -228,8 +228,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstFsetI op = context.GetOp<InstFsetI>();
|
InstFsetI op = context.GetOp<InstFsetI>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20));
|
Operand srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20));
|
||||||
|
|
||||||
EmitFset(context, op.FComp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.Dest, op.AbsA, op.AbsB, op.NegA, op.NegB, op.BVal, op.WriteCC);
|
EmitFset(context, op.FComp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.Dest, op.AbsA, op.AbsB, op.NegA, op.NegB, op.BVal, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -238,8 +238,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstFsetpR op = context.GetOp<InstFsetpR>();
|
InstFsetpR op = context.GetOp<InstFsetpR>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcReg(context, op.SrcB);
|
Operand srcB = GetSrcReg(context, op.SrcB);
|
||||||
|
|
||||||
EmitFsetp(
|
EmitFsetp(
|
||||||
context,
|
context,
|
||||||
@ -262,8 +262,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstFsetpI op = context.GetOp<InstFsetpI>();
|
InstFsetpI op = context.GetOp<InstFsetpI>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20));
|
Operand srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20));
|
||||||
|
|
||||||
EmitFsetp(
|
EmitFsetp(
|
||||||
context,
|
context,
|
||||||
@ -286,8 +286,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstFsetpC op = context.GetOp<InstFsetpC>();
|
InstFsetpC op = context.GetOp<InstFsetpC>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
Operand srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
||||||
|
|
||||||
EmitFsetp(
|
EmitFsetp(
|
||||||
context,
|
context,
|
||||||
@ -310,8 +310,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstHset2R op = context.GetOp<InstHset2R>();
|
InstHset2R op = context.GetOp<InstHset2R>();
|
||||||
|
|
||||||
var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, op.NegA, op.AbsA);
|
Operand[] srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, op.NegA, op.AbsA);
|
||||||
var srcB = GetHalfSrc(context, op.BSwizzle, op.SrcB, op.NegB, op.AbsB);
|
Operand[] srcB = GetHalfSrc(context, op.BSwizzle, op.SrcB, op.NegB, op.AbsB);
|
||||||
|
|
||||||
EmitHset2(context, op.Cmp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.Dest, op.Bval);
|
EmitHset2(context, op.Cmp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.Dest, op.Bval);
|
||||||
}
|
}
|
||||||
@ -320,8 +320,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstHset2I op = context.GetOp<InstHset2I>();
|
InstHset2I op = context.GetOp<InstHset2I>();
|
||||||
|
|
||||||
var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, op.NegA, op.AbsA);
|
Operand[] srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, op.NegA, op.AbsA);
|
||||||
var srcB = GetHalfSrc(context, op.BimmH0, op.BimmH1);
|
Operand[] srcB = GetHalfSrc(context, op.BimmH0, op.BimmH1);
|
||||||
|
|
||||||
EmitHset2(context, op.Cmp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.Dest, op.Bval);
|
EmitHset2(context, op.Cmp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.Dest, op.Bval);
|
||||||
}
|
}
|
||||||
@ -330,8 +330,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstHset2C op = context.GetOp<InstHset2C>();
|
InstHset2C op = context.GetOp<InstHset2C>();
|
||||||
|
|
||||||
var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, op.NegA, op.AbsA);
|
Operand[] srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, op.NegA, op.AbsA);
|
||||||
var srcB = GetHalfSrc(context, HalfSwizzle.F32, op.CbufSlot, op.CbufOffset, op.NegB, false);
|
Operand[] srcB = GetHalfSrc(context, HalfSwizzle.F32, op.CbufSlot, op.CbufOffset, op.NegB, false);
|
||||||
|
|
||||||
EmitHset2(context, op.Cmp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.Dest, op.Bval);
|
EmitHset2(context, op.Cmp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.Dest, op.Bval);
|
||||||
}
|
}
|
||||||
@ -340,8 +340,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstHsetp2R op = context.GetOp<InstHsetp2R>();
|
InstHsetp2R op = context.GetOp<InstHsetp2R>();
|
||||||
|
|
||||||
var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, op.NegA, op.AbsA);
|
Operand[] srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, op.NegA, op.AbsA);
|
||||||
var srcB = GetHalfSrc(context, op.BSwizzle, op.SrcB, op.NegB, op.AbsB);
|
Operand[] srcB = GetHalfSrc(context, op.BSwizzle, op.SrcB, op.NegB, op.AbsB);
|
||||||
|
|
||||||
EmitHsetp2(context, op.FComp2, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.DestPred, op.DestPredInv, op.HAnd);
|
EmitHsetp2(context, op.FComp2, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.DestPred, op.DestPredInv, op.HAnd);
|
||||||
}
|
}
|
||||||
@ -350,8 +350,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstHsetp2I op = context.GetOp<InstHsetp2I>();
|
InstHsetp2I op = context.GetOp<InstHsetp2I>();
|
||||||
|
|
||||||
var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, op.NegA, op.AbsA);
|
Operand[] srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, op.NegA, op.AbsA);
|
||||||
var srcB = GetHalfSrc(context, op.BimmH0, op.BimmH1);
|
Operand[] srcB = GetHalfSrc(context, op.BimmH0, op.BimmH1);
|
||||||
|
|
||||||
EmitHsetp2(context, op.FComp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.DestPred, op.DestPredInv, op.HAnd);
|
EmitHsetp2(context, op.FComp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.DestPred, op.DestPredInv, op.HAnd);
|
||||||
}
|
}
|
||||||
@ -360,8 +360,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstHsetp2C op = context.GetOp<InstHsetp2C>();
|
InstHsetp2C op = context.GetOp<InstHsetp2C>();
|
||||||
|
|
||||||
var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, op.NegA, op.AbsA);
|
Operand[] srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, op.NegA, op.AbsA);
|
||||||
var srcB = GetHalfSrc(context, HalfSwizzle.F32, op.CbufSlot, op.CbufOffset, op.NegB, op.AbsB);
|
Operand[] srcB = GetHalfSrc(context, HalfSwizzle.F32, op.CbufSlot, op.CbufOffset, op.NegB, op.AbsB);
|
||||||
|
|
||||||
EmitHsetp2(context, op.FComp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.DestPred, op.DestPredInv, op.HAnd);
|
EmitHsetp2(context, op.FComp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.DestPred, op.DestPredInv, op.HAnd);
|
||||||
}
|
}
|
||||||
@ -545,7 +545,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var inst = (cond & ~FComp.Nan) switch
|
Instruction inst = (cond & ~FComp.Nan) switch
|
||||||
{
|
{
|
||||||
FComp.Lt => Instruction.CompareLess,
|
FComp.Lt => Instruction.CompareLess,
|
||||||
FComp.Eq => Instruction.CompareEqual,
|
FComp.Eq => Instruction.CompareEqual,
|
||||||
|
@ -13,9 +13,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstDmnmxR op = context.GetOp<InstDmnmxR>();
|
InstDmnmxR op = context.GetOp<InstDmnmxR>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
Operand srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
||||||
var srcB = GetSrcReg(context, op.SrcB, isFP64: true);
|
Operand srcB = GetSrcReg(context, op.SrcB, isFP64: true);
|
||||||
var srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
|
Operand srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
|
||||||
|
|
||||||
EmitFmnmx(context, srcA, srcB, srcPred, op.Dest, op.AbsA, op.AbsB, op.NegA, op.NegB, op.WriteCC, isFP64: true);
|
EmitFmnmx(context, srcA, srcB, srcPred, op.Dest, op.AbsA, op.AbsB, op.NegA, op.NegB, op.WriteCC, isFP64: true);
|
||||||
}
|
}
|
||||||
@ -24,9 +24,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstDmnmxI op = context.GetOp<InstDmnmxI>();
|
InstDmnmxI op = context.GetOp<InstDmnmxI>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
Operand srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
||||||
var srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20), isFP64: true);
|
Operand srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20), isFP64: true);
|
||||||
var srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
|
Operand srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
|
||||||
|
|
||||||
EmitFmnmx(context, srcA, srcB, srcPred, op.Dest, op.AbsA, op.AbsB, op.NegA, op.NegB, op.WriteCC, isFP64: true);
|
EmitFmnmx(context, srcA, srcB, srcPred, op.Dest, op.AbsA, op.AbsB, op.NegA, op.NegB, op.WriteCC, isFP64: true);
|
||||||
}
|
}
|
||||||
@ -35,9 +35,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstDmnmxC op = context.GetOp<InstDmnmxC>();
|
InstDmnmxC op = context.GetOp<InstDmnmxC>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
Operand srcA = GetSrcReg(context, op.SrcA, isFP64: true);
|
||||||
var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset, isFP64: true);
|
Operand srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset, isFP64: true);
|
||||||
var srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
|
Operand srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
|
||||||
|
|
||||||
EmitFmnmx(context, srcA, srcB, srcPred, op.Dest, op.AbsA, op.AbsB, op.NegA, op.NegB, op.WriteCC, isFP64: true);
|
EmitFmnmx(context, srcA, srcB, srcPred, op.Dest, op.AbsA, op.AbsB, op.NegA, op.NegB, op.WriteCC, isFP64: true);
|
||||||
}
|
}
|
||||||
@ -46,9 +46,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstFmnmxR op = context.GetOp<InstFmnmxR>();
|
InstFmnmxR op = context.GetOp<InstFmnmxR>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcReg(context, op.SrcB);
|
Operand srcB = GetSrcReg(context, op.SrcB);
|
||||||
var srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
|
Operand srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
|
||||||
|
|
||||||
EmitFmnmx(context, srcA, srcB, srcPred, op.Dest, op.AbsA, op.AbsB, op.NegA, op.NegB, op.WriteCC);
|
EmitFmnmx(context, srcA, srcB, srcPred, op.Dest, op.AbsA, op.AbsB, op.NegA, op.NegB, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -57,9 +57,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstFmnmxI op = context.GetOp<InstFmnmxI>();
|
InstFmnmxI op = context.GetOp<InstFmnmxI>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20));
|
Operand srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20));
|
||||||
var srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
|
Operand srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
|
||||||
|
|
||||||
EmitFmnmx(context, srcA, srcB, srcPred, op.Dest, op.AbsA, op.AbsB, op.NegA, op.NegB, op.WriteCC);
|
EmitFmnmx(context, srcA, srcB, srcPred, op.Dest, op.AbsA, op.AbsB, op.NegA, op.NegB, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -68,9 +68,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstFmnmxC op = context.GetOp<InstFmnmxC>();
|
InstFmnmxC op = context.GetOp<InstFmnmxC>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
Operand srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
||||||
var srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
|
Operand srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
|
||||||
|
|
||||||
EmitFmnmx(context, srcA, srcB, srcPred, op.Dest, op.AbsA, op.AbsB, op.NegA, op.NegB, op.WriteCC);
|
EmitFmnmx(context, srcA, srcB, srcPred, op.Dest, op.AbsA, op.AbsB, op.NegA, op.NegB, op.WriteCC);
|
||||||
}
|
}
|
||||||
|
@ -39,13 +39,13 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
|
|
||||||
Operand address = context.IAdd(Register(op.SrcA, RegisterType.Gpr), Const(offset));
|
Operand address = context.IAdd(Register(op.SrcA, RegisterType.Gpr), Const(offset));
|
||||||
|
|
||||||
var targets = context.CurrBlock.Successors.Skip(startIndex);
|
IEnumerable<Block> targets = context.CurrBlock.Successors.Skip(startIndex);
|
||||||
|
|
||||||
bool allTargetsSinglePred = true;
|
bool allTargetsSinglePred = true;
|
||||||
int total = context.CurrBlock.Successors.Count - startIndex;
|
int total = context.CurrBlock.Successors.Count - startIndex;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
foreach (var target in targets.OrderBy(x => x.Address))
|
foreach (Block target in targets.OrderBy(x => x.Address))
|
||||||
{
|
{
|
||||||
if (++count < total && (target.Predecessors.Count > 1 || target.Address <= context.CurrBlock.Address))
|
if (++count < total && (target.Predecessors.Count > 1 || target.Address <= context.CurrBlock.Address))
|
||||||
{
|
{
|
||||||
@ -64,7 +64,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
// since it will be too late to insert a label, but this is something that can be improved
|
// since it will be too late to insert a label, but this is something that can be improved
|
||||||
// in the future if necessary.
|
// in the future if necessary.
|
||||||
|
|
||||||
var sortedTargets = targets.OrderBy(x => x.Address);
|
IOrderedEnumerable<Block> sortedTargets = targets.OrderBy(x => x.Address);
|
||||||
|
|
||||||
Block currentTarget = null;
|
Block currentTarget = null;
|
||||||
ulong firstTargetAddress = 0;
|
ulong firstTargetAddress = 0;
|
||||||
@ -93,7 +93,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
// Emit the branches sequentially.
|
// Emit the branches sequentially.
|
||||||
// This generates slightly worse code, but should work for all cases.
|
// This generates slightly worse code, but should work for all cases.
|
||||||
|
|
||||||
var sortedTargets = targets.OrderByDescending(x => x.Address);
|
IOrderedEnumerable<Block> sortedTargets = targets.OrderByDescending(x => x.Address);
|
||||||
ulong lastTargetAddress = ulong.MaxValue;
|
ulong lastTargetAddress = ulong.MaxValue;
|
||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
@ -238,7 +238,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
|
|
||||||
private static void EmitPbkPcntSsy(EmitterContext context)
|
private static void EmitPbkPcntSsy(EmitterContext context)
|
||||||
{
|
{
|
||||||
var consumers = context.CurrBlock.PushOpCodes.First(x => x.Op.Address == context.CurrOp.Address).Consumers;
|
Dictionary<Block, Operand> consumers = context.CurrBlock.PushOpCodes.First(x => x.Op.Address == context.CurrOp.Address).Consumers;
|
||||||
|
|
||||||
foreach (KeyValuePair<Block, Operand> kv in consumers)
|
foreach (KeyValuePair<Block, Operand> kv in consumers)
|
||||||
{
|
{
|
||||||
@ -253,7 +253,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
|
|
||||||
private static void EmitBrkContSync(EmitterContext context)
|
private static void EmitBrkContSync(EmitterContext context)
|
||||||
{
|
{
|
||||||
var targets = context.CurrBlock.SyncTargets;
|
Dictionary<ulong, SyncTarget> targets = context.CurrBlock.SyncTargets;
|
||||||
|
|
||||||
if (targets.Count == 1)
|
if (targets.Count == 1)
|
||||||
{
|
{
|
||||||
|
@ -14,8 +14,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstIaddR op = context.GetOp<InstIaddR>();
|
InstIaddR op = context.GetOp<InstIaddR>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcReg(context, op.SrcB);
|
Operand srcB = GetSrcReg(context, op.SrcB);
|
||||||
|
|
||||||
EmitIadd(context, srcA, srcB, op.Dest, op.AvgMode, op.X, op.WriteCC);
|
EmitIadd(context, srcA, srcB, op.Dest, op.AvgMode, op.X, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -24,8 +24,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstIaddI op = context.GetOp<InstIaddI>();
|
InstIaddI op = context.GetOp<InstIaddI>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
|
Operand srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
|
||||||
|
|
||||||
EmitIadd(context, srcA, srcB, op.Dest, op.AvgMode, op.X, op.WriteCC);
|
EmitIadd(context, srcA, srcB, op.Dest, op.AvgMode, op.X, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -34,8 +34,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstIaddC op = context.GetOp<InstIaddC>();
|
InstIaddC op = context.GetOp<InstIaddC>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
Operand srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
||||||
|
|
||||||
EmitIadd(context, srcA, srcB, op.Dest, op.AvgMode, op.X, op.WriteCC);
|
EmitIadd(context, srcA, srcB, op.Dest, op.AvgMode, op.X, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -44,8 +44,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstIadd32i op = context.GetOp<InstIadd32i>();
|
InstIadd32i op = context.GetOp<InstIadd32i>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcImm(context, op.Imm32);
|
Operand srcB = GetSrcImm(context, op.Imm32);
|
||||||
|
|
||||||
EmitIadd(context, srcA, srcB, op.Dest, op.AvgMode, op.X, op.WriteCC);
|
EmitIadd(context, srcA, srcB, op.Dest, op.AvgMode, op.X, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -54,9 +54,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstIadd3R op = context.GetOp<InstIadd3R>();
|
InstIadd3R op = context.GetOp<InstIadd3R>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcReg(context, op.SrcB);
|
Operand srcB = GetSrcReg(context, op.SrcB);
|
||||||
var srcC = GetSrcReg(context, op.SrcC);
|
Operand srcC = GetSrcReg(context, op.SrcC);
|
||||||
|
|
||||||
EmitIadd3(context, op.Lrs, srcA, srcB, srcC, op.Apart, op.Bpart, op.Cpart, op.Dest, op.NegA, op.NegB, op.NegC);
|
EmitIadd3(context, op.Lrs, srcA, srcB, srcC, op.Apart, op.Bpart, op.Cpart, op.Dest, op.NegA, op.NegB, op.NegC);
|
||||||
}
|
}
|
||||||
@ -65,9 +65,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstIadd3I op = context.GetOp<InstIadd3I>();
|
InstIadd3I op = context.GetOp<InstIadd3I>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
|
Operand srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
|
||||||
var srcC = GetSrcReg(context, op.SrcC);
|
Operand srcC = GetSrcReg(context, op.SrcC);
|
||||||
|
|
||||||
EmitIadd3(context, Lrs.None, srcA, srcB, srcC, HalfSelect.B32, HalfSelect.B32, HalfSelect.B32, op.Dest, op.NegA, op.NegB, op.NegC);
|
EmitIadd3(context, Lrs.None, srcA, srcB, srcC, HalfSelect.B32, HalfSelect.B32, HalfSelect.B32, op.Dest, op.NegA, op.NegB, op.NegC);
|
||||||
}
|
}
|
||||||
@ -76,9 +76,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstIadd3C op = context.GetOp<InstIadd3C>();
|
InstIadd3C op = context.GetOp<InstIadd3C>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
Operand srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
||||||
var srcC = GetSrcReg(context, op.SrcC);
|
Operand srcC = GetSrcReg(context, op.SrcC);
|
||||||
|
|
||||||
EmitIadd3(context, Lrs.None, srcA, srcB, srcC, HalfSelect.B32, HalfSelect.B32, HalfSelect.B32, op.Dest, op.NegA, op.NegB, op.NegC);
|
EmitIadd3(context, Lrs.None, srcA, srcB, srcC, HalfSelect.B32, HalfSelect.B32, HalfSelect.B32, op.Dest, op.NegA, op.NegB, op.NegC);
|
||||||
}
|
}
|
||||||
@ -87,9 +87,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstImadR op = context.GetOp<InstImadR>();
|
InstImadR op = context.GetOp<InstImadR>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcReg(context, op.SrcB);
|
Operand srcB = GetSrcReg(context, op.SrcB);
|
||||||
var srcC = GetSrcReg(context, op.SrcC);
|
Operand srcC = GetSrcReg(context, op.SrcC);
|
||||||
|
|
||||||
EmitImad(context, srcA, srcB, srcC, op.Dest, op.AvgMode, op.ASigned, op.BSigned, op.Hilo);
|
EmitImad(context, srcA, srcB, srcC, op.Dest, op.AvgMode, op.ASigned, op.BSigned, op.Hilo);
|
||||||
}
|
}
|
||||||
@ -98,9 +98,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstImadI op = context.GetOp<InstImadI>();
|
InstImadI op = context.GetOp<InstImadI>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
|
Operand srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
|
||||||
var srcC = GetSrcReg(context, op.SrcC);
|
Operand srcC = GetSrcReg(context, op.SrcC);
|
||||||
|
|
||||||
EmitImad(context, srcA, srcB, srcC, op.Dest, op.AvgMode, op.ASigned, op.BSigned, op.Hilo);
|
EmitImad(context, srcA, srcB, srcC, op.Dest, op.AvgMode, op.ASigned, op.BSigned, op.Hilo);
|
||||||
}
|
}
|
||||||
@ -109,9 +109,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstImadC op = context.GetOp<InstImadC>();
|
InstImadC op = context.GetOp<InstImadC>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
Operand srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
||||||
var srcC = GetSrcReg(context, op.SrcC);
|
Operand srcC = GetSrcReg(context, op.SrcC);
|
||||||
|
|
||||||
EmitImad(context, srcA, srcB, srcC, op.Dest, op.AvgMode, op.ASigned, op.BSigned, op.Hilo);
|
EmitImad(context, srcA, srcB, srcC, op.Dest, op.AvgMode, op.ASigned, op.BSigned, op.Hilo);
|
||||||
}
|
}
|
||||||
@ -120,9 +120,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstImadRc op = context.GetOp<InstImadRc>();
|
InstImadRc op = context.GetOp<InstImadRc>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcReg(context, op.SrcC);
|
Operand srcB = GetSrcReg(context, op.SrcC);
|
||||||
var srcC = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
Operand srcC = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
||||||
|
|
||||||
EmitImad(context, srcA, srcB, srcC, op.Dest, op.AvgMode, op.ASigned, op.BSigned, op.Hilo);
|
EmitImad(context, srcA, srcB, srcC, op.Dest, op.AvgMode, op.ASigned, op.BSigned, op.Hilo);
|
||||||
}
|
}
|
||||||
@ -131,9 +131,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstImad32i op = context.GetOp<InstImad32i>();
|
InstImad32i op = context.GetOp<InstImad32i>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcImm(context, op.Imm32);
|
Operand srcB = GetSrcImm(context, op.Imm32);
|
||||||
var srcC = GetSrcReg(context, op.Dest);
|
Operand srcC = GetSrcReg(context, op.Dest);
|
||||||
|
|
||||||
EmitImad(context, srcA, srcB, srcC, op.Dest, op.AvgMode, op.ASigned, op.BSigned, op.Hilo);
|
EmitImad(context, srcA, srcB, srcC, op.Dest, op.AvgMode, op.ASigned, op.BSigned, op.Hilo);
|
||||||
}
|
}
|
||||||
@ -142,8 +142,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstImulR op = context.GetOp<InstImulR>();
|
InstImulR op = context.GetOp<InstImulR>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcReg(context, op.SrcB);
|
Operand srcB = GetSrcReg(context, op.SrcB);
|
||||||
|
|
||||||
EmitImad(context, srcA, srcB, Const(0), op.Dest, AvgMode.NoNeg, op.ASigned, op.BSigned, op.Hilo);
|
EmitImad(context, srcA, srcB, Const(0), op.Dest, AvgMode.NoNeg, op.ASigned, op.BSigned, op.Hilo);
|
||||||
}
|
}
|
||||||
@ -152,8 +152,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstImulI op = context.GetOp<InstImulI>();
|
InstImulI op = context.GetOp<InstImulI>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
|
Operand srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
|
||||||
|
|
||||||
EmitImad(context, srcA, srcB, Const(0), op.Dest, AvgMode.NoNeg, op.ASigned, op.BSigned, op.Hilo);
|
EmitImad(context, srcA, srcB, Const(0), op.Dest, AvgMode.NoNeg, op.ASigned, op.BSigned, op.Hilo);
|
||||||
}
|
}
|
||||||
@ -162,8 +162,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstImulC op = context.GetOp<InstImulC>();
|
InstImulC op = context.GetOp<InstImulC>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
Operand srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
||||||
|
|
||||||
EmitImad(context, srcA, srcB, Const(0), op.Dest, AvgMode.NoNeg, op.ASigned, op.BSigned, op.Hilo);
|
EmitImad(context, srcA, srcB, Const(0), op.Dest, AvgMode.NoNeg, op.ASigned, op.BSigned, op.Hilo);
|
||||||
}
|
}
|
||||||
@ -172,8 +172,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstImul32i op = context.GetOp<InstImul32i>();
|
InstImul32i op = context.GetOp<InstImul32i>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcImm(context, op.Imm32);
|
Operand srcB = GetSrcImm(context, op.Imm32);
|
||||||
|
|
||||||
EmitImad(context, srcA, srcB, Const(0), op.Dest, AvgMode.NoNeg, op.ASigned, op.BSigned, op.Hilo);
|
EmitImad(context, srcA, srcB, Const(0), op.Dest, AvgMode.NoNeg, op.ASigned, op.BSigned, op.Hilo);
|
||||||
}
|
}
|
||||||
@ -182,8 +182,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstIscaddR op = context.GetOp<InstIscaddR>();
|
InstIscaddR op = context.GetOp<InstIscaddR>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcReg(context, op.SrcB);
|
Operand srcB = GetSrcReg(context, op.SrcB);
|
||||||
|
|
||||||
EmitIscadd(context, srcA, srcB, op.Dest, op.Imm5, op.AvgMode, op.WriteCC);
|
EmitIscadd(context, srcA, srcB, op.Dest, op.Imm5, op.AvgMode, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -192,8 +192,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstIscaddI op = context.GetOp<InstIscaddI>();
|
InstIscaddI op = context.GetOp<InstIscaddI>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
|
Operand srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
|
||||||
|
|
||||||
EmitIscadd(context, srcA, srcB, op.Dest, op.Imm5, op.AvgMode, op.WriteCC);
|
EmitIscadd(context, srcA, srcB, op.Dest, op.Imm5, op.AvgMode, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -202,8 +202,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstIscaddC op = context.GetOp<InstIscaddC>();
|
InstIscaddC op = context.GetOp<InstIscaddC>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
Operand srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
||||||
|
|
||||||
EmitIscadd(context, srcA, srcB, op.Dest, op.Imm5, op.AvgMode, op.WriteCC);
|
EmitIscadd(context, srcA, srcB, op.Dest, op.Imm5, op.AvgMode, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -212,8 +212,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstIscadd32i op = context.GetOp<InstIscadd32i>();
|
InstIscadd32i op = context.GetOp<InstIscadd32i>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcImm(context, op.Imm32);
|
Operand srcB = GetSrcImm(context, op.Imm32);
|
||||||
|
|
||||||
EmitIscadd(context, srcA, srcB, op.Dest, op.Imm5, AvgMode.NoNeg, op.WriteCC);
|
EmitIscadd(context, srcA, srcB, op.Dest, op.Imm5, AvgMode.NoNeg, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -222,8 +222,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstLeaR op = context.GetOp<InstLeaR>();
|
InstLeaR op = context.GetOp<InstLeaR>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcReg(context, op.SrcB);
|
Operand srcB = GetSrcReg(context, op.SrcB);
|
||||||
|
|
||||||
EmitLea(context, srcA, srcB, op.Dest, op.NegA, op.ImmU5);
|
EmitLea(context, srcA, srcB, op.Dest, op.NegA, op.ImmU5);
|
||||||
}
|
}
|
||||||
@ -232,8 +232,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstLeaI op = context.GetOp<InstLeaI>();
|
InstLeaI op = context.GetOp<InstLeaI>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
|
Operand srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
|
||||||
|
|
||||||
EmitLea(context, srcA, srcB, op.Dest, op.NegA, op.ImmU5);
|
EmitLea(context, srcA, srcB, op.Dest, op.NegA, op.ImmU5);
|
||||||
}
|
}
|
||||||
@ -242,8 +242,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstLeaC op = context.GetOp<InstLeaC>();
|
InstLeaC op = context.GetOp<InstLeaC>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
Operand srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
||||||
|
|
||||||
EmitLea(context, srcA, srcB, op.Dest, op.NegA, op.ImmU5);
|
EmitLea(context, srcA, srcB, op.Dest, op.NegA, op.ImmU5);
|
||||||
}
|
}
|
||||||
@ -252,9 +252,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstLeaHiR op = context.GetOp<InstLeaHiR>();
|
InstLeaHiR op = context.GetOp<InstLeaHiR>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcReg(context, op.SrcB);
|
Operand srcB = GetSrcReg(context, op.SrcB);
|
||||||
var srcC = GetSrcReg(context, op.SrcC);
|
Operand srcC = GetSrcReg(context, op.SrcC);
|
||||||
|
|
||||||
EmitLeaHi(context, srcA, srcB, srcC, op.Dest, op.NegA, op.ImmU5);
|
EmitLeaHi(context, srcA, srcB, srcC, op.Dest, op.NegA, op.ImmU5);
|
||||||
}
|
}
|
||||||
@ -263,9 +263,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstLeaHiC op = context.GetOp<InstLeaHiC>();
|
InstLeaHiC op = context.GetOp<InstLeaHiC>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
Operand srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
||||||
var srcC = GetSrcReg(context, op.SrcC);
|
Operand srcC = GetSrcReg(context, op.SrcC);
|
||||||
|
|
||||||
EmitLeaHi(context, srcA, srcB, srcC, op.Dest, op.NegA, op.ImmU5);
|
EmitLeaHi(context, srcA, srcB, srcC, op.Dest, op.NegA, op.ImmU5);
|
||||||
}
|
}
|
||||||
@ -274,9 +274,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstXmadR op = context.GetOp<InstXmadR>();
|
InstXmadR op = context.GetOp<InstXmadR>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcReg(context, op.SrcB);
|
Operand srcB = GetSrcReg(context, op.SrcB);
|
||||||
var srcC = GetSrcReg(context, op.SrcC);
|
Operand srcC = GetSrcReg(context, op.SrcC);
|
||||||
|
|
||||||
EmitXmad(context, op.XmadCop, srcA, srcB, srcC, op.Dest, op.ASigned, op.BSigned, op.HiloA, op.HiloB, op.Psl, op.Mrg, op.X, op.WriteCC);
|
EmitXmad(context, op.XmadCop, srcA, srcB, srcC, op.Dest, op.ASigned, op.BSigned, op.HiloA, op.HiloB, op.Psl, op.Mrg, op.X, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -285,9 +285,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstXmadI op = context.GetOp<InstXmadI>();
|
InstXmadI op = context.GetOp<InstXmadI>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcImm(context, op.Imm16);
|
Operand srcB = GetSrcImm(context, op.Imm16);
|
||||||
var srcC = GetSrcReg(context, op.SrcC);
|
Operand srcC = GetSrcReg(context, op.SrcC);
|
||||||
|
|
||||||
EmitXmad(context, op.XmadCop, srcA, srcB, srcC, op.Dest, op.ASigned, op.BSigned, op.HiloA, false, op.Psl, op.Mrg, op.X, op.WriteCC);
|
EmitXmad(context, op.XmadCop, srcA, srcB, srcC, op.Dest, op.ASigned, op.BSigned, op.HiloA, false, op.Psl, op.Mrg, op.X, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -296,9 +296,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstXmadC op = context.GetOp<InstXmadC>();
|
InstXmadC op = context.GetOp<InstXmadC>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
Operand srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
||||||
var srcC = GetSrcReg(context, op.SrcC);
|
Operand srcC = GetSrcReg(context, op.SrcC);
|
||||||
|
|
||||||
EmitXmad(context, op.XmadCop, srcA, srcB, srcC, op.Dest, op.ASigned, op.BSigned, op.HiloA, op.HiloB, op.Psl, op.Mrg, op.X, op.WriteCC);
|
EmitXmad(context, op.XmadCop, srcA, srcB, srcC, op.Dest, op.ASigned, op.BSigned, op.HiloA, op.HiloB, op.Psl, op.Mrg, op.X, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -307,9 +307,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstXmadRc op = context.GetOp<InstXmadRc>();
|
InstXmadRc op = context.GetOp<InstXmadRc>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcReg(context, op.SrcC);
|
Operand srcB = GetSrcReg(context, op.SrcC);
|
||||||
var srcC = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
Operand srcC = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
||||||
|
|
||||||
EmitXmad(context, op.XmadCop, srcA, srcB, srcC, op.Dest, op.ASigned, op.BSigned, op.HiloA, op.HiloB, false, false, op.X, op.WriteCC);
|
EmitXmad(context, op.XmadCop, srcA, srcB, srcC, op.Dest, op.ASigned, op.BSigned, op.HiloA, op.HiloB, false, false, op.X, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -578,7 +578,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
bool extended,
|
bool extended,
|
||||||
bool writeCC)
|
bool writeCC)
|
||||||
{
|
{
|
||||||
var srcBUnmodified = srcB;
|
Operand srcBUnmodified = srcB;
|
||||||
|
|
||||||
Operand Extend16To32(Operand src, bool high, bool signed)
|
Operand Extend16To32(Operand src, bool high, bool signed)
|
||||||
{
|
{
|
||||||
|
@ -14,9 +14,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstIcmpR op = context.GetOp<InstIcmpR>();
|
InstIcmpR op = context.GetOp<InstIcmpR>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcReg(context, op.SrcB);
|
Operand srcB = GetSrcReg(context, op.SrcB);
|
||||||
var srcC = GetSrcReg(context, op.SrcC);
|
Operand srcC = GetSrcReg(context, op.SrcC);
|
||||||
|
|
||||||
EmitIcmp(context, op.IComp, srcA, srcB, srcC, op.Dest, op.Signed);
|
EmitIcmp(context, op.IComp, srcA, srcB, srcC, op.Dest, op.Signed);
|
||||||
}
|
}
|
||||||
@ -25,9 +25,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstIcmpI op = context.GetOp<InstIcmpI>();
|
InstIcmpI op = context.GetOp<InstIcmpI>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
|
Operand srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
|
||||||
var srcC = GetSrcReg(context, op.SrcC);
|
Operand srcC = GetSrcReg(context, op.SrcC);
|
||||||
|
|
||||||
EmitIcmp(context, op.IComp, srcA, srcB, srcC, op.Dest, op.Signed);
|
EmitIcmp(context, op.IComp, srcA, srcB, srcC, op.Dest, op.Signed);
|
||||||
}
|
}
|
||||||
@ -36,9 +36,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstIcmpC op = context.GetOp<InstIcmpC>();
|
InstIcmpC op = context.GetOp<InstIcmpC>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
Operand srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
||||||
var srcC = GetSrcReg(context, op.SrcC);
|
Operand srcC = GetSrcReg(context, op.SrcC);
|
||||||
|
|
||||||
EmitIcmp(context, op.IComp, srcA, srcB, srcC, op.Dest, op.Signed);
|
EmitIcmp(context, op.IComp, srcA, srcB, srcC, op.Dest, op.Signed);
|
||||||
}
|
}
|
||||||
@ -47,9 +47,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstIcmpRc op = context.GetOp<InstIcmpRc>();
|
InstIcmpRc op = context.GetOp<InstIcmpRc>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcReg(context, op.SrcC);
|
Operand srcB = GetSrcReg(context, op.SrcC);
|
||||||
var srcC = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
Operand srcC = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
||||||
|
|
||||||
EmitIcmp(context, op.IComp, srcA, srcB, srcC, op.Dest, op.Signed);
|
EmitIcmp(context, op.IComp, srcA, srcB, srcC, op.Dest, op.Signed);
|
||||||
}
|
}
|
||||||
@ -58,8 +58,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstIsetR op = context.GetOp<InstIsetR>();
|
InstIsetR op = context.GetOp<InstIsetR>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcReg(context, op.SrcB);
|
Operand srcB = GetSrcReg(context, op.SrcB);
|
||||||
|
|
||||||
EmitIset(context, op.IComp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.Dest, op.BVal, op.Signed, op.X, op.WriteCC);
|
EmitIset(context, op.IComp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.Dest, op.BVal, op.Signed, op.X, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -68,8 +68,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstIsetI op = context.GetOp<InstIsetI>();
|
InstIsetI op = context.GetOp<InstIsetI>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
|
Operand srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
|
||||||
|
|
||||||
EmitIset(context, op.IComp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.Dest, op.BVal, op.Signed, op.X, op.WriteCC);
|
EmitIset(context, op.IComp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.Dest, op.BVal, op.Signed, op.X, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -78,8 +78,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstIsetC op = context.GetOp<InstIsetC>();
|
InstIsetC op = context.GetOp<InstIsetC>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
Operand srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
||||||
|
|
||||||
EmitIset(context, op.IComp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.Dest, op.BVal, op.Signed, op.X, op.WriteCC);
|
EmitIset(context, op.IComp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.Dest, op.BVal, op.Signed, op.X, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -88,8 +88,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstIsetpR op = context.GetOp<InstIsetpR>();
|
InstIsetpR op = context.GetOp<InstIsetpR>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcReg(context, op.SrcB);
|
Operand srcB = GetSrcReg(context, op.SrcB);
|
||||||
|
|
||||||
EmitIsetp(context, op.IComp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.DestPred, op.DestPredInv, op.Signed, op.X);
|
EmitIsetp(context, op.IComp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.DestPred, op.DestPredInv, op.Signed, op.X);
|
||||||
}
|
}
|
||||||
@ -98,8 +98,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstIsetpI op = context.GetOp<InstIsetpI>();
|
InstIsetpI op = context.GetOp<InstIsetpI>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
|
Operand srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
|
||||||
|
|
||||||
EmitIsetp(context, op.IComp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.DestPred, op.DestPredInv, op.Signed, op.X);
|
EmitIsetp(context, op.IComp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.DestPred, op.DestPredInv, op.Signed, op.X);
|
||||||
}
|
}
|
||||||
@ -108,8 +108,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstIsetpC op = context.GetOp<InstIsetpC>();
|
InstIsetpC op = context.GetOp<InstIsetpC>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
Operand srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
||||||
|
|
||||||
EmitIsetp(context, op.IComp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.DestPred, op.DestPredInv, op.Signed, op.X);
|
EmitIsetp(context, op.IComp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.DestPred, op.DestPredInv, op.Signed, op.X);
|
||||||
}
|
}
|
||||||
@ -280,7 +280,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var inst = cond switch
|
Instruction inst = cond switch
|
||||||
{
|
{
|
||||||
IComp.Lt => Instruction.CompareLessU32,
|
IComp.Lt => Instruction.CompareLessU32,
|
||||||
IComp.Eq => Instruction.CompareEqual,
|
IComp.Eq => Instruction.CompareEqual,
|
||||||
|
@ -15,8 +15,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstLopR op = context.GetOp<InstLopR>();
|
InstLopR op = context.GetOp<InstLopR>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcReg(context, op.SrcB);
|
Operand srcB = GetSrcReg(context, op.SrcB);
|
||||||
|
|
||||||
EmitLop(context, op.Lop, op.PredicateOp, srcA, srcB, op.Dest, op.DestPred, op.NegA, op.NegB, op.X, op.WriteCC);
|
EmitLop(context, op.Lop, op.PredicateOp, srcA, srcB, op.Dest, op.DestPred, op.NegA, op.NegB, op.X, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -25,8 +25,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstLopI op = context.GetOp<InstLopI>();
|
InstLopI op = context.GetOp<InstLopI>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
|
Operand srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
|
||||||
|
|
||||||
EmitLop(context, op.LogicOp, op.PredicateOp, srcA, srcB, op.Dest, op.DestPred, op.NegA, op.NegB, op.X, op.WriteCC);
|
EmitLop(context, op.LogicOp, op.PredicateOp, srcA, srcB, op.Dest, op.DestPred, op.NegA, op.NegB, op.X, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -35,8 +35,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstLopC op = context.GetOp<InstLopC>();
|
InstLopC op = context.GetOp<InstLopC>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
Operand srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
||||||
|
|
||||||
EmitLop(context, op.LogicOp, op.PredicateOp, srcA, srcB, op.Dest, op.DestPred, op.NegA, op.NegB, op.X, op.WriteCC);
|
EmitLop(context, op.LogicOp, op.PredicateOp, srcA, srcB, op.Dest, op.DestPred, op.NegA, op.NegB, op.X, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -45,8 +45,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstLop32i op = context.GetOp<InstLop32i>();
|
InstLop32i op = context.GetOp<InstLop32i>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcImm(context, op.Imm32);
|
Operand srcB = GetSrcImm(context, op.Imm32);
|
||||||
|
|
||||||
EmitLop(context, op.LogicOp, PredicateOp.F, srcA, srcB, op.Dest, PT, op.NegA, op.NegB, op.X, op.WriteCC);
|
EmitLop(context, op.LogicOp, PredicateOp.F, srcA, srcB, op.Dest, PT, op.NegA, op.NegB, op.X, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -55,9 +55,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstLop3R op = context.GetOp<InstLop3R>();
|
InstLop3R op = context.GetOp<InstLop3R>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcReg(context, op.SrcB);
|
Operand srcB = GetSrcReg(context, op.SrcB);
|
||||||
var srcC = GetSrcReg(context, op.SrcC);
|
Operand srcC = GetSrcReg(context, op.SrcC);
|
||||||
|
|
||||||
EmitLop3(context, op.Imm, op.PredicateOp, srcA, srcB, srcC, op.Dest, op.DestPred, op.X, op.WriteCC);
|
EmitLop3(context, op.Imm, op.PredicateOp, srcA, srcB, srcC, op.Dest, op.DestPred, op.X, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -66,9 +66,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstLop3I op = context.GetOp<InstLop3I>();
|
InstLop3I op = context.GetOp<InstLop3I>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
|
Operand srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
|
||||||
var srcC = GetSrcReg(context, op.SrcC);
|
Operand srcC = GetSrcReg(context, op.SrcC);
|
||||||
|
|
||||||
EmitLop3(context, op.Imm, PredicateOp.F, srcA, srcB, srcC, op.Dest, PT, false, op.WriteCC);
|
EmitLop3(context, op.Imm, PredicateOp.F, srcA, srcB, srcC, op.Dest, PT, false, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -77,9 +77,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstLop3C op = context.GetOp<InstLop3C>();
|
InstLop3C op = context.GetOp<InstLop3C>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
Operand srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
||||||
var srcC = GetSrcReg(context, op.SrcC);
|
Operand srcC = GetSrcReg(context, op.SrcC);
|
||||||
|
|
||||||
EmitLop3(context, op.Imm, PredicateOp.F, srcA, srcB, srcC, op.Dest, PT, false, op.WriteCC);
|
EmitLop3(context, op.Imm, PredicateOp.F, srcA, srcB, srcC, op.Dest, PT, false, op.WriteCC);
|
||||||
}
|
}
|
||||||
|
@ -13,9 +13,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstImnmxR op = context.GetOp<InstImnmxR>();
|
InstImnmxR op = context.GetOp<InstImnmxR>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcReg(context, op.SrcB);
|
Operand srcB = GetSrcReg(context, op.SrcB);
|
||||||
var srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
|
Operand srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
|
||||||
|
|
||||||
EmitImnmx(context, srcA, srcB, srcPred, op.Dest, op.Signed, op.WriteCC);
|
EmitImnmx(context, srcA, srcB, srcPred, op.Dest, op.Signed, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -24,9 +24,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstImnmxI op = context.GetOp<InstImnmxI>();
|
InstImnmxI op = context.GetOp<InstImnmxI>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
|
Operand srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
|
||||||
var srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
|
Operand srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
|
||||||
|
|
||||||
EmitImnmx(context, srcA, srcB, srcPred, op.Dest, op.Signed, op.WriteCC);
|
EmitImnmx(context, srcA, srcB, srcPred, op.Dest, op.Signed, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -35,9 +35,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstImnmxC op = context.GetOp<InstImnmxC>();
|
InstImnmxC op = context.GetOp<InstImnmxC>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
Operand srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
||||||
var srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
|
Operand srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
|
||||||
|
|
||||||
EmitImnmx(context, srcA, srcB, srcPred, op.Dest, op.Signed, op.WriteCC);
|
EmitImnmx(context, srcA, srcB, srcPred, op.Dest, op.Signed, op.WriteCC);
|
||||||
}
|
}
|
||||||
|
@ -13,9 +13,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstShfLR op = context.GetOp<InstShfLR>();
|
InstShfLR op = context.GetOp<InstShfLR>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcReg(context, op.SrcB);
|
Operand srcB = GetSrcReg(context, op.SrcB);
|
||||||
var srcC = GetSrcReg(context, op.SrcC);
|
Operand srcC = GetSrcReg(context, op.SrcC);
|
||||||
|
|
||||||
EmitShf(context, op.MaxShift, srcA, srcB, srcC, op.Dest, op.M, left: true, op.WriteCC);
|
EmitShf(context, op.MaxShift, srcA, srcB, srcC, op.Dest, op.M, left: true, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -24,9 +24,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstShfRR op = context.GetOp<InstShfRR>();
|
InstShfRR op = context.GetOp<InstShfRR>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcReg(context, op.SrcB);
|
Operand srcB = GetSrcReg(context, op.SrcB);
|
||||||
var srcC = GetSrcReg(context, op.SrcC);
|
Operand srcC = GetSrcReg(context, op.SrcC);
|
||||||
|
|
||||||
EmitShf(context, op.MaxShift, srcA, srcB, srcC, op.Dest, op.M, left: false, op.WriteCC);
|
EmitShf(context, op.MaxShift, srcA, srcB, srcC, op.Dest, op.M, left: false, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -35,9 +35,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstShfLI op = context.GetOp<InstShfLI>();
|
InstShfLI op = context.GetOp<InstShfLI>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = Const(op.Imm6);
|
Operand srcB = Const(op.Imm6);
|
||||||
var srcC = GetSrcReg(context, op.SrcC);
|
Operand srcC = GetSrcReg(context, op.SrcC);
|
||||||
|
|
||||||
EmitShf(context, op.MaxShift, srcA, srcB, srcC, op.Dest, op.M, left: true, op.WriteCC);
|
EmitShf(context, op.MaxShift, srcA, srcB, srcC, op.Dest, op.M, left: true, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -46,9 +46,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstShfRI op = context.GetOp<InstShfRI>();
|
InstShfRI op = context.GetOp<InstShfRI>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = Const(op.Imm6);
|
Operand srcB = Const(op.Imm6);
|
||||||
var srcC = GetSrcReg(context, op.SrcC);
|
Operand srcC = GetSrcReg(context, op.SrcC);
|
||||||
|
|
||||||
EmitShf(context, op.MaxShift, srcA, srcB, srcC, op.Dest, op.M, left: false, op.WriteCC);
|
EmitShf(context, op.MaxShift, srcA, srcB, srcC, op.Dest, op.M, left: false, op.WriteCC);
|
||||||
}
|
}
|
||||||
@ -78,8 +78,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstShrR op = context.GetOp<InstShrR>();
|
InstShrR op = context.GetOp<InstShrR>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcReg(context, op.SrcB);
|
Operand srcB = GetSrcReg(context, op.SrcB);
|
||||||
|
|
||||||
EmitShr(context, srcA, srcB, op.Dest, op.M, op.Brev, op.Signed);
|
EmitShr(context, srcA, srcB, op.Dest, op.M, op.Brev, op.Signed);
|
||||||
}
|
}
|
||||||
@ -88,8 +88,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstShrI op = context.GetOp<InstShrI>();
|
InstShrI op = context.GetOp<InstShrI>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
|
Operand srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
|
||||||
|
|
||||||
EmitShr(context, srcA, srcB, op.Dest, op.M, op.Brev, op.Signed);
|
EmitShr(context, srcA, srcB, op.Dest, op.M, op.Brev, op.Signed);
|
||||||
}
|
}
|
||||||
@ -98,8 +98,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstShrC op = context.GetOp<InstShrC>();
|
InstShrC op = context.GetOp<InstShrC>();
|
||||||
|
|
||||||
var srcA = GetSrcReg(context, op.SrcA);
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
Operand srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
||||||
|
|
||||||
EmitShr(context, srcA, srcB, op.Dest, op.M, op.Brev, op.Signed);
|
EmitShr(context, srcA, srcB, op.Dest, op.M, op.Brev, op.Signed);
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstTld op = context.GetOp<InstTld>();
|
InstTld op = context.GetOp<InstTld>();
|
||||||
|
|
||||||
var lod = op.Lod ? Lod.Ll : Lod.Lz;
|
Lod lod = op.Lod ? Lod.Ll : Lod.Lz;
|
||||||
|
|
||||||
EmitTex(context, TextureFlags.IntCoords, op.Dim, lod, op.TidB, op.WMask, op.SrcA, op.SrcB, op.Dest, op.Ms, false, op.Toff);
|
EmitTex(context, TextureFlags.IntCoords, op.Dim, lod, op.TidB, op.WMask, op.SrcA, op.SrcB, op.Dest, op.Ms, false, op.Toff);
|
||||||
}
|
}
|
||||||
@ -66,8 +66,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
InstTldB op = context.GetOp<InstTldB>();
|
InstTldB op = context.GetOp<InstTldB>();
|
||||||
|
|
||||||
var flags = TextureFlags.IntCoords | TextureFlags.Bindless;
|
TextureFlags flags = TextureFlags.IntCoords | TextureFlags.Bindless;
|
||||||
var lod = op.Lod ? Lod.Ll : Lod.Lz;
|
Lod lod = op.Lod ? Lod.Ll : Lod.Lz;
|
||||||
|
|
||||||
EmitTex(context, flags, op.Dim, lod, 0, op.WMask, op.SrcA, op.SrcB, op.Dest, op.Ms, false, op.Toff);
|
EmitTex(context, flags, op.Dim, lod, 0, op.WMask, op.SrcA, op.SrcB, op.Dest, op.Ms, false, op.Toff);
|
||||||
}
|
}
|
||||||
@ -376,7 +376,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
|
|
||||||
if (texsType == TexsType.Texs)
|
if (texsType == TexsType.Texs)
|
||||||
{
|
{
|
||||||
var texsOp = context.GetOp<InstTexs>();
|
InstTexs texsOp = context.GetOp<InstTexs>();
|
||||||
|
|
||||||
type = ConvertSamplerType(texsOp.Target);
|
type = ConvertSamplerType(texsOp.Target);
|
||||||
|
|
||||||
@ -468,7 +468,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
}
|
}
|
||||||
else if (texsType == TexsType.Tlds)
|
else if (texsType == TexsType.Tlds)
|
||||||
{
|
{
|
||||||
var tldsOp = context.GetOp<InstTlds>();
|
InstTlds tldsOp = context.GetOp<InstTlds>();
|
||||||
|
|
||||||
type = ConvertSamplerType(tldsOp.Target);
|
type = ConvertSamplerType(tldsOp.Target);
|
||||||
|
|
||||||
@ -562,7 +562,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
}
|
}
|
||||||
else if (texsType == TexsType.Tld4s)
|
else if (texsType == TexsType.Tld4s)
|
||||||
{
|
{
|
||||||
var tld4sOp = context.GetOp<InstTld4s>();
|
InstTld4s tld4sOp = context.GetOp<InstTld4s>();
|
||||||
|
|
||||||
if (!(tld4sOp.Dc || tld4sOp.Aoffi))
|
if (!(tld4sOp.Dc || tld4sOp.Aoffi))
|
||||||
{
|
{
|
||||||
|
@ -192,7 +192,7 @@ namespace Ryujinx.Graphics.Shader
|
|||||||
typeName += "_array";
|
typeName += "_array";
|
||||||
}
|
}
|
||||||
|
|
||||||
var format = aggregateType switch
|
string format = aggregateType switch
|
||||||
{
|
{
|
||||||
AggregateType.S32 => "int",
|
AggregateType.S32 => "int",
|
||||||
AggregateType.U32 => "uint",
|
AggregateType.U32 => "uint",
|
||||||
|
@ -73,7 +73,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
return TextureFormat.Unknown;
|
return TextureFormat.Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
var format = gpuAccessor.QueryTextureFormat(handle, cbufSlot);
|
TextureFormat format = gpuAccessor.QueryTextureFormat(handle, cbufSlot);
|
||||||
|
|
||||||
if (format == TextureFormat.Unknown)
|
if (format == TextureFormat.Unknown)
|
||||||
{
|
{
|
||||||
@ -95,7 +95,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
// Atomic image instructions do not support GL_EXT_shader_image_load_formatted,
|
// Atomic image instructions do not support GL_EXT_shader_image_load_formatted,
|
||||||
// and must have a type specified. Default to R32Sint if not available.
|
// and must have a type specified. Default to R32Sint if not available.
|
||||||
|
|
||||||
var format = gpuAccessor.QueryTextureFormat(handle, cbufSlot);
|
TextureFormat format = gpuAccessor.QueryTextureFormat(handle, cbufSlot);
|
||||||
|
|
||||||
if (!FormatSupportsAtomic(format))
|
if (!FormatSupportsAtomic(format))
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using Ryujinx.Graphics.Shader.Decoders;
|
using Ryujinx.Graphics.Shader.Decoders;
|
||||||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
@ -256,8 +257,8 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
|
|
||||||
for (int tfbIndex = 0; tfbIndex < ResourceReservations.TfeBuffersCount; tfbIndex++)
|
for (int tfbIndex = 0; tfbIndex < ResourceReservations.TfeBuffersCount; tfbIndex++)
|
||||||
{
|
{
|
||||||
var locations = TranslatorContext.GpuAccessor.QueryTransformFeedbackVaryingLocations(tfbIndex);
|
ReadOnlySpan<byte> locations = TranslatorContext.GpuAccessor.QueryTransformFeedbackVaryingLocations(tfbIndex);
|
||||||
var stride = TranslatorContext.GpuAccessor.QueryTransformFeedbackStride(tfbIndex);
|
int stride = TranslatorContext.GpuAccessor.QueryTransformFeedbackStride(tfbIndex);
|
||||||
|
|
||||||
Operand baseOffset = this.Load(StorageKind.ConstantBuffer, SupportBuffer.Binding, Const((int)SupportBufferField.TfeOffset), Const(tfbIndex));
|
Operand baseOffset = this.Load(StorageKind.ConstantBuffer, SupportBuffer.Binding, Const((int)SupportBufferField.TfeOffset), Const(tfbIndex));
|
||||||
Operand baseVertex = this.Load(StorageKind.Input, IoVariable.BaseVertex);
|
Operand baseVertex = this.Load(StorageKind.Input, IoVariable.BaseVertex);
|
||||||
|
@ -490,8 +490,8 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
|
|
||||||
for (int index = 0; index < pTreeNode.Uses.Count; index++)
|
for (int index = 0; index < pTreeNode.Uses.Count; index++)
|
||||||
{
|
{
|
||||||
var pUse = pTreeNode.Uses[index];
|
PatternTreeNodeUse pUse = pTreeNode.Uses[index];
|
||||||
var cUse = cTreeNode.Uses[index];
|
TreeNodeUse cUse = cTreeNode.Uses[index];
|
||||||
|
|
||||||
if (pUse.Index <= -2)
|
if (pUse.Index <= -2)
|
||||||
{
|
{
|
||||||
@ -524,8 +524,8 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
{
|
{
|
||||||
public static IPatternTreeNode[] GetFsiGetAddress()
|
public static IPatternTreeNode[] GetFsiGetAddress()
|
||||||
{
|
{
|
||||||
var affinityValue = S2r(SReg.Affinity).Use(PT).Out;
|
PatternTreeNodeUse affinityValue = S2r(SReg.Affinity).Use(PT).Out;
|
||||||
var orderingTicketValue = S2r(SReg.OrderingTicket).Use(PT).Out;
|
PatternTreeNodeUse orderingTicketValue = S2r(SReg.OrderingTicket).Use(PT).Out;
|
||||||
|
|
||||||
return new IPatternTreeNode[]
|
return new IPatternTreeNode[]
|
||||||
{
|
{
|
||||||
@ -554,8 +554,8 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
|
|
||||||
public static IPatternTreeNode[] GetFsiGetAddressV2()
|
public static IPatternTreeNode[] GetFsiGetAddressV2()
|
||||||
{
|
{
|
||||||
var affinityValue = S2r(SReg.Affinity).Use(PT).Out;
|
PatternTreeNodeUse affinityValue = S2r(SReg.Affinity).Use(PT).Out;
|
||||||
var orderingTicketValue = S2r(SReg.OrderingTicket).Use(PT).Out;
|
PatternTreeNodeUse orderingTicketValue = S2r(SReg.OrderingTicket).Use(PT).Out;
|
||||||
|
|
||||||
return new IPatternTreeNode[]
|
return new IPatternTreeNode[]
|
||||||
{
|
{
|
||||||
@ -582,8 +582,8 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
|
|
||||||
public static IPatternTreeNode[] GetFsiIsLastWarpThread()
|
public static IPatternTreeNode[] GetFsiIsLastWarpThread()
|
||||||
{
|
{
|
||||||
var threadKillValue = S2r(SReg.ThreadKill).Use(PT).Out;
|
PatternTreeNodeUse threadKillValue = S2r(SReg.ThreadKill).Use(PT).Out;
|
||||||
var laneIdValue = S2r(SReg.LaneId).Use(PT).Out;
|
PatternTreeNodeUse laneIdValue = S2r(SReg.LaneId).Use(PT).Out;
|
||||||
|
|
||||||
return new IPatternTreeNode[]
|
return new IPatternTreeNode[]
|
||||||
{
|
{
|
||||||
@ -609,11 +609,11 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
|
|
||||||
public static IPatternTreeNode[] GetFsiBeginPattern()
|
public static IPatternTreeNode[] GetFsiBeginPattern()
|
||||||
{
|
{
|
||||||
var addressLowValue = CallArg(1);
|
PatternTreeNodeUse addressLowValue = CallArg(1);
|
||||||
|
|
||||||
static PatternTreeNodeUse HighU16Equals(PatternTreeNodeUse x)
|
static PatternTreeNodeUse HighU16Equals(PatternTreeNodeUse x)
|
||||||
{
|
{
|
||||||
var expectedValue = CallArg(3);
|
PatternTreeNodeUse expectedValue = CallArg(3);
|
||||||
|
|
||||||
return IsetpU32(IComp.Eq)
|
return IsetpU32(IComp.Eq)
|
||||||
.Use(PT)
|
.Use(PT)
|
||||||
@ -644,13 +644,13 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
|
|
||||||
public static IPatternTreeNode[] GetFsiEndPattern()
|
public static IPatternTreeNode[] GetFsiEndPattern()
|
||||||
{
|
{
|
||||||
var voteResult = Vote(VoteMode.All).Use(PT).Use(PT).OutAt(1);
|
PatternTreeNodeUse voteResult = Vote(VoteMode.All).Use(PT).Use(PT).OutAt(1);
|
||||||
var popcResult = Popc().Use(PT).Use(voteResult).Out;
|
PatternTreeNodeUse popcResult = Popc().Use(PT).Use(voteResult).Out;
|
||||||
var threadKillValue = S2r(SReg.ThreadKill).Use(PT).Out;
|
PatternTreeNodeUse threadKillValue = S2r(SReg.ThreadKill).Use(PT).Out;
|
||||||
var laneIdValue = S2r(SReg.LaneId).Use(PT).Out;
|
PatternTreeNodeUse laneIdValue = S2r(SReg.LaneId).Use(PT).Out;
|
||||||
|
|
||||||
var addressLowValue = CallArg(1);
|
PatternTreeNodeUse addressLowValue = CallArg(1);
|
||||||
var incrementValue = CallArg(2);
|
PatternTreeNodeUse incrementValue = CallArg(2);
|
||||||
|
|
||||||
return new IPatternTreeNode[]
|
return new IPatternTreeNode[]
|
||||||
{
|
{
|
||||||
|
@ -267,7 +267,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
|||||||
{
|
{
|
||||||
Operand value = operation.GetSource(operation.SourcesCount - 1);
|
Operand value = operation.GetSource(operation.SourcesCount - 1);
|
||||||
|
|
||||||
var result = FindUniqueBaseAddressCb(gtsContext, block, value, needsOffset: false);
|
SearchResult result = FindUniqueBaseAddressCb(gtsContext, block, value, needsOffset: false);
|
||||||
if (result.Found)
|
if (result.Found)
|
||||||
{
|
{
|
||||||
uint targetCb = PackCbSlotAndOffset(result.SbCbSlot, result.SbCbOffset);
|
uint targetCb = PackCbSlotAndOffset(result.SbCbSlot, result.SbCbOffset);
|
||||||
@ -1018,7 +1018,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
|||||||
offset = src1;
|
offset = src1;
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = GetBaseAddressCbWithOffset(baseAddr, offset, 0);
|
SearchResult result = GetBaseAddressCbWithOffset(baseAddr, offset, 0);
|
||||||
if (result.Found)
|
if (result.Found)
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
|
@ -302,7 +302,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
|
|
||||||
Debug.Assert(funcId.Type == OperandType.Constant);
|
Debug.Assert(funcId.Type == OperandType.Constant);
|
||||||
|
|
||||||
var fru = frus[funcId.Value];
|
FunctionRegisterUsage fru = frus[funcId.Value];
|
||||||
|
|
||||||
Operand[] inRegs = new Operand[fru.InArguments.Length];
|
Operand[] inRegs = new Operand[fru.InArguments.Length];
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
size = DefaultLocalMemorySize;
|
size = DefaultLocalMemorySize;
|
||||||
}
|
}
|
||||||
|
|
||||||
var lmem = new MemoryDefinition("local_memory", AggregateType.Array | AggregateType.U32, BitUtils.DivRoundUp(size, sizeof(uint)));
|
MemoryDefinition lmem = new MemoryDefinition("local_memory", AggregateType.Array | AggregateType.U32, BitUtils.DivRoundUp(size, sizeof(uint)));
|
||||||
|
|
||||||
LocalMemoryId = Properties.AddLocalMemory(lmem);
|
LocalMemoryId = Properties.AddLocalMemory(lmem);
|
||||||
}
|
}
|
||||||
@ -122,7 +122,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
size = DefaultSharedMemorySize;
|
size = DefaultSharedMemorySize;
|
||||||
}
|
}
|
||||||
|
|
||||||
var smem = new MemoryDefinition("shared_memory", AggregateType.Array | AggregateType.U32, BitUtils.DivRoundUp(size, sizeof(uint)));
|
MemoryDefinition smem = new MemoryDefinition("shared_memory", AggregateType.Array | AggregateType.U32, BitUtils.DivRoundUp(size, sizeof(uint)));
|
||||||
|
|
||||||
SharedMemoryId = Properties.AddSharedMemory(smem);
|
SharedMemoryId = Properties.AddSharedMemory(smem);
|
||||||
}
|
}
|
||||||
@ -283,16 +283,16 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
bool coherent,
|
bool coherent,
|
||||||
bool separate)
|
bool separate)
|
||||||
{
|
{
|
||||||
var dimensions = type == SamplerType.None ? 0 : type.GetDimensions();
|
int dimensions = type == SamplerType.None ? 0 : type.GetDimensions();
|
||||||
var dict = isImage ? _usedImages : _usedTextures;
|
Dictionary<TextureInfo, TextureMeta> dict = isImage ? _usedImages : _usedTextures;
|
||||||
|
|
||||||
var usageFlags = TextureUsageFlags.None;
|
TextureUsageFlags usageFlags = TextureUsageFlags.None;
|
||||||
|
|
||||||
if (intCoords)
|
if (intCoords)
|
||||||
{
|
{
|
||||||
usageFlags |= TextureUsageFlags.NeedsScaleValue;
|
usageFlags |= TextureUsageFlags.NeedsScaleValue;
|
||||||
|
|
||||||
var canScale = _stage.SupportsRenderScale() && arrayLength == 1 && !write && dimensions == 2;
|
bool canScale = _stage.SupportsRenderScale() && arrayLength == 1 && !write && dimensions == 2;
|
||||||
|
|
||||||
if (!canScale)
|
if (!canScale)
|
||||||
{
|
{
|
||||||
@ -314,9 +314,9 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
|
|
||||||
// For array textures, we also want to use type as key,
|
// For array textures, we also want to use type as key,
|
||||||
// since we may have texture handles stores in the same buffer, but for textures with different types.
|
// since we may have texture handles stores in the same buffer, but for textures with different types.
|
||||||
var keyType = arrayLength > 1 ? type : SamplerType.None;
|
SamplerType keyType = arrayLength > 1 ? type : SamplerType.None;
|
||||||
var info = new TextureInfo(cbufSlot, handle, arrayLength, separate, keyType, format);
|
TextureInfo info = new TextureInfo(cbufSlot, handle, arrayLength, separate, keyType, format);
|
||||||
var meta = new TextureMeta()
|
TextureMeta meta = new TextureMeta()
|
||||||
{
|
{
|
||||||
AccurateType = accurateType,
|
AccurateType = accurateType,
|
||||||
Type = type,
|
Type = type,
|
||||||
@ -326,7 +326,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
int setIndex;
|
int setIndex;
|
||||||
int binding;
|
int binding;
|
||||||
|
|
||||||
if (dict.TryGetValue(info, out var existingMeta))
|
if (dict.TryGetValue(info, out TextureMeta existingMeta))
|
||||||
{
|
{
|
||||||
dict[info] = MergeTextureMeta(meta, existingMeta);
|
dict[info] = MergeTextureMeta(meta, existingMeta);
|
||||||
setIndex = existingMeta.Set;
|
setIndex = existingMeta.Set;
|
||||||
@ -383,7 +383,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
nameSuffix = cbufSlot < 0 ? $"{prefix}_tcb_{handle:X}" : $"{prefix}_cb{cbufSlot}_{handle:X}";
|
nameSuffix = cbufSlot < 0 ? $"{prefix}_tcb_{handle:X}" : $"{prefix}_cb{cbufSlot}_{handle:X}";
|
||||||
}
|
}
|
||||||
|
|
||||||
var definition = new TextureDefinition(
|
TextureDefinition definition = new TextureDefinition(
|
||||||
setIndex,
|
setIndex,
|
||||||
binding,
|
binding,
|
||||||
arrayLength,
|
arrayLength,
|
||||||
@ -443,8 +443,8 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
{
|
{
|
||||||
selectedMeta.UsageFlags |= TextureUsageFlags.NeedsScaleValue;
|
selectedMeta.UsageFlags |= TextureUsageFlags.NeedsScaleValue;
|
||||||
|
|
||||||
var dimensions = type.GetDimensions();
|
int dimensions = type.GetDimensions();
|
||||||
var canScale = _stage.SupportsRenderScale() && selectedInfo.ArrayLength == 1 && dimensions == 2;
|
bool canScale = _stage.SupportsRenderScale() && selectedInfo.ArrayLength == 1 && dimensions == 2;
|
||||||
|
|
||||||
if (!canScale)
|
if (!canScale)
|
||||||
{
|
{
|
||||||
@ -464,7 +464,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
|
|
||||||
public BufferDescriptor[] GetConstantBufferDescriptors()
|
public BufferDescriptor[] GetConstantBufferDescriptors()
|
||||||
{
|
{
|
||||||
var descriptors = new BufferDescriptor[_usedConstantBufferBindings.Count];
|
BufferDescriptor[] descriptors = new BufferDescriptor[_usedConstantBufferBindings.Count];
|
||||||
|
|
||||||
int descriptorIndex = 0;
|
int descriptorIndex = 0;
|
||||||
|
|
||||||
@ -488,7 +488,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
|
|
||||||
public BufferDescriptor[] GetStorageBufferDescriptors()
|
public BufferDescriptor[] GetStorageBufferDescriptors()
|
||||||
{
|
{
|
||||||
var descriptors = new BufferDescriptor[_sbSlots.Count];
|
BufferDescriptor[] descriptors = new BufferDescriptor[_sbSlots.Count];
|
||||||
|
|
||||||
int descriptorIndex = 0;
|
int descriptorIndex = 0;
|
||||||
|
|
||||||
@ -575,7 +575,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
|
|
||||||
public ShaderProgramInfo GetVertexAsComputeInfo(bool isVertex = false)
|
public ShaderProgramInfo GetVertexAsComputeInfo(bool isVertex = false)
|
||||||
{
|
{
|
||||||
var cbDescriptors = new BufferDescriptor[_vacConstantBuffers.Count];
|
BufferDescriptor[] cbDescriptors = new BufferDescriptor[_vacConstantBuffers.Count];
|
||||||
int cbDescriptorIndex = 0;
|
int cbDescriptorIndex = 0;
|
||||||
|
|
||||||
foreach (BufferDefinition definition in _vacConstantBuffers)
|
foreach (BufferDefinition definition in _vacConstantBuffers)
|
||||||
@ -583,7 +583,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
cbDescriptors[cbDescriptorIndex++] = new BufferDescriptor(definition.Set, definition.Binding, 0, 0, 0, BufferUsageFlags.None);
|
cbDescriptors[cbDescriptorIndex++] = new BufferDescriptor(definition.Set, definition.Binding, 0, 0, 0, BufferUsageFlags.None);
|
||||||
}
|
}
|
||||||
|
|
||||||
var sbDescriptors = new BufferDescriptor[_vacStorageBuffers.Count];
|
BufferDescriptor[] sbDescriptors = new BufferDescriptor[_vacStorageBuffers.Count];
|
||||||
int sbDescriptorIndex = 0;
|
int sbDescriptorIndex = 0;
|
||||||
|
|
||||||
foreach (BufferDefinition definition in _vacStorageBuffers)
|
foreach (BufferDefinition definition in _vacStorageBuffers)
|
||||||
@ -591,7 +591,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
sbDescriptors[sbDescriptorIndex++] = new BufferDescriptor(definition.Set, definition.Binding, 0, 0, 0, BufferUsageFlags.Write);
|
sbDescriptors[sbDescriptorIndex++] = new BufferDescriptor(definition.Set, definition.Binding, 0, 0, 0, BufferUsageFlags.Write);
|
||||||
}
|
}
|
||||||
|
|
||||||
var tDescriptors = new TextureDescriptor[_vacTextures.Count];
|
TextureDescriptor[] tDescriptors = new TextureDescriptor[_vacTextures.Count];
|
||||||
int tDescriptorIndex = 0;
|
int tDescriptorIndex = 0;
|
||||||
|
|
||||||
foreach (TextureDefinition definition in _vacTextures)
|
foreach (TextureDefinition definition in _vacTextures)
|
||||||
@ -608,7 +608,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
definition.Flags);
|
definition.Flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
var iDescriptors = new TextureDescriptor[_vacImages.Count];
|
TextureDescriptor[] iDescriptors = new TextureDescriptor[_vacImages.Count];
|
||||||
int iDescriptorIndex = 0;
|
int iDescriptorIndex = 0;
|
||||||
|
|
||||||
foreach (TextureDefinition definition in _vacImages)
|
foreach (TextureDefinition definition in _vacImages)
|
||||||
|
@ -192,7 +192,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
component = subIndex;
|
component = subIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
var transformFeedbackVariable = new TransformFeedbackVariable(ioVariable, location, component);
|
TransformFeedbackVariable transformFeedbackVariable = new TransformFeedbackVariable(ioVariable, location, component);
|
||||||
_transformFeedbackDefinitions.TryAdd(transformFeedbackVariable, transformFeedbackOutputs[wordOffset]);
|
_transformFeedbackDefinitions.TryAdd(transformFeedbackVariable, transformFeedbackOutputs[wordOffset]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -219,7 +219,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var transformFeedbackVariable = new TransformFeedbackVariable(ioVariable, location, component);
|
TransformFeedbackVariable transformFeedbackVariable = new TransformFeedbackVariable(ioVariable, location, component);
|
||||||
return _transformFeedbackDefinitions.TryGetValue(transformFeedbackVariable, out transformFeedbackOutput);
|
return _transformFeedbackDefinitions.TryGetValue(transformFeedbackVariable, out transformFeedbackOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,8 +271,8 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
|
|
||||||
for (; count < 4; count++)
|
for (; count < 4; count++)
|
||||||
{
|
{
|
||||||
ref var prev = ref _transformFeedbackOutputs[baseIndex + count - 1];
|
ref TransformFeedbackOutput prev = ref _transformFeedbackOutputs[baseIndex + count - 1];
|
||||||
ref var curr = ref _transformFeedbackOutputs[baseIndex + count];
|
ref TransformFeedbackOutput curr = ref _transformFeedbackOutputs[baseIndex + count];
|
||||||
|
|
||||||
int prevOffset = prev.Offset;
|
int prevOffset = prev.Offset;
|
||||||
int currOffset = curr.Offset;
|
int currOffset = curr.Offset;
|
||||||
|
@ -110,8 +110,8 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
|
|
||||||
for (int tfbIndex = 0; tfbIndex < 4; tfbIndex++)
|
for (int tfbIndex = 0; tfbIndex < 4; tfbIndex++)
|
||||||
{
|
{
|
||||||
var locations = gpuAccessor.QueryTransformFeedbackVaryingLocations(tfbIndex);
|
ReadOnlySpan<byte> locations = gpuAccessor.QueryTransformFeedbackVaryingLocations(tfbIndex);
|
||||||
var stride = gpuAccessor.QueryTransformFeedbackStride(tfbIndex);
|
int stride = gpuAccessor.QueryTransformFeedbackStride(tfbIndex);
|
||||||
|
|
||||||
for (int i = 0; i < locations.Length; i++)
|
for (int i = 0; i < locations.Length; i++)
|
||||||
{
|
{
|
||||||
|
@ -243,8 +243,8 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
usedFeatures |= FeatureFlags.VtgAsCompute;
|
usedFeatures |= FeatureFlags.VtgAsCompute;
|
||||||
}
|
}
|
||||||
|
|
||||||
var cfgs = new ControlFlowGraph[functions.Length];
|
ControlFlowGraph[] cfgs = new ControlFlowGraph[functions.Length];
|
||||||
var frus = new RegisterUsage.FunctionRegisterUsage[functions.Length];
|
RegisterUsage.FunctionRegisterUsage[] frus = new RegisterUsage.FunctionRegisterUsage[functions.Length];
|
||||||
|
|
||||||
for (int i = 0; i < functions.Length; i++)
|
for (int i = 0; i < functions.Length; i++)
|
||||||
{
|
{
|
||||||
@ -267,14 +267,14 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
|
|
||||||
for (int i = 0; i < functions.Length; i++)
|
for (int i = 0; i < functions.Length; i++)
|
||||||
{
|
{
|
||||||
var cfg = cfgs[i];
|
ControlFlowGraph cfg = cfgs[i];
|
||||||
|
|
||||||
int inArgumentsCount = 0;
|
int inArgumentsCount = 0;
|
||||||
int outArgumentsCount = 0;
|
int outArgumentsCount = 0;
|
||||||
|
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
{
|
{
|
||||||
var fru = frus[i];
|
RegisterUsage.FunctionRegisterUsage fru = frus[i];
|
||||||
|
|
||||||
inArgumentsCount = fru.InArguments.Length;
|
inArgumentsCount = fru.InArguments.Length;
|
||||||
outArgumentsCount = fru.OutArguments.Length;
|
outArgumentsCount = fru.OutArguments.Length;
|
||||||
@ -326,7 +326,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
FeatureFlags usedFeatures,
|
FeatureFlags usedFeatures,
|
||||||
byte clipDistancesWritten)
|
byte clipDistancesWritten)
|
||||||
{
|
{
|
||||||
var sInfo = StructuredProgram.MakeStructuredProgram(
|
StructuredProgramInfo sInfo = StructuredProgram.MakeStructuredProgram(
|
||||||
funcs,
|
funcs,
|
||||||
attributeUsage,
|
attributeUsage,
|
||||||
definitions,
|
definitions,
|
||||||
@ -342,7 +342,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
_ => 1
|
_ => 1
|
||||||
};
|
};
|
||||||
|
|
||||||
var info = new ShaderProgramInfo(
|
ShaderProgramInfo info = new ShaderProgramInfo(
|
||||||
resourceManager.GetConstantBufferDescriptors(),
|
resourceManager.GetConstantBufferDescriptors(),
|
||||||
resourceManager.GetStorageBufferDescriptors(),
|
resourceManager.GetStorageBufferDescriptors(),
|
||||||
resourceManager.GetTextureDescriptors(),
|
resourceManager.GetTextureDescriptors(),
|
||||||
@ -358,7 +358,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
clipDistancesWritten,
|
clipDistancesWritten,
|
||||||
originalDefinitions.OmapTargets);
|
originalDefinitions.OmapTargets);
|
||||||
|
|
||||||
var hostCapabilities = new HostCapabilities(
|
HostCapabilities hostCapabilities = new HostCapabilities(
|
||||||
GpuAccessor.QueryHostReducedPrecision(),
|
GpuAccessor.QueryHostReducedPrecision(),
|
||||||
GpuAccessor.QueryHostSupportsFragmentShaderInterlock(),
|
GpuAccessor.QueryHostSupportsFragmentShaderInterlock(),
|
||||||
GpuAccessor.QueryHostSupportsFragmentShaderOrderingIntel(),
|
GpuAccessor.QueryHostSupportsFragmentShaderOrderingIntel(),
|
||||||
@ -369,7 +369,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
GpuAccessor.QueryHostSupportsTextureShadowLod(),
|
GpuAccessor.QueryHostSupportsTextureShadowLod(),
|
||||||
GpuAccessor.QueryHostSupportsViewportMask());
|
GpuAccessor.QueryHostSupportsViewportMask());
|
||||||
|
|
||||||
var parameters = new CodeGenParameters(attributeUsage, definitions, resourceManager.Properties, hostCapabilities, GpuAccessor, Options.TargetApi);
|
CodeGenParameters parameters = new CodeGenParameters(attributeUsage, definitions, resourceManager.Properties, hostCapabilities, GpuAccessor, Options.TargetApi);
|
||||||
|
|
||||||
return Options.TargetLanguage switch
|
return Options.TargetLanguage switch
|
||||||
{
|
{
|
||||||
@ -494,10 +494,10 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
|
|
||||||
public (ShaderProgram, ShaderProgramInfo) GenerateVertexPassthroughForCompute()
|
public (ShaderProgram, ShaderProgramInfo) GenerateVertexPassthroughForCompute()
|
||||||
{
|
{
|
||||||
var attributeUsage = new AttributeUsage(GpuAccessor);
|
AttributeUsage attributeUsage = new AttributeUsage(GpuAccessor);
|
||||||
var resourceManager = new ResourceManager(ShaderStage.Vertex, GpuAccessor);
|
ResourceManager resourceManager = new ResourceManager(ShaderStage.Vertex, GpuAccessor);
|
||||||
|
|
||||||
var reservations = GetResourceReservations();
|
ResourceReservations reservations = GetResourceReservations();
|
||||||
|
|
||||||
int vertexInfoCbBinding = reservations.VertexInfoConstantBufferBinding;
|
int vertexInfoCbBinding = reservations.VertexInfoConstantBufferBinding;
|
||||||
|
|
||||||
@ -516,7 +516,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
BufferDefinition vertexOutputBuffer = new(BufferLayout.Std430, 1, vertexDataSbBinding, "vb_input", vertexInputStruct);
|
BufferDefinition vertexOutputBuffer = new(BufferLayout.Std430, 1, vertexDataSbBinding, "vb_input", vertexInputStruct);
|
||||||
resourceManager.AddVertexAsComputeStorageBuffer(vertexOutputBuffer);
|
resourceManager.AddVertexAsComputeStorageBuffer(vertexOutputBuffer);
|
||||||
|
|
||||||
var context = new EmitterContext();
|
EmitterContext context = new EmitterContext();
|
||||||
|
|
||||||
Operand vertexIndex = Options.TargetApi == TargetApi.OpenGL
|
Operand vertexIndex = Options.TargetApi == TargetApi.OpenGL
|
||||||
? context.Load(StorageKind.Input, IoVariable.VertexId)
|
? context.Load(StorageKind.Input, IoVariable.VertexId)
|
||||||
@ -561,13 +561,13 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var operations = context.GetOperations();
|
Operation[] operations = context.GetOperations();
|
||||||
var cfg = ControlFlowGraph.Create(operations);
|
ControlFlowGraph cfg = ControlFlowGraph.Create(operations);
|
||||||
var function = new Function(cfg.Blocks, "main", false, 0, 0);
|
Function function = new Function(cfg.Blocks, "main", false, 0, 0);
|
||||||
|
|
||||||
var transformFeedbackOutputs = GetTransformFeedbackOutputs(GpuAccessor, out ulong transformFeedbackVecMap);
|
TransformFeedbackOutput[] transformFeedbackOutputs = GetTransformFeedbackOutputs(GpuAccessor, out ulong transformFeedbackVecMap);
|
||||||
|
|
||||||
var definitions = new ShaderDefinitions(ShaderStage.Vertex, transformFeedbackVecMap, transformFeedbackOutputs)
|
ShaderDefinitions definitions = new ShaderDefinitions(ShaderStage.Vertex, transformFeedbackVecMap, transformFeedbackOutputs)
|
||||||
{
|
{
|
||||||
LastInVertexPipeline = true
|
LastInVertexPipeline = true
|
||||||
};
|
};
|
||||||
@ -612,10 +612,10 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var attributeUsage = new AttributeUsage(GpuAccessor);
|
AttributeUsage attributeUsage = new AttributeUsage(GpuAccessor);
|
||||||
var resourceManager = new ResourceManager(ShaderStage.Geometry, GpuAccessor);
|
ResourceManager resourceManager = new ResourceManager(ShaderStage.Geometry, GpuAccessor);
|
||||||
|
|
||||||
var context = new EmitterContext();
|
EmitterContext context = new EmitterContext();
|
||||||
|
|
||||||
for (int v = 0; v < maxOutputVertices; v++)
|
for (int v = 0; v < maxOutputVertices; v++)
|
||||||
{
|
{
|
||||||
@ -656,11 +656,11 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
|
|
||||||
context.EndPrimitive();
|
context.EndPrimitive();
|
||||||
|
|
||||||
var operations = context.GetOperations();
|
Operation[] operations = context.GetOperations();
|
||||||
var cfg = ControlFlowGraph.Create(operations);
|
ControlFlowGraph cfg = ControlFlowGraph.Create(operations);
|
||||||
var function = new Function(cfg.Blocks, "main", false, 0, 0);
|
Function function = new Function(cfg.Blocks, "main", false, 0, 0);
|
||||||
|
|
||||||
var definitions = new ShaderDefinitions(
|
ShaderDefinitions definitions = new ShaderDefinitions(
|
||||||
ShaderStage.Geometry,
|
ShaderStage.Geometry,
|
||||||
GpuAccessor.QueryGraphicsState(),
|
GpuAccessor.QueryGraphicsState(),
|
||||||
false,
|
false,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user