aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Graphics.Shader/CodeGen/Glsl
diff options
context:
space:
mode:
Diffstat (limited to 'src/Ryujinx.Graphics.Shader/CodeGen/Glsl')
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs94
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Glsl/DefaultNames.cs10
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_cp.glsl4
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_fp.glsl4
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_vp.glsl4
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGen.cs3
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs1
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs98
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/IoMap.cs3
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Glsl/OperandManager.cs67
10 files changed, 95 insertions, 193 deletions
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs
index 81b79ec4..8d805e32 100644
--- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs
@@ -3,6 +3,7 @@ using Ryujinx.Graphics.Shader.StructuredIr;
using Ryujinx.Graphics.Shader.Translation;
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Linq;
using System.Numerics;
@@ -102,13 +103,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
context.AppendLine();
}
- var cBufferDescriptors = context.Config.GetConstantBufferDescriptors();
- if (cBufferDescriptors.Length != 0)
- {
- DeclareUniforms(context, cBufferDescriptors);
-
- context.AppendLine();
- }
+ DeclareConstantBuffers(context, context.Config.Properties.ConstantBuffers.Values);
var sBufferDescriptors = context.Config.GetStorageBufferDescriptors();
if (sBufferDescriptors.Length != 0)
@@ -265,18 +260,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
scaleElements++; // Also includes render target scale, for gl_FragCoord.
}
- DeclareSupportUniformBlock(context, context.Config.Stage, scaleElements);
-
if (context.Config.UsedFeatures.HasFlag(FeatureFlags.IntegerSampling) && scaleElements != 0)
{
AppendHelperFunction(context, $"Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_{stage}.glsl");
context.AppendLine();
}
}
- else if (isFragment || context.Config.Stage == ShaderStage.Vertex)
- {
- DeclareSupportUniformBlock(context, context.Config.Stage, 0);
- }
}
if ((info.HelperFunctionsMask & HelperFunctionsMask.AtomicMinMaxS32Shared) != 0)
@@ -389,36 +378,38 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
};
}
- private static void DeclareUniforms(CodeGenContext context, BufferDescriptor[] descriptors)
+ private static void DeclareConstantBuffers(CodeGenContext context, IEnumerable<BufferDefinition> buffers)
{
- string ubSize = "[" + NumberFormatter.FormatInt(Constants.ConstantBufferSize / 16) + "]";
-
- if (context.Config.UsedFeatures.HasFlag(FeatureFlags.CbIndexing))
+ foreach (BufferDefinition buffer in buffers)
{
- string ubName = OperandManager.GetShaderStagePrefix(context.Config.Stage);
-
- ubName += "_" + DefaultNames.UniformNamePrefix;
-
- string blockName = $"{ubName}_{DefaultNames.BlockSuffix}";
+ string layout = buffer.Layout switch
+ {
+ BufferLayout.Std140 => "std140",
+ _ => "std430"
+ };
- context.AppendLine($"layout (binding = {context.Config.FirstConstantBufferBinding}, std140) uniform {blockName}");
+ context.AppendLine($"layout (binding = {buffer.Binding}, {layout}) uniform _{buffer.Name}");
context.EnterScope();
- context.AppendLine("vec4 " + DefaultNames.DataName + ubSize + ";");
- context.LeaveScope($" {ubName}[{NumberFormatter.FormatInt(descriptors.Max(x => x.Slot) + 1)}];");
- }
- else
- {
- foreach (var descriptor in descriptors)
+
+ foreach (StructureField field in buffer.Type.Fields)
{
- string ubName = OperandManager.GetShaderStagePrefix(context.Config.Stage);
+ if (field.Type.HasFlag(AggregateType.Array))
+ {
+ string typeName = GetVarTypeName(context, field.Type & ~AggregateType.Array);
+ string arraySize = field.ArrayLength.ToString(CultureInfo.InvariantCulture);
- ubName += "_" + DefaultNames.UniformNamePrefix + descriptor.Slot;
+ context.AppendLine($"{typeName} {field.Name}[{arraySize}];");
+ }
+ else
+ {
+ string typeName = GetVarTypeName(context, field.Type);
- context.AppendLine($"layout (binding = {descriptor.Binding}, std140) uniform {ubName}");
- context.EnterScope();
- context.AppendLine("vec4 " + OperandManager.GetUbName(context.Config.Stage, descriptor.Slot, false) + ubSize + ";");
- context.LeaveScope(";");
+ context.AppendLine($"{typeName} {field.Name};");
+ }
}
+
+ context.LeaveScope($" {buffer.Name};");
+ context.AppendLine();
}
}
@@ -759,39 +750,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
context.AppendLine($"layout (location = {location}) patch out vec4 {name};");
}
- private static void DeclareSupportUniformBlock(CodeGenContext context, ShaderStage stage, int scaleElements)
- {
- bool needsSupportBlock = stage == ShaderStage.Fragment ||
- (context.Config.LastInVertexPipeline && context.Config.GpuAccessor.QueryViewportTransformDisable());
-
- if (!needsSupportBlock && scaleElements == 0)
- {
- return;
- }
-
- context.AppendLine($"layout (binding = 0, std140) uniform {DefaultNames.SupportBlockName}");
- context.EnterScope();
-
- switch (stage)
- {
- case ShaderStage.Fragment:
- case ShaderStage.Vertex:
- context.AppendLine($"uint {DefaultNames.SupportBlockAlphaTestName};");
- context.AppendLine($"bool {DefaultNames.SupportBlockIsBgraName}[{SupportBuffer.FragmentIsBgraCount}];");
- context.AppendLine($"vec4 {DefaultNames.SupportBlockViewportInverse};");
- context.AppendLine($"int {DefaultNames.SupportBlockFragmentScaleCount};");
- break;
- case ShaderStage.Compute:
- context.AppendLine($"uint s_reserved[{SupportBuffer.ComputeRenderScaleOffset / SupportBuffer.FieldSize}];");
- break;
- }
-
- context.AppendLine($"float {DefaultNames.SupportBlockRenderScaleName}[{SupportBuffer.RenderScaleMaxCount}];");
-
- context.LeaveScope(";");
- context.AppendLine();
- }
-
private static void AppendHelperFunction(CodeGenContext context, string filename)
{
string code = EmbeddedResources.ReadAllText(filename);
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/DefaultNames.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/DefaultNames.cs
index 3ab4814c..fc3004a8 100644
--- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/DefaultNames.cs
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/DefaultNames.cs
@@ -15,18 +15,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
public const string DataName = "data";
- public const string SupportBlockName = "support_block";
- public const string SupportBlockAlphaTestName = "s_alpha_test";
- public const string SupportBlockIsBgraName = "s_is_bgra";
- public const string SupportBlockViewportInverse = "s_viewport_inverse";
- public const string SupportBlockFragmentScaleCount = "s_frag_scale_count";
- public const string SupportBlockRenderScaleName = "s_render_scale";
-
public const string BlockSuffix = "block";
- public const string UniformNamePrefix = "c";
- public const string UniformNameSuffix = "data";
-
public const string LocalMemoryName = "local_mem";
public const string SharedMemoryName = "shared_mem";
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_cp.glsl b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_cp.glsl
index 4ebade5e..08c62548 100644
--- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_cp.glsl
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_cp.glsl
@@ -1,6 +1,6 @@
ivec2 Helper_TexelFetchScale(ivec2 inputVec, int samplerIndex)
{
- float scale = s_render_scale[samplerIndex];
+ float scale = support_buffer.s_render_scale[1 + samplerIndex];
if (scale == 1.0)
{
return inputVec;
@@ -10,7 +10,7 @@
int Helper_TextureSizeUnscale(int size, int samplerIndex)
{
- float scale = s_render_scale[samplerIndex];
+ float scale = support_buffer.s_render_scale[1 + samplerIndex];
if (scale == 1.0)
{
return size;
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_fp.glsl b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_fp.glsl
index 6c670f91..07a38a7a 100644
--- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_fp.glsl
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_fp.glsl
@@ -1,6 +1,6 @@
ivec2 Helper_TexelFetchScale(ivec2 inputVec, int samplerIndex)
{
- float scale = s_render_scale[1 + samplerIndex];
+ float scale = support_buffer.s_render_scale[1 + samplerIndex];
if (scale == 1.0)
{
return inputVec;
@@ -17,7 +17,7 @@
int Helper_TextureSizeUnscale(int size, int samplerIndex)
{
- float scale = abs(s_render_scale[1 + samplerIndex]);
+ float scale = abs(support_buffer.s_render_scale[1 + samplerIndex]);
if (scale == 1.0)
{
return size;
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_vp.glsl b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_vp.glsl
index 19eb119d..72baa441 100644
--- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_vp.glsl
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_vp.glsl
@@ -1,6 +1,6 @@
ivec2 Helper_TexelFetchScale(ivec2 inputVec, int samplerIndex)
{
- float scale = abs(s_render_scale[1 + samplerIndex + s_frag_scale_count]);
+ float scale = abs(support_buffer.s_render_scale[1 + samplerIndex + support_buffer.s_frag_scale_count]);
if (scale == 1.0)
{
return inputVec;
@@ -11,7 +11,7 @@
int Helper_TextureSizeUnscale(int size, int samplerIndex)
{
- float scale = abs(s_render_scale[1 + samplerIndex + s_frag_scale_count]);
+ float scale = abs(support_buffer.s_render_scale[1 + samplerIndex + support_buffer.s_frag_scale_count]);
if (scale == 1.0)
{
return size;
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGen.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGen.cs
index 01bd11e5..24ea66d0 100644
--- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGen.cs
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGen.cs
@@ -167,9 +167,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
case Instruction.Load:
return Load(context, operation);
- case Instruction.LoadConstant:
- return LoadConstant(context, operation);
-
case Instruction.LoadLocal:
return LoadLocal(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 00478f6a..71e40fe7 100644
--- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs
@@ -83,7 +83,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
Add(Instruction.ImageAtomic, InstType.Special);
Add(Instruction.IsNan, InstType.CallUnary, "isnan");
Add(Instruction.Load, InstType.Special);
- Add(Instruction.LoadConstant, InstType.Special);
Add(Instruction.LoadLocal, InstType.Special);
Add(Instruction.LoadShared, InstType.Special);
Add(Instruction.LoadStorage, 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 99519837..ef5260d1 100644
--- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs
@@ -215,29 +215,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
return GenerateLoadOrStore(context, operation, isStore: false);
}
- public static string LoadConstant(CodeGenContext context, AstOperation operation)
- {
- IAstNode src1 = operation.GetSource(0);
- IAstNode src2 = operation.GetSource(1);
-
- string offsetExpr = GetSoureExpr(context, src2, GetSrcVarType(operation.Inst, 1));
- offsetExpr = Enclose(offsetExpr, src2, Instruction.ShiftRightS32, isLhs: true);
-
- var config = context.Config;
- bool indexElement = !config.GpuAccessor.QueryHostHasVectorIndexingBug();
-
- if (src1 is AstOperand operand && operand.Type == OperandType.Constant)
- {
- bool cbIndexable = config.UsedFeatures.HasFlag(Translation.FeatureFlags.CbIndexing);
- return OperandManager.GetConstantBufferName(operand.Value, offsetExpr, config.Stage, cbIndexable, indexElement);
- }
- else
- {
- string slotExpr = GetSoureExpr(context, src1, GetSrcVarType(operation.Inst, 0));
- return OperandManager.GetConstantBufferName(slotExpr, offsetExpr, config.Stage, indexElement);
- }
- }
-
public static string LoadLocal(CodeGenContext context, AstOperation operation)
{
return LoadLocalOrShared(context, operation, DefaultNames.LocalMemoryName);
@@ -809,9 +786,29 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
string varName;
AggregateType varType;
int srcIndex = 0;
+ int inputsCount = isStore ? operation.SourcesCount - 1 : operation.SourcesCount;
switch (storageKind)
{
+ case StorageKind.ConstantBuffer:
+ 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];
+
+ if (!(operation.GetSource(srcIndex++) is AstOperand fieldIndex) || fieldIndex.Type != OperandType.Constant)
+ {
+ throw new InvalidOperationException($"Second input of {operation.Inst} with {storageKind} storage must be a constant operand.");
+ }
+
+ StructureField field = buffer.Type.Fields[fieldIndex.Value];
+ varName = $"{buffer.Name}.{field.Name}";
+ varType = field.Type;
+ break;
+
case StorageKind.Input:
case StorageKind.InputPerPatch:
case StorageKind.Output:
@@ -864,40 +861,39 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
varName = $"gl_out[{expr}].{varName}";
}
}
-
- int firstSrcIndex = srcIndex;
- int inputsCount = isStore ? operation.SourcesCount - 1 : operation.SourcesCount;
-
- for (; srcIndex < inputsCount; srcIndex++)
- {
- IAstNode src = operation.GetSource(srcIndex);
-
- if ((varType & AggregateType.ElementCountMask) != 0 &&
- srcIndex == inputsCount - 1 &&
- src is AstOperand elementIndex &&
- elementIndex.Type == OperandType.Constant)
- {
- varName += "." + "xyzw"[elementIndex.Value & 3];
- }
- else if (srcIndex == firstSrcIndex && context.Config.Stage == ShaderStage.TessellationControl && storageKind == StorageKind.Output)
- {
- // GLSL requires that for tessellation control shader outputs,
- // that the index expression must be *exactly* "gl_InvocationID",
- // otherwise the compilation fails.
- // TODO: Get rid of this and use expression propagation to make sure we generate the correct code from IR.
- varName += "[gl_InvocationID]";
- }
- else
- {
- varName += $"[{GetSoureExpr(context, src, AggregateType.S32)}]";
- }
- }
break;
default:
throw new InvalidOperationException($"Invalid storage kind {storageKind}.");
}
+ int firstSrcIndex = srcIndex;
+
+ for (; srcIndex < inputsCount; srcIndex++)
+ {
+ IAstNode src = operation.GetSource(srcIndex);
+
+ if ((varType & AggregateType.ElementCountMask) != 0 &&
+ srcIndex == inputsCount - 1 &&
+ src is AstOperand elementIndex &&
+ elementIndex.Type == OperandType.Constant)
+ {
+ varName += "." + "xyzw"[elementIndex.Value & 3];
+ }
+ else if (srcIndex == firstSrcIndex && context.Config.Stage == ShaderStage.TessellationControl && storageKind == StorageKind.Output)
+ {
+ // GLSL requires that for tessellation control shader outputs,
+ // that the index expression must be *exactly* "gl_InvocationID",
+ // otherwise the compilation fails.
+ // TODO: Get rid of this and use expression propagation to make sure we generate the correct code from IR.
+ varName += "[gl_InvocationID]";
+ }
+ else
+ {
+ varName += $"[{GetSoureExpr(context, src, AggregateType.S32)}]";
+ }
+ }
+
if (isStore)
{
varType &= AggregateType.ElementTypeMask;
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/IoMap.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/IoMap.cs
index 093ee232..2a73b8b0 100644
--- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/IoMap.cs
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/IoMap.cs
@@ -27,7 +27,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
IoVariable.FragmentCoord => ("gl_FragCoord", AggregateType.Vector4 | AggregateType.FP32),
IoVariable.FragmentOutputColor => GetFragmentOutputColorVariableName(config, location),
IoVariable.FragmentOutputDepth => ("gl_FragDepth", AggregateType.FP32),
- IoVariable.FragmentOutputIsBgra => (DefaultNames.SupportBlockIsBgraName, AggregateType.Array | AggregateType.Bool),
IoVariable.FrontColorDiffuse => ("gl_FrontColor", AggregateType.Vector4 | AggregateType.FP32), // Deprecated.
IoVariable.FrontColorSpecular => ("gl_FrontSecondaryColor", AggregateType.Vector4 | AggregateType.FP32), // Deprecated.
IoVariable.FrontFacing => ("gl_FrontFacing", AggregateType.Bool),
@@ -46,8 +45,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
IoVariable.SubgroupLaneId => GetSubgroupInvocationIdVariableName(config),
IoVariable.SubgroupLeMask => GetSubgroupMaskVariableName(config, "Le"),
IoVariable.SubgroupLtMask => GetSubgroupMaskVariableName(config, "Lt"),
- IoVariable.SupportBlockRenderScale => (DefaultNames.SupportBlockRenderScaleName, AggregateType.Array | AggregateType.FP32),
- IoVariable.SupportBlockViewInverse => (DefaultNames.SupportBlockViewportInverse, AggregateType.Vector2 | AggregateType.FP32),
IoVariable.TessellationCoord => ("gl_TessCoord", AggregateType.Vector3 | AggregateType.FP32),
IoVariable.TessellationLevelInner => ("gl_TessLevelInner", AggregateType.Array | AggregateType.FP32),
IoVariable.TessellationLevelOuter => ("gl_TessLevelOuter", AggregateType.Array | AggregateType.FP32),
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/OperandManager.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/OperandManager.cs
index 92e83358..e34e4e07 100644
--- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/OperandManager.cs
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/OperandManager.cs
@@ -36,63 +36,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
{
OperandType.Argument => GetArgumentName(operand.Value),
OperandType.Constant => NumberFormatter.FormatInt(operand.Value),
- OperandType.ConstantBuffer => GetConstantBufferName(operand, context.Config),
OperandType.LocalVariable => _locals[operand],
OperandType.Undefined => DefaultNames.UndefinedName,
_ => throw new ArgumentException($"Invalid operand type \"{operand.Type}\".")
};
}
- private static string GetConstantBufferName(AstOperand operand, ShaderConfig config)
- {
- return GetConstantBufferName(operand.CbufSlot, operand.CbufOffset, config.Stage, config.UsedFeatures.HasFlag(FeatureFlags.CbIndexing));
- }
-
- public static string GetConstantBufferName(int slot, int offset, ShaderStage stage, bool cbIndexable)
- {
- return $"{GetUbName(stage, slot, cbIndexable)}[{offset >> 2}].{GetSwizzleMask(offset & 3)}";
- }
-
- private static string GetVec4Indexed(string vectorName, string indexExpr, bool indexElement)
- {
- if (indexElement)
- {
- return $"{vectorName}[{indexExpr}]";
- }
-
- string result = $"{vectorName}.x";
- for (int i = 1; i < 4; i++)
- {
- result = $"(({indexExpr}) == {i}) ? ({vectorName}.{GetSwizzleMask(i)}) : ({result})";
- }
- return $"({result})";
- }
-
- public static string GetConstantBufferName(int slot, string offsetExpr, ShaderStage stage, bool cbIndexable, bool indexElement)
- {
- return GetVec4Indexed(GetUbName(stage, slot, cbIndexable) + $"[{offsetExpr} >> 2]", offsetExpr + " & 3", indexElement);
- }
-
- public static string GetConstantBufferName(string slotExpr, string offsetExpr, ShaderStage stage, bool indexElement)
- {
- return GetVec4Indexed(GetUbName(stage, slotExpr) + $"[{offsetExpr} >> 2]", offsetExpr + " & 3", indexElement);
- }
-
- public static string GetUbName(ShaderStage stage, int slot, bool cbIndexable)
- {
- if (cbIndexable)
- {
- return GetUbName(stage, NumberFormatter.FormatInt(slot, AggregateType.S32));
- }
-
- return $"{GetShaderStagePrefix(stage)}_{DefaultNames.UniformNamePrefix}{slot}_{DefaultNames.UniformNameSuffix}";
- }
-
- private static string GetUbName(ShaderStage stage, string slotExpr)
- {
- return $"{GetShaderStagePrefix(stage)}_{DefaultNames.UniformNamePrefix}[{slotExpr}].{DefaultNames.DataName}";
- }
-
public static string GetSamplerName(ShaderStage stage, AstTextureOperation texOp, string indexExpr)
{
return GetSamplerName(stage, texOp.CbufSlot, texOp.Handle, texOp.Type.HasFlag(SamplerType.Indexed), indexExpr);
@@ -168,6 +117,22 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
{
switch (operation.StorageKind)
{
+ case StorageKind.ConstantBuffer:
+ 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.");
+ }
+
+ if (!(operation.GetSource(1) is AstOperand fieldIndex) || fieldIndex.Type != OperandType.Constant)
+ {
+ 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];
+ StructureField field = buffer.Type.Fields[fieldIndex.Value];
+
+ return field.Type & AggregateType.ElementTypeMask;
+
case StorageKind.Input:
case StorageKind.InputPerPatch:
case StorageKind.Output: