Skip to content

Commit

Permalink
Replace constant buffer access on shader with new Load instruction (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
gdkchan committed May 20, 2023
1 parent fb27042 commit 402f05b
Show file tree
Hide file tree
Showing 42 changed files with 784 additions and 621 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class DiskCacheHostStorage
private const ushort FileFormatVersionMajor = 1;
private const ushort FileFormatVersionMinor = 2;
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
private const uint CodeGenVersion = 5027;
private const uint CodeGenVersion = 4646;

private const string SharedTocFileName = "shared.toc";
private const string SharedDataFileName = "shared.data";
Expand Down
19 changes: 18 additions & 1 deletion src/Ryujinx.Graphics.Gpu/Shader/GpuAccessorBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Ryujinx.Graphics.Gpu.Image;
using Ryujinx.Graphics.Shader;
using Ryujinx.Graphics.Shader.Translation;
using System;

namespace Ryujinx.Graphics.Gpu.Shader
{
Expand All @@ -16,6 +17,8 @@ class GpuAccessorBase
private readonly ResourceCounts _resourceCounts;
private readonly int _stageIndex;

private readonly int[] _constantBufferBindings;

/// <summary>
/// Creates a new GPU accessor.
/// </summary>
Expand All @@ -25,6 +28,12 @@ public GpuAccessorBase(GpuContext context, ResourceCounts resourceCounts, int st
_context = context;
_resourceCounts = resourceCounts;
_stageIndex = stageIndex;

if (context.Capabilities.Api != TargetApi.Vulkan)
{
_constantBufferBindings = new int[Constants.TotalGpUniformBuffers];
_constantBufferBindings.AsSpan().Fill(-1);
}
}

public int QueryBindingConstantBuffer(int index)
Expand All @@ -36,7 +45,15 @@ public int QueryBindingConstantBuffer(int index)
}
else
{
return _resourceCounts.UniformBuffersCount++;
int binding = _constantBufferBindings[index];

if (binding < 0)
{
binding = _resourceCounts.UniformBuffersCount++;
_constantBufferBindings[index] = binding;
}

return binding;
}
}

Expand Down
94 changes: 26 additions & 68 deletions src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Ryujinx.Graphics.Shader.Translation;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Numerics;

Expand Down Expand Up @@ -102,13 +103,7 @@ public static void Declare(CodeGenContext context, StructuredProgramInfo info)
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)
Expand Down Expand Up @@ -265,18 +260,12 @@ public static void Declare(CodeGenContext context, StructuredProgramInfo info)
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)
Expand Down Expand Up @@ -389,36 +378,38 @@ public static string GetVarTypeName(CodeGenContext context, AggregateType type,
};
}

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();
}
}

Expand Down Expand Up @@ -759,39 +750,6 @@ private static void DeclareOutputAttributePerPatch(CodeGenContext context, int a
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);
Expand Down
10 changes: 0 additions & 10 deletions src/Ryujinx.Graphics.Shader/CodeGen/Glsl/DefaultNames.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,8 @@ static class DefaultNames

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";

Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,6 @@ private static string GetExpression(CodeGenContext context, AstOperation operati
case Instruction.Load:
return Load(context, operation);

case Instruction.LoadConstant:
return LoadConstant(context, operation);

case Instruction.LoadLocal:
return LoadLocal(context, operation);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ static InstGenHelper()
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);
Expand Down

0 comments on commit 402f05b

Please sign in to comment.