aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs')
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs32
1 files changed, 32 insertions, 0 deletions
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs
index 30ce7f8b..98c1b9d2 100644
--- a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs
@@ -1788,6 +1788,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
StorageClass storageClass;
SpvInstruction baseObj;
int srcIndex = 0;
+ IoVariable? perVertexBuiltIn = null;
switch (storageKind)
{
@@ -1881,6 +1882,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
else
{
(_, varType) = IoMap.GetSpirvBuiltIn(ioVariable);
+
+ if (IoMap.IsPerVertexBuiltIn(ioVariable))
+ {
+ perVertexBuiltIn = ioVariable;
+ ioVariable = IoVariable.Position;
+ }
}
varType &= AggregateType.ElementTypeMask;
@@ -1902,6 +1909,31 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
bool isStoreOrAtomic = operation.Inst == Instruction.Store || operation.Inst.IsAtomic();
int inputsCount = (isStoreOrAtomic ? operation.SourcesCount - 1 : operation.SourcesCount) - srcIndex;
+ if (perVertexBuiltIn.HasValue)
+ {
+ int fieldIndex = IoMap.GetPerVertexStructFieldIndex(perVertexBuiltIn.Value);
+
+ var indexes = new SpvInstruction[inputsCount + 1];
+ int index = 0;
+
+ if (IoMap.IsPerVertexArrayBuiltIn(storageKind, context.Definitions.Stage))
+ {
+ indexes[index++] = context.Get(AggregateType.S32, operation.GetSource(srcIndex++));
+ indexes[index++] = context.Constant(context.TypeS32(), fieldIndex);
+ }
+ else
+ {
+ indexes[index++] = context.Constant(context.TypeS32(), fieldIndex);
+ }
+
+ for (; index < inputsCount + 1; srcIndex++, index++)
+ {
+ indexes[index] = context.Get(AggregateType.S32, operation.GetSource(srcIndex));
+ }
+
+ return context.AccessChain(context.TypePointer(storageClass, context.GetType(varType)), baseObj, indexes);
+ }
+
if (operation.Inst == Instruction.AtomicCompareAndSwap)
{
inputsCount--;