aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Graphics.Shader/CodeGen/Glsl
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2023-06-03 20:12:18 -0300
committerGitHub <noreply@github.com>2023-06-03 20:12:18 -0300
commit21c9ac6240a3db3300143d1d0dd4a1070d4f576f (patch)
tree1d3fbafa1861368efe7cf8c923752cb0b621f717 /src/Ryujinx.Graphics.Shader/CodeGen/Glsl
parent81c9052847f1aa4a70010fefa8e6ee38b5ace612 (diff)
Implement shader storage buffer operations using new Load/Store instructions (#4993)
* Implement storage buffer operations using new Load/Store instruction * Extend GenerateMultiTargetStorageOp to also match access with constant offset, and log and comments * Remove now unused code * Catch more complex cases of global memory usage * Shader cache version bump * Extend global access elimination to work with more shared memory cases * Change alignment requirement from 16 bytes to 8 bytes, handle cases where we need more than 16 storage buffers * Tweak preferencing to catch more cases * Enable CB0 elimination even when host storage buffer alignment is > 16 (for Intel) * Fix storage buffer bindings * Simplify some code * Shader cache version bump * Fix typo * Extend global memory elimination to handle shared memory with multiple possible offsets and local memory
Diffstat (limited to 'src/Ryujinx.Graphics.Shader/CodeGen/Glsl')
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs60
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Glsl/DefaultNames.cs6
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/AtomicMinMaxS32Storage.glsl21
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/StoreStorageSmallInt.glsl23
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGen.cs56
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs4
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs89
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Glsl/OperandManager.cs5
8 files changed, 66 insertions, 198 deletions
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs
index 1bd0182b..958f1cef 100644
--- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs
@@ -104,14 +104,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
}
DeclareConstantBuffers(context, context.Config.Properties.ConstantBuffers.Values);
-
- var sBufferDescriptors = context.Config.GetStorageBufferDescriptors();
- if (sBufferDescriptors.Length != 0)
- {
- DeclareStorages(context, sBufferDescriptors);
-
- context.AppendLine();
- }
+ DeclareStorageBuffers(context, context.Config.Properties.StorageBuffers.Values);
var textureDescriptors = context.Config.GetTextureDescriptors();
if (textureDescriptors.Length != 0)
@@ -250,11 +243,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
AppendHelperFunction(context, "Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/AtomicMinMaxS32Shared.glsl");
}
- if ((info.HelperFunctionsMask & HelperFunctionsMask.AtomicMinMaxS32Storage) != 0)
- {
- AppendHelperFunction(context, "Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/AtomicMinMaxS32Storage.glsl");
- }
-
if ((info.HelperFunctionsMask & HelperFunctionsMask.MultiplyHighS32) != 0)
{
AppendHelperFunction(context, "Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/MultiplyHighS32.glsl");
@@ -290,11 +278,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
AppendHelperFunction(context, "Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/StoreSharedSmallInt.glsl");
}
- if ((info.HelperFunctionsMask & HelperFunctionsMask.StoreStorageSmallInt) != 0)
- {
- AppendHelperFunction(context, "Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/StoreStorageSmallInt.glsl");
- }
-
if ((info.HelperFunctionsMask & HelperFunctionsMask.SwizzleAdd) != 0)
{
AppendHelperFunction(context, "Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/SwizzleAdd.glsl");
@@ -357,6 +340,16 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
private static void DeclareConstantBuffers(CodeGenContext context, IEnumerable<BufferDefinition> buffers)
{
+ DeclareBuffers(context, buffers, "uniform");
+ }
+
+ private static void DeclareStorageBuffers(CodeGenContext context, IEnumerable<BufferDefinition> buffers)
+ {
+ DeclareBuffers(context, buffers, "buffer");
+ }
+
+ private static void DeclareBuffers(CodeGenContext context, IEnumerable<BufferDefinition> buffers, string declType)
+ {
foreach (BufferDefinition buffer in buffers)
{
string layout = buffer.Layout switch
@@ -365,7 +358,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
_ => "std430"
};
- context.AppendLine($"layout (binding = {buffer.Binding}, {layout}) uniform _{buffer.Name}");
+ context.AppendLine($"layout (binding = {buffer.Binding}, {layout}) {declType} _{buffer.Name}");
context.EnterScope();
foreach (StructureField field in buffer.Type.Fields)
@@ -373,9 +366,17 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
if (field.Type.HasFlag(AggregateType.Array))
{
string typeName = GetVarTypeName(context, field.Type & ~AggregateType.Array);
- string arraySize = field.ArrayLength.ToString(CultureInfo.InvariantCulture);
- context.AppendLine($"{typeName} {field.Name}[{arraySize}];");
+ if (field.ArrayLength > 0)
+ {
+ string arraySize = field.ArrayLength.ToString(CultureInfo.InvariantCulture);
+
+ context.AppendLine($"{typeName} {field.Name}[{arraySize}];");
+ }
+ else
+ {
+ context.AppendLine($"{typeName} {field.Name}[];");
+ }
}
else
{
@@ -390,22 +391,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
}
}
- private static void DeclareStorages(CodeGenContext context, BufferDescriptor[] descriptors)
- {
- string sbName = OperandManager.GetShaderStagePrefix(context.Config.Stage);
-
- sbName += "_" + DefaultNames.StorageNamePrefix;
-
- string blockName = $"{sbName}_{DefaultNames.BlockSuffix}";
-
- string layout = context.Config.Options.TargetApi == TargetApi.Vulkan ? ", set = 1" : string.Empty;
-
- context.AppendLine($"layout (binding = {context.Config.FirstStorageBufferBinding}{layout}, std430) buffer {blockName}");
- context.EnterScope();
- context.AppendLine("uint " + DefaultNames.DataName + "[];");
- context.LeaveScope($" {sbName}[{NumberFormatter.FormatInt(descriptors.Max(x => x.Slot) + 1)}];");
- }
-
private static void DeclareSamplers(CodeGenContext context, TextureDescriptor[] descriptors)
{
int arraySize = 0;
@@ -733,7 +718,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
code = code.Replace("\t", CodeGenContext.Tab);
code = code.Replace("$SHARED_MEM$", DefaultNames.SharedMemoryName);
- code = code.Replace("$STORAGE_MEM$", OperandManager.GetShaderStagePrefix(context.Config.Stage) + "_" + DefaultNames.StorageNamePrefix);
if (context.Config.GpuAccessor.QueryHostSupportsShaderBallot())
{
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/DefaultNames.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/DefaultNames.cs
index fc3004a8..5ee8259c 100644
--- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/DefaultNames.cs
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/DefaultNames.cs
@@ -11,12 +11,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
public const string IAttributePrefix = "in_attr";
public const string OAttributePrefix = "out_attr";
- public const string StorageNamePrefix = "s";
-
- public const string DataName = "data";
-
- public const string BlockSuffix = "block";
-
public const string LocalMemoryName = "local_mem";
public const string SharedMemoryName = "shared_mem";
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/AtomicMinMaxS32Storage.glsl b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/AtomicMinMaxS32Storage.glsl
deleted file mode 100644
index 0862a71b..00000000
--- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/AtomicMinMaxS32Storage.glsl
+++ /dev/null
@@ -1,21 +0,0 @@
-int Helper_AtomicMaxS32(int index, int offset, int value)
-{
- uint oldValue, newValue;
- do
- {
- oldValue = $STORAGE_MEM$[index].data[offset];
- newValue = uint(max(int(oldValue), value));
- } while (atomicCompSwap($STORAGE_MEM$[index].data[offset], oldValue, newValue) != oldValue);
- return int(oldValue);
-}
-
-int Helper_AtomicMinS32(int index, int offset, int value)
-{
- uint oldValue, newValue;
- do
- {
- oldValue = $STORAGE_MEM$[index].data[offset];
- newValue = uint(min(int(oldValue), value));
- } while (atomicCompSwap($STORAGE_MEM$[index].data[offset], oldValue, newValue) != oldValue);
- return int(oldValue);
-} \ No newline at end of file
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/StoreStorageSmallInt.glsl b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/StoreStorageSmallInt.glsl
deleted file mode 100644
index f2253a79..00000000
--- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/StoreStorageSmallInt.glsl
+++ /dev/null
@@ -1,23 +0,0 @@
-void Helper_StoreStorage16(int index, int offset, uint value)
-{
- int wordOffset = offset >> 2;
- int bitOffset = (offset & 3) * 8;
- uint oldValue, newValue;
- do
- {
- oldValue = $STORAGE_MEM$[index].data[wordOffset];
- newValue = bitfieldInsert(oldValue, value, bitOffset, 16);
- } while (atomicCompSwap($STORAGE_MEM$[index].data[wordOffset], oldValue, newValue) != oldValue);
-}
-
-void Helper_StoreStorage8(int index, int offset, uint value)
-{
- int wordOffset = offset >> 2;
- int bitOffset = (offset & 3) * 8;
- uint oldValue, newValue;
- do
- {
- oldValue = $STORAGE_MEM$[index].data[wordOffset];
- newValue = bitfieldInsert(oldValue, value, bitOffset, 8);
- } while (atomicCompSwap($STORAGE_MEM$[index].data[wordOffset], oldValue, newValue) != oldValue);
-} \ No newline at end of file
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGen.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGen.cs
index 24ea66d0..01d8a6e7 100644
--- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGen.cs
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGen.cs
@@ -68,33 +68,45 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
string args = string.Empty;
- for (int argIndex = 0; argIndex < arity; argIndex++)
+ if (atomic && operation.StorageKind == StorageKind.StorageBuffer)
{
+ args = GenerateLoadOrStore(context, operation, isStore: false);
+
+ AggregateType dstType = operation.Inst == Instruction.AtomicMaxS32 || operation.Inst == Instruction.AtomicMinS32
+ ? AggregateType.S32
+ : AggregateType.U32;
+
+ for (int argIndex = operation.SourcesCount - arity + 2; argIndex < operation.SourcesCount; argIndex++)
+ {
+ args += ", " + GetSoureExpr(context, operation.GetSource(argIndex), dstType);
+ }
+ }
+ else if (atomic && operation.StorageKind == StorageKind.SharedMemory)
+ {
+ args = LoadShared(context, operation);
+
// For shared memory access, the second argument is unused and should be ignored.
// It is there to make both storage and shared access have the same number of arguments.
// For storage, both inputs are consumed when the argument index is 0, so we should skip it here.
- if (argIndex == 1 && (atomic || operation.StorageKind == StorageKind.SharedMemory))
- {
- continue;
- }
- if (argIndex != 0)
+ for (int argIndex = 2; argIndex < arity; argIndex++)
{
args += ", ";
- }
- if (argIndex == 0 && atomic)
- {
- switch (operation.StorageKind)
- {
- case StorageKind.SharedMemory: args += LoadShared(context, operation); break;
- case StorageKind.StorageBuffer: args += LoadStorage(context, operation); break;
+ AggregateType dstType = GetSrcVarType(inst, argIndex);
- default: throw new InvalidOperationException($"Invalid storage kind \"{operation.StorageKind}\".");
- }
+ args += GetSoureExpr(context, operation.GetSource(argIndex), dstType);
}
- else
+ }
+ else
+ {
+ for (int argIndex = 0; argIndex < arity; argIndex++)
{
+ if (argIndex != 0)
+ {
+ args += ", ";
+ }
+
AggregateType dstType = GetSrcVarType(inst, argIndex);
args += GetSoureExpr(context, operation.GetSource(argIndex), dstType);
@@ -173,9 +185,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
case Instruction.LoadShared:
return LoadShared(context, operation);
- case Instruction.LoadStorage:
- return LoadStorage(context, operation);
-
case Instruction.Lod:
return Lod(context, operation);
@@ -203,15 +212,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
case Instruction.StoreShared8:
return StoreShared8(context, operation);
- case Instruction.StoreStorage:
- return StoreStorage(context, operation);
-
- case Instruction.StoreStorage16:
- return StoreStorage16(context, operation);
-
- case Instruction.StoreStorage8:
- return StoreStorage8(context, operation);
-
case Instruction.TextureSample:
return TextureSample(context, operation);
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs
index 6cf36a2a..f42d9898 100644
--- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs
@@ -85,7 +85,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
Add(Instruction.Load, InstType.Special);
Add(Instruction.LoadLocal, InstType.Special);
Add(Instruction.LoadShared, InstType.Special);
- Add(Instruction.LoadStorage, InstType.Special);
Add(Instruction.Lod, InstType.Special);
Add(Instruction.LogarithmB2, InstType.CallUnary, "log2");
Add(Instruction.LogicalAnd, InstType.OpBinaryCom, "&&", 9);
@@ -123,9 +122,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
Add(Instruction.StoreShared, InstType.Special);
Add(Instruction.StoreShared16, InstType.Special);
Add(Instruction.StoreShared8, InstType.Special);
- Add(Instruction.StoreStorage, InstType.Special);
- Add(Instruction.StoreStorage16, InstType.Special);
- Add(Instruction.StoreStorage8, InstType.Special);
Add(Instruction.Subtract, InstType.OpBinary, "-", 2);
Add(Instruction.SwizzleAdd, InstType.CallTernary, HelperFunctionNames.SwizzleAdd);
Add(Instruction.TextureSample, InstType.Special);
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs
index dfc8197b..c8084d9d 100644
--- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs
@@ -210,17 +210,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
return $"{arrayName}[{offsetExpr}]";
}
- public static string LoadStorage(CodeGenContext context, AstOperation operation)
- {
- IAstNode src1 = operation.GetSource(0);
- IAstNode src2 = operation.GetSource(1);
-
- string indexExpr = GetSoureExpr(context, src1, GetSrcVarType(operation.Inst, 0));
- string offsetExpr = GetSoureExpr(context, src2, GetSrcVarType(operation.Inst, 1));
-
- return GetStorageBufferAccessor(indexExpr, offsetExpr, context.Config.Stage);
- }
-
public static string Lod(CodeGenContext context, AstOperation operation)
{
AstTextureOperation texOp = (AstTextureOperation)operation;
@@ -326,60 +315,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
return $"{HelperFunctionNames.StoreShared8}({offsetExpr}, {src})";
}
- public static string StoreStorage(CodeGenContext context, AstOperation operation)
- {
- IAstNode src1 = operation.GetSource(0);
- IAstNode src2 = operation.GetSource(1);
- IAstNode src3 = operation.GetSource(2);
-
- string indexExpr = GetSoureExpr(context, src1, GetSrcVarType(operation.Inst, 0));
- string offsetExpr = GetSoureExpr(context, src2, GetSrcVarType(operation.Inst, 1));
-
- AggregateType srcType = OperandManager.GetNodeDestType(context, src3);
-
- string src = TypeConversion.ReinterpretCast(context, src3, srcType, AggregateType.U32);
-
- string sb = GetStorageBufferAccessor(indexExpr, offsetExpr, context.Config.Stage);
-
- return $"{sb} = {src}";
- }
-
- public static string StoreStorage16(CodeGenContext context, AstOperation operation)
- {
- IAstNode src1 = operation.GetSource(0);
- IAstNode src2 = operation.GetSource(1);
- IAstNode src3 = operation.GetSource(2);
-
- string indexExpr = GetSoureExpr(context, src1, GetSrcVarType(operation.Inst, 0));
- string offsetExpr = GetSoureExpr(context, src2, GetSrcVarType(operation.Inst, 1));
-
- AggregateType srcType = OperandManager.GetNodeDestType(context, src3);
-
- string src = TypeConversion.ReinterpretCast(context, src3, srcType, AggregateType.U32);
-
- string sb = GetStorageBufferAccessor(indexExpr, offsetExpr, context.Config.Stage);
-
- return $"{HelperFunctionNames.StoreStorage16}({indexExpr}, {offsetExpr}, {src})";
- }
-
- public static string StoreStorage8(CodeGenContext context, AstOperation operation)
- {
- IAstNode src1 = operation.GetSource(0);
- IAstNode src2 = operation.GetSource(1);
- IAstNode src3 = operation.GetSource(2);
-
- string indexExpr = GetSoureExpr(context, src1, GetSrcVarType(operation.Inst, 0));
- string offsetExpr = GetSoureExpr(context, src2, GetSrcVarType(operation.Inst, 1));
-
- AggregateType srcType = OperandManager.GetNodeDestType(context, src3);
-
- string src = TypeConversion.ReinterpretCast(context, src3, srcType, AggregateType.U32);
-
- string sb = GetStorageBufferAccessor(indexExpr, offsetExpr, context.Config.Stage);
-
- return $"{HelperFunctionNames.StoreStorage8}({indexExpr}, {offsetExpr}, {src})";
- }
-
public static string TextureSample(CodeGenContext context, AstOperation operation)
{
AstTextureOperation texOp = (AstTextureOperation)operation;
@@ -701,25 +636,34 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
}
}
- private static string GenerateLoadOrStore(CodeGenContext context, AstOperation operation, bool isStore)
+ public static string GenerateLoadOrStore(CodeGenContext context, AstOperation operation, bool isStore)
{
StorageKind storageKind = operation.StorageKind;
string varName;
AggregateType varType;
int srcIndex = 0;
- int inputsCount = isStore ? operation.SourcesCount - 1 : operation.SourcesCount;
+ bool isStoreOrAtomic = operation.Inst == Instruction.Store || operation.Inst.IsAtomic();
+ int inputsCount = isStoreOrAtomic ? operation.SourcesCount - 1 : operation.SourcesCount;
+
+ if (operation.Inst == Instruction.AtomicCompareAndSwap)
+ {
+ inputsCount--;
+ }
switch (storageKind)
{
case StorageKind.ConstantBuffer:
+ case StorageKind.StorageBuffer:
if (!(operation.GetSource(srcIndex++) is AstOperand bindingIndex) || bindingIndex.Type != OperandType.Constant)
{
throw new InvalidOperationException($"First input of {operation.Inst} with {storageKind} storage must be a constant operand.");
}
int binding = bindingIndex.Value;
- BufferDefinition buffer = context.Config.Properties.ConstantBuffers[binding];
+ BufferDefinition buffer = storageKind == StorageKind.ConstantBuffer
+ ? context.Config.Properties.ConstantBuffers[binding]
+ : context.Config.Properties.StorageBuffers[binding];
if (!(operation.GetSource(srcIndex++) is AstOperand fieldIndex) || fieldIndex.Type != OperandType.Constant)
{
@@ -825,15 +769,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
return varName;
}
- private static string GetStorageBufferAccessor(string slotExpr, string offsetExpr, ShaderStage stage)
- {
- string sbName = OperandManager.GetShaderStagePrefix(stage);
-
- sbName += "_" + DefaultNames.StorageNamePrefix;
-
- return $"{sbName}[{slotExpr}].{DefaultNames.DataName}[{offsetExpr}]";
- }
-
private static string GetMask(int index)
{
return $".{"rgba".AsSpan(index, 1)}";
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/OperandManager.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/OperandManager.cs
index e34e4e07..4fd1d17c 100644
--- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/OperandManager.cs
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/OperandManager.cs
@@ -118,6 +118,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
switch (operation.StorageKind)
{
case StorageKind.ConstantBuffer:
+ case StorageKind.StorageBuffer:
if (!(operation.GetSource(0) is AstOperand bindingIndex) || bindingIndex.Type != OperandType.Constant)
{
throw new InvalidOperationException($"First input of {operation.Inst} with {operation.StorageKind} storage must be a constant operand.");
@@ -128,7 +129,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
throw new InvalidOperationException($"Second input of {operation.Inst} with {operation.StorageKind} storage must be a constant operand.");
}
- BufferDefinition buffer = context.Config.Properties.ConstantBuffers[bindingIndex.Value];
+ BufferDefinition buffer = operation.StorageKind == StorageKind.ConstantBuffer
+ ? context.Config.Properties.ConstantBuffers[bindingIndex.Value]
+ : context.Config.Properties.StorageBuffers[bindingIndex.Value];
StructureField field = buffer.Type.Fields[fieldIndex.Value];
return field.Type & AggregateType.ElementTypeMask;