Delete ShaderConfig and organize shader resources/definitions better (#5509)
* Move some properties out of ShaderConfig * Stop using ShaderConfig on backends * Replace ShaderConfig usages on Translator and passes * Move remaining properties out of ShaderConfig and delete ShaderConfig * Remove ResourceManager property from TranslatorContext * Move Rewriter passes to separate transform pass files * Fix TransformPasses.RunPass on cases where a node is removed * Move remaining ClipDistancePrimitivesWritten and UsedFeatures updates to decode stage * Reduce excessive parameter passing a bit by using structs more * Remove binding parameter from ShaderProperties methods since it is redundant * Replace decoder instruction checks with switch statement * Put GLSL on the same plan as SPIR-V for input/output declaration * Stop mutating TranslatorContext state when Translate is called * Pass most of the graphics state using a struct instead of individual query methods * Auto-format * Auto-format * Add backend logging interface * Auto-format * Remove unnecessary use of interpolated strings * Remove more modifications of AttributeUsage after decode * PR feedback * gl_Layer is not supported on compute
This commit is contained in:
parent
8edfb2bc7b
commit
b423197619
68 changed files with 2653 additions and 2407 deletions
|
@ -127,25 +127,25 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
{
|
||||
if (!(isPerPatch ? _attributesPerPatch : _attributes).TryGetValue(offset, out AttributeEntry entry))
|
||||
{
|
||||
context.Config.GpuAccessor.Log($"Attribute offset 0x{offset:X} is not valid.");
|
||||
context.TranslatorContext.GpuAccessor.Log($"Attribute offset 0x{offset:X} is not valid.");
|
||||
return Const(0);
|
||||
}
|
||||
|
||||
StagesMask validUseMask = isOutput ? entry.OutputMask : entry.InputMask;
|
||||
|
||||
if (((StagesMask)(1 << (int)context.Config.Stage) & validUseMask) == StagesMask.None)
|
||||
if (((StagesMask)(1 << (int)context.TranslatorContext.Definitions.Stage) & validUseMask) == StagesMask.None)
|
||||
{
|
||||
context.Config.GpuAccessor.Log($"Attribute offset 0x{offset:X} ({entry.IoVariable}) is not valid for stage {context.Config.Stage}.");
|
||||
context.TranslatorContext.GpuAccessor.Log($"Attribute offset 0x{offset:X} ({entry.IoVariable}) is not valid for stage {context.TranslatorContext.Definitions.Stage}.");
|
||||
return Const(0);
|
||||
}
|
||||
|
||||
if (!IsSupportedByHost(context.Config.GpuAccessor, context.Config.Stage, entry.IoVariable))
|
||||
if (!IsSupportedByHost(context.TranslatorContext.GpuAccessor, context.TranslatorContext.Definitions.Stage, entry.IoVariable))
|
||||
{
|
||||
context.Config.GpuAccessor.Log($"Attribute offset 0x{offset:X} ({entry.IoVariable}) is not supported by the host for stage {context.Config.Stage}.");
|
||||
context.TranslatorContext.GpuAccessor.Log($"Attribute offset 0x{offset:X} ({entry.IoVariable}) is not supported by the host for stage {context.TranslatorContext.Definitions.Stage}.");
|
||||
return Const(0);
|
||||
}
|
||||
|
||||
if (HasInvocationId(context.Config.Stage, isOutput) && !isPerPatch)
|
||||
if (HasInvocationId(context.TranslatorContext.Definitions.Stage, isOutput) && !isPerPatch)
|
||||
{
|
||||
primVertex = context.Load(StorageKind.Input, IoVariable.InvocationId);
|
||||
}
|
||||
|
@ -156,12 +156,12 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
StorageKind storageKind = isPerPatch
|
||||
? (isOutput ? StorageKind.OutputPerPatch : StorageKind.InputPerPatch)
|
||||
: (isOutput ? StorageKind.Output : StorageKind.Input);
|
||||
IoVariable ioVariable = GetIoVariable(context.Config.Stage, in entry);
|
||||
AggregateType type = GetType(context.Config, isOutput, innerIndex, in entry);
|
||||
IoVariable ioVariable = GetIoVariable(context.TranslatorContext.Definitions.Stage, in entry);
|
||||
AggregateType type = GetType(context.TranslatorContext.Definitions, isOutput, innerIndex, in entry);
|
||||
int elementCount = GetElementCount(type);
|
||||
|
||||
bool isArray = type.HasFlag(AggregateType.Array);
|
||||
bool hasArrayIndex = isArray || context.Config.HasPerLocationInputOrOutput(ioVariable, isOutput);
|
||||
bool hasArrayIndex = isArray || context.TranslatorContext.Definitions.HasPerLocationInputOrOutput(ioVariable, isOutput);
|
||||
|
||||
bool hasElementIndex = elementCount > 1;
|
||||
|
||||
|
@ -190,25 +190,25 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
{
|
||||
if (!(isPerPatch ? _attributesPerPatch : _attributes).TryGetValue(offset, out AttributeEntry entry))
|
||||
{
|
||||
context.Config.GpuAccessor.Log($"Attribute offset 0x{offset:X} is not valid.");
|
||||
context.TranslatorContext.GpuAccessor.Log($"Attribute offset 0x{offset:X} is not valid.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (((StagesMask)(1 << (int)context.Config.Stage) & entry.OutputMask) == StagesMask.None)
|
||||
if (((StagesMask)(1 << (int)context.TranslatorContext.Definitions.Stage) & entry.OutputMask) == StagesMask.None)
|
||||
{
|
||||
context.Config.GpuAccessor.Log($"Attribute offset 0x{offset:X} ({entry.IoVariable}) is not valid for stage {context.Config.Stage}.");
|
||||
context.TranslatorContext.GpuAccessor.Log($"Attribute offset 0x{offset:X} ({entry.IoVariable}) is not valid for stage {context.TranslatorContext.Definitions.Stage}.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsSupportedByHost(context.Config.GpuAccessor, context.Config.Stage, entry.IoVariable))
|
||||
if (!IsSupportedByHost(context.TranslatorContext.GpuAccessor, context.TranslatorContext.Definitions.Stage, entry.IoVariable))
|
||||
{
|
||||
context.Config.GpuAccessor.Log($"Attribute offset 0x{offset:X} ({entry.IoVariable}) is not supported by the host for stage {context.Config.Stage}.");
|
||||
context.TranslatorContext.GpuAccessor.Log($"Attribute offset 0x{offset:X} ({entry.IoVariable}) is not supported by the host for stage {context.TranslatorContext.Definitions.Stage}.");
|
||||
return;
|
||||
}
|
||||
|
||||
Operand invocationId = null;
|
||||
|
||||
if (HasInvocationId(context.Config.Stage, isOutput: true) && !isPerPatch)
|
||||
if (HasInvocationId(context.TranslatorContext.Definitions.Stage, isOutput: true) && !isPerPatch)
|
||||
{
|
||||
invocationId = context.Load(StorageKind.Input, IoVariable.InvocationId);
|
||||
}
|
||||
|
@ -217,12 +217,12 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
int innerIndex = innerOffset / 4;
|
||||
|
||||
StorageKind storageKind = isPerPatch ? StorageKind.OutputPerPatch : StorageKind.Output;
|
||||
IoVariable ioVariable = GetIoVariable(context.Config.Stage, in entry);
|
||||
AggregateType type = GetType(context.Config, isOutput: true, innerIndex, in entry);
|
||||
IoVariable ioVariable = GetIoVariable(context.TranslatorContext.Definitions.Stage, in entry);
|
||||
AggregateType type = GetType(context.TranslatorContext.Definitions, isOutput: true, innerIndex, in entry);
|
||||
int elementCount = GetElementCount(type);
|
||||
|
||||
bool isArray = type.HasFlag(AggregateType.Array);
|
||||
bool hasArrayIndex = isArray || context.Config.HasPerLocationInputOrOutput(ioVariable, isOutput: true);
|
||||
bool hasArrayIndex = isArray || context.TranslatorContext.Definitions.HasPerLocationInputOrOutput(ioVariable, isOutput: true);
|
||||
|
||||
bool hasElementIndex = elementCount > 1;
|
||||
|
||||
|
@ -271,7 +271,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
return true;
|
||||
}
|
||||
|
||||
public static IoVariable GetIoVariable(ShaderConfig config, int offset, out int location)
|
||||
public static IoVariable GetIoVariable(ShaderDefinitions definitions, int offset, out int location)
|
||||
{
|
||||
location = 0;
|
||||
|
||||
|
@ -280,17 +280,17 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
return IoVariable.Invalid;
|
||||
}
|
||||
|
||||
if (((StagesMask)(1 << (int)config.Stage) & entry.OutputMask) == StagesMask.None)
|
||||
if (((StagesMask)(1 << (int)definitions.Stage) & entry.OutputMask) == StagesMask.None)
|
||||
{
|
||||
return IoVariable.Invalid;
|
||||
}
|
||||
|
||||
if (config.HasPerLocationInputOrOutput(entry.IoVariable, isOutput: true))
|
||||
if (definitions.HasPerLocationInputOrOutput(entry.IoVariable, isOutput: true))
|
||||
{
|
||||
location = (offset - entry.BaseOffset) / 16;
|
||||
}
|
||||
|
||||
return GetIoVariable(config.Stage, in entry);
|
||||
return GetIoVariable(definitions.Stage, in entry);
|
||||
}
|
||||
|
||||
private static IoVariable GetIoVariable(ShaderStage stage, in AttributeEntry entry)
|
||||
|
@ -303,17 +303,17 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
return entry.IoVariable;
|
||||
}
|
||||
|
||||
private static AggregateType GetType(ShaderConfig config, bool isOutput, int innerIndex, in AttributeEntry entry)
|
||||
private static AggregateType GetType(ShaderDefinitions definitions, bool isOutput, int innerIndex, in AttributeEntry entry)
|
||||
{
|
||||
AggregateType type = entry.Type;
|
||||
|
||||
if (entry.IoVariable == IoVariable.UserDefined)
|
||||
{
|
||||
type = config.GetUserDefinedType(innerIndex / 4, isOutput);
|
||||
type = definitions.GetUserDefinedType(innerIndex / 4, isOutput);
|
||||
}
|
||||
else if (entry.IoVariable == IoVariable.FragmentOutputColor)
|
||||
{
|
||||
type = config.GetFragmentOutputColorType(innerIndex / 4);
|
||||
type = definitions.GetFragmentOutputColorType(innerIndex / 4);
|
||||
}
|
||||
|
||||
return type;
|
||||
|
|
|
@ -9,350 +9,350 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
{
|
||||
context.GetOp<InstAtomCas>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction AtomCas is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction AtomCas is not implemented.");
|
||||
}
|
||||
|
||||
public static void AtomsCas(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstAtomsCas>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction AtomsCas is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction AtomsCas is not implemented.");
|
||||
}
|
||||
|
||||
public static void B2r(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstB2r>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction B2r is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction B2r is not implemented.");
|
||||
}
|
||||
|
||||
public static void Bpt(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstBpt>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Bpt is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction Bpt is not implemented.");
|
||||
}
|
||||
|
||||
public static void Cctl(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstCctl>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Cctl is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction Cctl is not implemented.");
|
||||
}
|
||||
|
||||
public static void Cctll(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstCctll>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Cctll is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction Cctll is not implemented.");
|
||||
}
|
||||
|
||||
public static void Cctlt(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstCctlt>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Cctlt is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction Cctlt is not implemented.");
|
||||
}
|
||||
|
||||
public static void Cs2r(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstCs2r>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Cs2r is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction Cs2r is not implemented.");
|
||||
}
|
||||
|
||||
public static void FchkR(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstFchkR>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction FchkR is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction FchkR is not implemented.");
|
||||
}
|
||||
|
||||
public static void FchkI(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstFchkI>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction FchkI is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction FchkI is not implemented.");
|
||||
}
|
||||
|
||||
public static void FchkC(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstFchkC>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction FchkC is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction FchkC is not implemented.");
|
||||
}
|
||||
|
||||
public static void Getcrsptr(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstGetcrsptr>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Getcrsptr is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction Getcrsptr is not implemented.");
|
||||
}
|
||||
|
||||
public static void Getlmembase(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstGetlmembase>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Getlmembase is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction Getlmembase is not implemented.");
|
||||
}
|
||||
|
||||
public static void Ide(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstIde>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Ide is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction Ide is not implemented.");
|
||||
}
|
||||
|
||||
public static void IdpR(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstIdpR>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction IdpR is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction IdpR is not implemented.");
|
||||
}
|
||||
|
||||
public static void IdpC(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstIdpC>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction IdpC is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction IdpC is not implemented.");
|
||||
}
|
||||
|
||||
public static void ImadspR(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstImadspR>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction ImadspR is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction ImadspR is not implemented.");
|
||||
}
|
||||
|
||||
public static void ImadspI(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstImadspI>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction ImadspI is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction ImadspI is not implemented.");
|
||||
}
|
||||
|
||||
public static void ImadspC(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstImadspC>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction ImadspC is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction ImadspC is not implemented.");
|
||||
}
|
||||
|
||||
public static void ImadspRc(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstImadspRc>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction ImadspRc is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction ImadspRc is not implemented.");
|
||||
}
|
||||
|
||||
public static void Jcal(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstJcal>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Jcal is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction Jcal is not implemented.");
|
||||
}
|
||||
|
||||
public static void Jmp(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstJmp>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Jmp is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction Jmp is not implemented.");
|
||||
}
|
||||
|
||||
public static void Jmx(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstJmx>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Jmx is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction Jmx is not implemented.");
|
||||
}
|
||||
|
||||
public static void Ld(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstLd>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Ld is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction Ld is not implemented.");
|
||||
}
|
||||
|
||||
public static void Lepc(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstLepc>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Lepc is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction Lepc is not implemented.");
|
||||
}
|
||||
|
||||
public static void Longjmp(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstLongjmp>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Longjmp is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction Longjmp is not implemented.");
|
||||
}
|
||||
|
||||
public static void Pexit(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstPexit>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Pexit is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction Pexit is not implemented.");
|
||||
}
|
||||
|
||||
public static void Pixld(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstPixld>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Pixld is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction Pixld is not implemented.");
|
||||
}
|
||||
|
||||
public static void Plongjmp(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstPlongjmp>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Plongjmp is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction Plongjmp is not implemented.");
|
||||
}
|
||||
|
||||
public static void Pret(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstPret>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Pret is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction Pret is not implemented.");
|
||||
}
|
||||
|
||||
public static void PrmtR(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstPrmtR>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction PrmtR is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction PrmtR is not implemented.");
|
||||
}
|
||||
|
||||
public static void PrmtI(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstPrmtI>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction PrmtI is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction PrmtI is not implemented.");
|
||||
}
|
||||
|
||||
public static void PrmtC(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstPrmtC>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction PrmtC is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction PrmtC is not implemented.");
|
||||
}
|
||||
|
||||
public static void PrmtRc(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstPrmtRc>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction PrmtRc is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction PrmtRc is not implemented.");
|
||||
}
|
||||
|
||||
public static void R2b(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstR2b>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction R2b is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction R2b is not implemented.");
|
||||
}
|
||||
|
||||
public static void Ram(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstRam>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Ram is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction Ram is not implemented.");
|
||||
}
|
||||
|
||||
public static void Rtt(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstRtt>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Rtt is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction Rtt is not implemented.");
|
||||
}
|
||||
|
||||
public static void Sam(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstSam>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Sam is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction Sam is not implemented.");
|
||||
}
|
||||
|
||||
public static void Setcrsptr(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstSetcrsptr>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Setcrsptr is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction Setcrsptr is not implemented.");
|
||||
}
|
||||
|
||||
public static void Setlmembase(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstSetlmembase>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Setlmembase is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction Setlmembase is not implemented.");
|
||||
}
|
||||
|
||||
public static void St(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstSt>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction St is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction St is not implemented.");
|
||||
}
|
||||
|
||||
public static void Stp(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstStp>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Stp is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction Stp is not implemented.");
|
||||
}
|
||||
|
||||
public static void Txa(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstTxa>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Txa is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction Txa is not implemented.");
|
||||
}
|
||||
|
||||
public static void Vabsdiff(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstVabsdiff>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Vabsdiff is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction Vabsdiff is not implemented.");
|
||||
}
|
||||
|
||||
public static void Vabsdiff4(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstVabsdiff4>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Vabsdiff4 is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction Vabsdiff4 is not implemented.");
|
||||
}
|
||||
|
||||
public static void Vadd(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstVadd>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Vadd is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction Vadd is not implemented.");
|
||||
}
|
||||
|
||||
public static void Votevtg(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstVotevtg>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Votevtg is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction Votevtg is not implemented.");
|
||||
}
|
||||
|
||||
public static void Vset(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstVset>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Vset is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction Vset is not implemented.");
|
||||
}
|
||||
|
||||
public static void Vshl(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstVshl>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Vshl is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction Vshl is not implemented.");
|
||||
}
|
||||
|
||||
public static void Vshr(EmitterContext context)
|
||||
{
|
||||
context.GetOp<InstVshr>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction Vshr is not implemented.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction Vshr is not implemented.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
// Some of those attributes are per invocation,
|
||||
// so we should ignore any primitive vertex indexing for those.
|
||||
bool hasPrimitiveVertex = AttributeMap.HasPrimitiveVertex(context.Config.Stage, op.O) && !op.P;
|
||||
bool hasPrimitiveVertex = AttributeMap.HasPrimitiveVertex(context.TranslatorContext.Definitions.Stage, op.O) && !op.P;
|
||||
|
||||
if (!op.Phys)
|
||||
{
|
||||
|
@ -52,10 +52,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
}
|
||||
else if (op.SrcB == RegisterConsts.RegisterZeroIndex || op.P)
|
||||
{
|
||||
int offset = FixedFuncToUserAttribute(context.Config, op.Imm11 + index * 4, op.O);
|
||||
|
||||
context.FlagAttributeRead(offset);
|
||||
|
||||
int offset = FixedFuncToUserAttribute(context.TranslatorContext, op.Imm11 + index * 4, op.O);
|
||||
bool isOutput = op.O && CanLoadOutput(offset);
|
||||
|
||||
if (!op.P && !isOutput && TryConvertIdToIndexForVulkan(context, offset, out Operand value))
|
||||
|
@ -69,10 +66,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
}
|
||||
else
|
||||
{
|
||||
int offset = FixedFuncToUserAttribute(context.Config, op.Imm11 + index * 4, op.O);
|
||||
|
||||
context.FlagAttributeRead(offset);
|
||||
|
||||
int offset = FixedFuncToUserAttribute(context.TranslatorContext, op.Imm11 + index * 4, op.O);
|
||||
bool isOutput = op.O && CanLoadOutput(offset);
|
||||
|
||||
context.Copy(Register(rd), AttributeMap.GenerateAttributeLoad(context, primVertex, offset, isOutput, false));
|
||||
|
@ -98,7 +92,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
Operand offset = context.ISubtract(GetSrcReg(context, op.SrcA), Const(AttributeConsts.UserAttributeBase));
|
||||
Operand vecIndex = context.ShiftRightU32(offset, Const(4));
|
||||
Operand elemIndex = context.BitwiseAnd(context.ShiftRightU32(offset, Const(2)), Const(3));
|
||||
Operand invocationId = AttributeMap.HasInvocationId(context.Config.Stage, isOutput: true)
|
||||
Operand invocationId = AttributeMap.HasInvocationId(context.TranslatorContext.Definitions.Stage, isOutput: true)
|
||||
? context.Load(StorageKind.Input, IoVariable.InvocationId)
|
||||
: null;
|
||||
|
||||
|
@ -110,15 +104,12 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
int offset = op.Imm11 + index * 4;
|
||||
|
||||
if (!context.Config.IsUsedOutputAttribute(offset))
|
||||
if (!context.TranslatorContext.AttributeUsage.IsUsedOutputAttribute(offset))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
offset = FixedFuncToUserAttribute(context.Config, offset, isOutput: true);
|
||||
|
||||
context.FlagAttributeWritten(offset);
|
||||
|
||||
offset = FixedFuncToUserAttribute(context.TranslatorContext, offset, isOutput: true);
|
||||
AttributeMap.GenerateAttributeStore(context, offset, op.P, Register(rd));
|
||||
}
|
||||
}
|
||||
|
@ -128,8 +119,6 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
{
|
||||
InstIpa op = context.GetOp<InstIpa>();
|
||||
|
||||
context.FlagAttributeRead(op.Imm10);
|
||||
|
||||
Operand res;
|
||||
|
||||
bool isFixedFunc = false;
|
||||
|
@ -151,7 +140,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
{
|
||||
int index = (op.Imm10 - AttributeConsts.UserAttributeBase) >> 4;
|
||||
|
||||
if (context.Config.ImapTypes[index].GetFirstUsedType() == PixelImap.Perspective)
|
||||
if (context.TranslatorContext.Definitions.ImapTypes[index].GetFirstUsedType() == PixelImap.Perspective)
|
||||
{
|
||||
res = context.FPMultiply(res, context.Load(StorageKind.Input, IoVariable.FragmentCoord, null, Const(3)));
|
||||
}
|
||||
|
@ -162,11 +151,11 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
// because the shader code is not expecting scaled values.
|
||||
res = context.FPDivide(res, context.Load(StorageKind.ConstantBuffer, SupportBuffer.Binding, Const((int)SupportBufferField.RenderScale), Const(0)));
|
||||
|
||||
if (op.Imm10 == AttributeConsts.PositionY && context.Config.Options.TargetApi != TargetApi.OpenGL)
|
||||
if (op.Imm10 == AttributeConsts.PositionY && context.TranslatorContext.Options.TargetApi != TargetApi.OpenGL)
|
||||
{
|
||||
// If YNegate is enabled, we need to flip the fragment coordinates vertically, unless
|
||||
// the API supports changing the origin (only OpenGL does).
|
||||
if (context.Config.GpuAccessor.QueryYNegateEnabled())
|
||||
if (context.TranslatorContext.Definitions.YNegateEnabled)
|
||||
{
|
||||
Operand viewportHeight = context.Load(StorageKind.ConstantBuffer, 0, Const((int)SupportBufferField.ViewportSize), Const(1));
|
||||
|
||||
|
@ -174,7 +163,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (op.Imm10 == AttributeConsts.FrontFacing && context.Config.GpuAccessor.QueryHostHasFrontFacingBug())
|
||||
else if (op.Imm10 == AttributeConsts.FrontFacing && context.TranslatorContext.GpuAccessor.QueryHostHasFrontFacingBug())
|
||||
{
|
||||
// gl_FrontFacing sometimes has incorrect (flipped) values depending how it is accessed on Intel GPUs.
|
||||
// This weird trick makes it behave.
|
||||
|
@ -231,12 +220,12 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
{
|
||||
if (!(emit || cut))
|
||||
{
|
||||
context.Config.GpuAccessor.Log("Invalid OUT encoding.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Invalid OUT encoding.");
|
||||
}
|
||||
|
||||
if (emit)
|
||||
{
|
||||
if (context.Config.LastInVertexPipeline)
|
||||
if (context.TranslatorContext.Definitions.LastInVertexPipeline)
|
||||
{
|
||||
context.PrepareForVertexReturn(out var tempXLocal, out var tempYLocal, out var tempZLocal);
|
||||
|
||||
|
@ -289,13 +278,13 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
{
|
||||
// TODO: If two sided rendering is enabled, then this should return
|
||||
// FrontColor if the fragment is front facing, and back color otherwise.
|
||||
selectedAttr = GenerateIpaLoad(context, FixedFuncToUserAttribute(context.Config, attr, isOutput: false));
|
||||
selectedAttr = GenerateIpaLoad(context, FixedFuncToUserAttribute(context.TranslatorContext, attr, isOutput: false));
|
||||
return true;
|
||||
}
|
||||
else if (attr == AttributeConsts.FogCoord)
|
||||
{
|
||||
// TODO: We likely need to emulate the fixed-function functionality for FogCoord here.
|
||||
selectedAttr = GenerateIpaLoad(context, FixedFuncToUserAttribute(context.Config, attr, isOutput: false));
|
||||
selectedAttr = GenerateIpaLoad(context, FixedFuncToUserAttribute(context.TranslatorContext, attr, isOutput: false));
|
||||
return true;
|
||||
}
|
||||
else if (attr >= AttributeConsts.BackColorDiffuseR && attr < AttributeConsts.ClipDistance0)
|
||||
|
@ -305,7 +294,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
}
|
||||
else if (attr >= AttributeConsts.TexCoordBase && attr < AttributeConsts.TexCoordEnd)
|
||||
{
|
||||
selectedAttr = GenerateIpaLoad(context, FixedFuncToUserAttribute(context.Config, attr, isOutput: false));
|
||||
selectedAttr = GenerateIpaLoad(context, FixedFuncToUserAttribute(context.TranslatorContext, attr, isOutput: false));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -318,53 +307,44 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
return AttributeMap.GenerateAttributeLoad(context, null, offset, isOutput: false, isPerPatch: false);
|
||||
}
|
||||
|
||||
private static int FixedFuncToUserAttribute(ShaderConfig config, int attr, bool isOutput)
|
||||
private static int FixedFuncToUserAttribute(TranslatorContext translatorContext, int attr, bool isOutput)
|
||||
{
|
||||
bool supportsLayerFromVertexOrTess = config.GpuAccessor.QueryHostSupportsLayerVertexTessellation();
|
||||
bool supportsLayerFromVertexOrTess = translatorContext.GpuAccessor.QueryHostSupportsLayerVertexTessellation();
|
||||
int fixedStartAttr = supportsLayerFromVertexOrTess ? 0 : 1;
|
||||
|
||||
if (attr == AttributeConsts.Layer && config.Stage != ShaderStage.Geometry && !supportsLayerFromVertexOrTess)
|
||||
if (attr == AttributeConsts.Layer && translatorContext.Definitions.Stage != ShaderStage.Geometry && !supportsLayerFromVertexOrTess)
|
||||
{
|
||||
attr = FixedFuncToUserAttribute(config, attr, AttributeConsts.Layer, 0, isOutput);
|
||||
config.SetLayerOutputAttribute(attr);
|
||||
attr = FixedFuncToUserAttribute(translatorContext, attr, AttributeConsts.Layer, 0, isOutput);
|
||||
translatorContext.SetLayerOutputAttribute(attr);
|
||||
}
|
||||
else if (attr == AttributeConsts.FogCoord)
|
||||
{
|
||||
attr = FixedFuncToUserAttribute(config, attr, AttributeConsts.FogCoord, fixedStartAttr, isOutput);
|
||||
attr = FixedFuncToUserAttribute(translatorContext, attr, AttributeConsts.FogCoord, fixedStartAttr, isOutput);
|
||||
}
|
||||
else if (attr >= AttributeConsts.FrontColorDiffuseR && attr < AttributeConsts.ClipDistance0)
|
||||
{
|
||||
attr = FixedFuncToUserAttribute(config, attr, AttributeConsts.FrontColorDiffuseR, fixedStartAttr + 1, isOutput);
|
||||
attr = FixedFuncToUserAttribute(translatorContext, attr, AttributeConsts.FrontColorDiffuseR, fixedStartAttr + 1, isOutput);
|
||||
}
|
||||
else if (attr >= AttributeConsts.TexCoordBase && attr < AttributeConsts.TexCoordEnd)
|
||||
{
|
||||
attr = FixedFuncToUserAttribute(config, attr, AttributeConsts.TexCoordBase, fixedStartAttr + 5, isOutput);
|
||||
attr = FixedFuncToUserAttribute(translatorContext, attr, AttributeConsts.TexCoordBase, fixedStartAttr + 5, isOutput);
|
||||
}
|
||||
|
||||
return attr;
|
||||
}
|
||||
|
||||
private static int FixedFuncToUserAttribute(ShaderConfig config, int attr, int baseAttr, int baseIndex, bool isOutput)
|
||||
private static int FixedFuncToUserAttribute(TranslatorContext translatorContext, int attr, int baseAttr, int baseIndex, bool isOutput)
|
||||
{
|
||||
int index = (attr - baseAttr) >> 4;
|
||||
int userAttrIndex = config.GetFreeUserAttribute(isOutput, baseIndex + index);
|
||||
int userAttrIndex = translatorContext.AttributeUsage.GetFreeUserAttribute(isOutput, baseIndex + index);
|
||||
|
||||
if ((uint)userAttrIndex < Constants.MaxAttributes)
|
||||
{
|
||||
attr = AttributeConsts.UserAttributeBase + userAttrIndex * 16 + (attr & 0xf);
|
||||
|
||||
if (isOutput)
|
||||
{
|
||||
config.SetOutputUserAttributeFixedFunc(userAttrIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
config.SetInputUserAttributeFixedFunc(userAttrIndex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
config.GpuAccessor.Log($"No enough user attributes for fixed attribute offset 0x{attr:X}.");
|
||||
translatorContext.GpuAccessor.Log($"No enough user attributes for fixed attribute offset 0x{attr:X}.");
|
||||
}
|
||||
|
||||
return attr;
|
||||
|
@ -372,7 +352,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
private static bool TryConvertIdToIndexForVulkan(EmitterContext context, int attr, out Operand value)
|
||||
{
|
||||
if (context.Config.Options.TargetApi == TargetApi.Vulkan)
|
||||
if (context.TranslatorContext.Options.TargetApi == TargetApi.Vulkan)
|
||||
{
|
||||
if (attr == AttributeConsts.InstanceId)
|
||||
{
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
}
|
||||
else
|
||||
{
|
||||
context.Config.GpuAccessor.Log($"Invalid barrier mode: {op.BarOp}.");
|
||||
context.TranslatorContext.GpuAccessor.Log($"Invalid barrier mode: {op.BarOp}.");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -174,7 +174,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
{
|
||||
if (dstType == IDstFmt.U64)
|
||||
{
|
||||
context.Config.GpuAccessor.Log("Unimplemented 64-bits F2I.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Unimplemented 64-bits F2I.");
|
||||
}
|
||||
|
||||
Instruction fpType = srcType.ToInstFPType();
|
||||
|
@ -297,7 +297,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
{
|
||||
if ((srcType & ~ISrcDstFmt.S8) > ISrcDstFmt.U32 || (dstType & ~ISrcDstFmt.S8) > ISrcDstFmt.U32)
|
||||
{
|
||||
context.Config.GpuAccessor.Log("Invalid I2I encoding.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Invalid I2I encoding.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -462,7 +462,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
if (scaleConst.AsFloat() == 1f)
|
||||
{
|
||||
context.Config.GpuAccessor.Log($"Invalid FP multiply scale \"{scale}\".");
|
||||
context.TranslatorContext.GpuAccessor.Log($"Invalid FP multiply scale \"{scale}\".");
|
||||
}
|
||||
|
||||
if (isFP64)
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
if (context.CurrBlock.Successors.Count <= startIndex)
|
||||
{
|
||||
context.Config.GpuAccessor.Log($"Failed to find targets for BRX instruction at 0x{currOp.Address:X}.");
|
||||
context.TranslatorContext.GpuAccessor.Log($"Failed to find targets for BRX instruction at 0x{currOp.Address:X}.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -156,7 +156,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
if (context.IsNonMain)
|
||||
{
|
||||
context.Config.GpuAccessor.Log("Invalid exit on non-main function.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Invalid exit on non-main function.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -218,7 +218,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
}
|
||||
else
|
||||
{
|
||||
context.Config.GpuAccessor.Log("Invalid return on main function.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Invalid return on main function.");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -371,7 +371,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
}
|
||||
else
|
||||
{
|
||||
context.Config.GpuAccessor.Log($"Iadd3 has invalid component selection {part}.");
|
||||
context.TranslatorContext.GpuAccessor.Log($"Iadd3 has invalid component selection {part}.");
|
||||
}
|
||||
|
||||
return src;
|
||||
|
@ -555,7 +555,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
modeConv = XmadCop.Csfu;
|
||||
break;
|
||||
default:
|
||||
context.Config.GpuAccessor.Log($"Invalid XMAD mode \"{mode}\".");
|
||||
context.TranslatorContext.GpuAccessor.Log($"Invalid XMAD mode \"{mode}\".");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -634,7 +634,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
break;
|
||||
|
||||
default:
|
||||
context.Config.GpuAccessor.Log($"Invalid XMAD mode \"{mode}\".");
|
||||
context.TranslatorContext.GpuAccessor.Log($"Invalid XMAD mode \"{mode}\".");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,9 +26,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
public static void Atoms(EmitterContext context)
|
||||
{
|
||||
if (context.Config.Stage != ShaderStage.Compute)
|
||||
if (context.TranslatorContext.Definitions.Stage != ShaderStage.Compute)
|
||||
{
|
||||
context.Config.GpuAccessor.Log($"Atoms instruction is not valid on \"{context.Config.Stage}\" stage.");
|
||||
context.TranslatorContext.GpuAccessor.Log($"Atoms instruction is not valid on \"{context.TranslatorContext.Definitions.Stage}\" stage.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
_ => AtomSize.U32,
|
||||
};
|
||||
|
||||
Operand id = Const(context.Config.ResourceManager.SharedMemoryId);
|
||||
Operand id = Const(context.ResourceManager.SharedMemoryId);
|
||||
Operand res = EmitAtomicOp(context, StorageKind.SharedMemory, op.AtomOp, size, id, offset, value);
|
||||
|
||||
context.Copy(GetDest(op.Dest), res);
|
||||
|
@ -62,7 +62,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
if (op.LsSize > LsSize2.B64)
|
||||
{
|
||||
context.Config.GpuAccessor.Log($"Invalid LDC size: {op.LsSize}.");
|
||||
context.TranslatorContext.GpuAccessor.Log($"Invalid LDC size: {op.LsSize}.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -119,9 +119,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
public static void Lds(EmitterContext context)
|
||||
{
|
||||
if (context.Config.Stage != ShaderStage.Compute)
|
||||
if (context.TranslatorContext.Definitions.Stage != ShaderStage.Compute)
|
||||
{
|
||||
context.Config.GpuAccessor.Log($"Lds instruction is not valid on \"{context.Config.Stage}\" stage.");
|
||||
context.TranslatorContext.GpuAccessor.Log($"Lds instruction is not valid on \"{context.TranslatorContext.Definitions.Stage}\" stage.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -155,9 +155,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
public static void Sts(EmitterContext context)
|
||||
{
|
||||
if (context.Config.Stage != ShaderStage.Compute)
|
||||
if (context.TranslatorContext.Definitions.Stage != ShaderStage.Compute)
|
||||
{
|
||||
context.Config.GpuAccessor.Log($"Sts instruction is not valid on \"{context.Config.Stage}\" stage.");
|
||||
context.TranslatorContext.GpuAccessor.Log($"Sts instruction is not valid on \"{context.TranslatorContext.Definitions.Stage}\" stage.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -173,19 +173,19 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
if (slot.Type == OperandType.Constant)
|
||||
{
|
||||
int binding = context.Config.ResourceManager.GetConstantBufferBinding(slot.Value);
|
||||
int binding = context.ResourceManager.GetConstantBufferBinding(slot.Value);
|
||||
return context.Load(StorageKind.ConstantBuffer, binding, Const(0), vecIndex, elemIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
Operand value = Const(0);
|
||||
|
||||
uint cbUseMask = context.Config.GpuAccessor.QueryConstantBufferUse();
|
||||
uint cbUseMask = context.TranslatorContext.GpuAccessor.QueryConstantBufferUse();
|
||||
|
||||
while (cbUseMask != 0)
|
||||
{
|
||||
int cbIndex = BitOperations.TrailingZeroCount(cbUseMask);
|
||||
int binding = context.Config.ResourceManager.GetConstantBufferBinding(cbIndex);
|
||||
int binding = context.ResourceManager.GetConstantBufferBinding(cbIndex);
|
||||
|
||||
Operand isCurrent = context.ICompareEqual(slot, Const(cbIndex));
|
||||
Operand currentValue = context.Load(StorageKind.ConstantBuffer, binding, Const(0), vecIndex, elemIndex);
|
||||
|
@ -219,7 +219,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
}
|
||||
else
|
||||
{
|
||||
context.Config.GpuAccessor.Log($"Invalid reduction type: {type}.");
|
||||
context.TranslatorContext.GpuAccessor.Log($"Invalid reduction type: {type}.");
|
||||
}
|
||||
break;
|
||||
case AtomOp.And:
|
||||
|
@ -229,7 +229,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
}
|
||||
else
|
||||
{
|
||||
context.Config.GpuAccessor.Log($"Invalid reduction type: {type}.");
|
||||
context.TranslatorContext.GpuAccessor.Log($"Invalid reduction type: {type}.");
|
||||
}
|
||||
break;
|
||||
case AtomOp.Xor:
|
||||
|
@ -239,7 +239,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
}
|
||||
else
|
||||
{
|
||||
context.Config.GpuAccessor.Log($"Invalid reduction type: {type}.");
|
||||
context.TranslatorContext.GpuAccessor.Log($"Invalid reduction type: {type}.");
|
||||
}
|
||||
break;
|
||||
case AtomOp.Or:
|
||||
|
@ -249,7 +249,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
}
|
||||
else
|
||||
{
|
||||
context.Config.GpuAccessor.Log($"Invalid reduction type: {type}.");
|
||||
context.TranslatorContext.GpuAccessor.Log($"Invalid reduction type: {type}.");
|
||||
}
|
||||
break;
|
||||
case AtomOp.Max:
|
||||
|
@ -263,7 +263,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
}
|
||||
else
|
||||
{
|
||||
context.Config.GpuAccessor.Log($"Invalid reduction type: {type}.");
|
||||
context.TranslatorContext.GpuAccessor.Log($"Invalid reduction type: {type}.");
|
||||
}
|
||||
break;
|
||||
case AtomOp.Min:
|
||||
|
@ -277,7 +277,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
}
|
||||
else
|
||||
{
|
||||
context.Config.GpuAccessor.Log($"Invalid reduction type: {type}.");
|
||||
context.TranslatorContext.GpuAccessor.Log($"Invalid reduction type: {type}.");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -295,13 +295,13 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
{
|
||||
if (size > LsSize2.B128)
|
||||
{
|
||||
context.Config.GpuAccessor.Log($"Invalid load size: {size}.");
|
||||
context.TranslatorContext.GpuAccessor.Log($"Invalid load size: {size}.");
|
||||
return;
|
||||
}
|
||||
|
||||
int id = storageKind == StorageKind.LocalMemory
|
||||
? context.Config.ResourceManager.LocalMemoryId
|
||||
: context.Config.ResourceManager.SharedMemoryId;
|
||||
? context.ResourceManager.LocalMemoryId
|
||||
: context.ResourceManager.SharedMemoryId;
|
||||
bool isSmallInt = size < LsSize2.B32;
|
||||
|
||||
int count = size switch
|
||||
|
@ -376,13 +376,13 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
{
|
||||
if (size > LsSize2.B128)
|
||||
{
|
||||
context.Config.GpuAccessor.Log($"Invalid store size: {size}.");
|
||||
context.TranslatorContext.GpuAccessor.Log($"Invalid store size: {size}.");
|
||||
return;
|
||||
}
|
||||
|
||||
int id = storageKind == StorageKind.LocalMemory
|
||||
? context.Config.ResourceManager.LocalMemoryId
|
||||
: context.Config.ResourceManager.SharedMemoryId;
|
||||
? context.ResourceManager.LocalMemoryId
|
||||
: context.ResourceManager.SharedMemoryId;
|
||||
bool isSmallInt = size < LsSize2.B32;
|
||||
|
||||
int count = size switch
|
||||
|
@ -444,7 +444,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
{
|
||||
if (size > LsSize2.B128)
|
||||
{
|
||||
context.Config.GpuAccessor.Log($"Invalid store size: {size}.");
|
||||
context.TranslatorContext.GpuAccessor.Log($"Invalid store size: {size}.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -88,24 +88,24 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
break;
|
||||
|
||||
case SReg.ThreadKill:
|
||||
src = context.Config.Stage == ShaderStage.Fragment ? context.Load(StorageKind.Input, IoVariable.ThreadKill) : Const(0);
|
||||
src = context.TranslatorContext.Definitions.Stage == ShaderStage.Fragment ? context.Load(StorageKind.Input, IoVariable.ThreadKill) : Const(0);
|
||||
break;
|
||||
|
||||
case SReg.InvocationInfo:
|
||||
if (context.Config.Stage != ShaderStage.Compute && context.Config.Stage != ShaderStage.Fragment)
|
||||
if (context.TranslatorContext.Definitions.Stage != ShaderStage.Compute && context.TranslatorContext.Definitions.Stage != ShaderStage.Fragment)
|
||||
{
|
||||
// Note: Lowest 8-bits seems to contain some primitive index,
|
||||
// but it seems to be NVIDIA implementation specific as it's only used
|
||||
// to calculate ISBE offsets, so we can just keep it as zero.
|
||||
|
||||
if (context.Config.Stage == ShaderStage.TessellationControl ||
|
||||
context.Config.Stage == ShaderStage.TessellationEvaluation)
|
||||
if (context.TranslatorContext.Definitions.Stage == ShaderStage.TessellationControl ||
|
||||
context.TranslatorContext.Definitions.Stage == ShaderStage.TessellationEvaluation)
|
||||
{
|
||||
src = context.ShiftLeft(context.Load(StorageKind.Input, IoVariable.PatchVertices), Const(16));
|
||||
}
|
||||
else
|
||||
{
|
||||
src = Const(context.Config.GpuAccessor.QueryPrimitiveTopology().ToInputVertices() << 16);
|
||||
src = Const(context.TranslatorContext.Definitions.InputTopology.ToInputVertices() << 16);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -76,7 +76,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
break;
|
||||
|
||||
default:
|
||||
context.Config.GpuAccessor.Log($"Invalid MUFU operation \"{op.MufuOp}\".");
|
||||
context.TranslatorContext.GpuAccessor.Log($"Invalid MUFU operation \"{op.MufuOp}\".");
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using Ryujinx.Graphics.Shader.Decoders;
|
||||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||
using Ryujinx.Graphics.Shader.StructuredIr;
|
||||
using Ryujinx.Graphics.Shader.Translation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
@ -194,7 +195,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
if (type == SamplerType.None)
|
||||
{
|
||||
context.Config.GpuAccessor.Log("Invalid image atomic sampler type.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Invalid image atomic sampler type.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -258,7 +259,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
// TODO: FP and 64-bit formats.
|
||||
TextureFormat format = size == SuatomSize.Sd32 || size == SuatomSize.Sd64
|
||||
? (isBindless ? TextureFormat.Unknown : context.Config.GetTextureFormatAtomic(imm))
|
||||
? (isBindless ? TextureFormat.Unknown : ShaderProperties.GetTextureFormatAtomic(context.TranslatorContext.GpuAccessor, imm))
|
||||
: GetTextureFormat(size);
|
||||
|
||||
if (compareAndSwap)
|
||||
|
@ -277,7 +278,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
flags |= TextureFlags.Bindless;
|
||||
}
|
||||
|
||||
int binding = isBindless ? 0 : context.Config.ResourceManager.GetTextureOrImageBinding(
|
||||
int binding = isBindless ? 0 : context.ResourceManager.GetTextureOrImageBinding(
|
||||
Instruction.ImageAtomic,
|
||||
type,
|
||||
format,
|
||||
|
@ -309,13 +310,11 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
return;
|
||||
}
|
||||
|
||||
context.Config.SetUsedFeature(FeatureFlags.IntegerSampling);
|
||||
|
||||
SamplerType type = ConvertSamplerType(dimensions);
|
||||
|
||||
if (type == SamplerType.None)
|
||||
{
|
||||
context.Config.GpuAccessor.Log("Invalid image store sampler type.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Invalid image store sampler type.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -388,9 +387,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
Array.Resize(ref dests, outputIndex);
|
||||
}
|
||||
|
||||
TextureFormat format = isBindless ? TextureFormat.Unknown : context.Config.GetTextureFormat(handle);
|
||||
TextureFormat format = isBindless ? TextureFormat.Unknown : ShaderProperties.GetTextureFormat(context.TranslatorContext.GpuAccessor, handle);
|
||||
|
||||
int binding = isBindless ? 0 : context.Config.ResourceManager.GetTextureOrImageBinding(
|
||||
int binding = isBindless ? 0 : context.ResourceManager.GetTextureOrImageBinding(
|
||||
Instruction.ImageLoad,
|
||||
type,
|
||||
format,
|
||||
|
@ -433,7 +432,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
TextureFormat format = GetTextureFormat(size);
|
||||
|
||||
int binding = isBindless ? 0 : context.Config.ResourceManager.GetTextureOrImageBinding(
|
||||
int binding = isBindless ? 0 : context.ResourceManager.GetTextureOrImageBinding(
|
||||
Instruction.ImageLoad,
|
||||
type,
|
||||
format,
|
||||
|
@ -477,7 +476,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
if (type == SamplerType.None)
|
||||
{
|
||||
context.Config.GpuAccessor.Log("Invalid image reduction sampler type.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Invalid image reduction sampler type.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -539,7 +538,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
// TODO: FP and 64-bit formats.
|
||||
TextureFormat format = size == SuatomSize.Sd32 || size == SuatomSize.Sd64
|
||||
? (isBindless ? TextureFormat.Unknown : context.Config.GetTextureFormatAtomic(imm))
|
||||
? (isBindless ? TextureFormat.Unknown : ShaderProperties.GetTextureFormatAtomic(context.TranslatorContext.GpuAccessor, imm))
|
||||
: GetTextureFormat(size);
|
||||
|
||||
sourcesList.Add(Rb());
|
||||
|
@ -553,7 +552,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
flags |= TextureFlags.Bindless;
|
||||
}
|
||||
|
||||
int binding = isBindless ? 0 : context.Config.ResourceManager.GetTextureOrImageBinding(
|
||||
int binding = isBindless ? 0 : context.ResourceManager.GetTextureOrImageBinding(
|
||||
Instruction.ImageAtomic,
|
||||
type,
|
||||
format,
|
||||
|
@ -582,7 +581,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
if (type == SamplerType.None)
|
||||
{
|
||||
context.Config.GpuAccessor.Log("Invalid image store sampler type.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Invalid image store sampler type.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -647,7 +646,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
if (!isBindless)
|
||||
{
|
||||
format = context.Config.GetTextureFormat(imm);
|
||||
format = ShaderProperties.GetTextureFormat(context.TranslatorContext.GpuAccessor, imm);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -680,7 +679,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
flags |= TextureFlags.Coherent;
|
||||
}
|
||||
|
||||
int binding = isBindless ? 0 : context.Config.ResourceManager.GetTextureOrImageBinding(
|
||||
int binding = isBindless ? 0 : context.ResourceManager.GetTextureOrImageBinding(
|
||||
Instruction.ImageStore,
|
||||
type,
|
||||
format,
|
||||
|
|
|
@ -57,8 +57,6 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
{
|
||||
InstTld op = context.GetOp<InstTld>();
|
||||
|
||||
context.Config.SetUsedFeature(FeatureFlags.IntegerSampling);
|
||||
|
||||
var 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);
|
||||
|
@ -68,8 +66,6 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
{
|
||||
InstTldB op = context.GetOp<InstTldB>();
|
||||
|
||||
context.Config.SetUsedFeature(FeatureFlags.IntegerSampling);
|
||||
|
||||
var flags = TextureFlags.IntCoords | TextureFlags.Bindless;
|
||||
var lod = op.Lod ? Lod.Ll : Lod.Lz;
|
||||
|
||||
|
@ -224,7 +220,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
{
|
||||
// For bindless, we don't have any way to know the texture type,
|
||||
// so we assume it's texture buffer when the sampler type is 1D, since that's more common.
|
||||
bool isTypeBuffer = isBindless || context.Config.GpuAccessor.QuerySamplerType(imm) == SamplerType.TextureBuffer;
|
||||
bool isTypeBuffer = isBindless || context.TranslatorContext.GpuAccessor.QuerySamplerType(imm) == SamplerType.TextureBuffer;
|
||||
if (isTypeBuffer)
|
||||
{
|
||||
type = SamplerType.TextureBuffer;
|
||||
|
@ -386,7 +382,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
if (type == SamplerType.None)
|
||||
{
|
||||
context.Config.GpuAccessor.Log("Invalid texture sampler type.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Invalid texture sampler type.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -478,16 +474,14 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
if (type == SamplerType.None)
|
||||
{
|
||||
context.Config.GpuAccessor.Log("Invalid texel fetch sampler type.");
|
||||
context.TranslatorContext.GpuAccessor.Log("Invalid texel fetch sampler type.");
|
||||
return;
|
||||
}
|
||||
|
||||
context.Config.SetUsedFeature(FeatureFlags.IntegerSampling);
|
||||
|
||||
flags = ConvertTextureFlags(tldsOp.Target) | TextureFlags.IntCoords;
|
||||
|
||||
if (tldsOp.Target == TldsTarget.Texture1DLodZero &&
|
||||
context.Config.GpuAccessor.QuerySamplerType(tldsOp.TidB) == SamplerType.TextureBuffer)
|
||||
context.TranslatorContext.GpuAccessor.QuerySamplerType(tldsOp.TidB) == SamplerType.TextureBuffer)
|
||||
{
|
||||
type = SamplerType.TextureBuffer;
|
||||
flags &= ~TextureFlags.LodLevel;
|
||||
|
@ -884,7 +878,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
return Register(dest++, RegisterType.Gpr);
|
||||
}
|
||||
|
||||
int binding = isBindless ? 0 : context.Config.ResourceManager.GetTextureOrImageBinding(
|
||||
int binding = isBindless ? 0 : context.ResourceManager.GetTextureOrImageBinding(
|
||||
Instruction.Lod,
|
||||
type,
|
||||
TextureFormat.Unknown,
|
||||
|
@ -1065,8 +1059,6 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
return;
|
||||
}
|
||||
|
||||
context.Config.SetUsedFeature(FeatureFlags.IntegerSampling);
|
||||
|
||||
Operand Ra()
|
||||
{
|
||||
if (srcA > RegisterConsts.RegisterZeroIndex)
|
||||
|
@ -1106,12 +1098,12 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
}
|
||||
else
|
||||
{
|
||||
type = context.Config.GpuAccessor.QuerySamplerType(imm);
|
||||
type = context.TranslatorContext.GpuAccessor.QuerySamplerType(imm);
|
||||
}
|
||||
|
||||
TextureFlags flags = isBindless ? TextureFlags.Bindless : TextureFlags.None;
|
||||
|
||||
int binding = isBindless ? 0 : context.Config.ResourceManager.GetTextureOrImageBinding(
|
||||
int binding = isBindless ? 0 : context.ResourceManager.GetTextureOrImageBinding(
|
||||
Instruction.TextureSize,
|
||||
type,
|
||||
TextureFormat.Unknown,
|
||||
|
@ -1147,7 +1139,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
Operand[] dests,
|
||||
Operand[] sources)
|
||||
{
|
||||
int binding = flags.HasFlag(TextureFlags.Bindless) ? 0 : context.Config.ResourceManager.GetTextureOrImageBinding(
|
||||
int binding = flags.HasFlag(TextureFlags.Bindless) ? 0 : context.ResourceManager.GetTextureOrImageBinding(
|
||||
Instruction.TextureSample,
|
||||
type,
|
||||
TextureFormat.Unknown,
|
||||
|
|
|
@ -71,7 +71,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
}
|
||||
else
|
||||
{
|
||||
context.Config.GpuAccessor.Log($"Invalid vote operation: {op.VoteMode}.");
|
||||
context.TranslatorContext.GpuAccessor.Log($"Invalid vote operation: {op.VoteMode}.");
|
||||
}
|
||||
|
||||
if (op.Dest != RegisterConsts.RegisterZeroIndex)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue