Start building more accurate vertex as compute usage info

This commit is contained in:
Gabriel A 2024-07-27 17:01:08 -03:00 committed by Isaac Marovitz
parent 3214a4cf8e
commit 29cca80d9f
4 changed files with 143 additions and 13 deletions

View file

@ -435,6 +435,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
geometryAsCompute = CreateHostVertexAsComputeProgram(program, currentStage, tfEnabled); geometryAsCompute = CreateHostVertexAsComputeProgram(program, currentStage, tfEnabled);
program = null; program = null;
} }
infoBuilder.AddStageInfoVac(currentStage.GetVertexAsComputeInfo());
} }
if (program != null) if (program != null)
@ -533,7 +535,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
private ShaderAsCompute CreateHostVertexAsComputeProgram(ShaderProgram program, TranslatorContext context, bool tfEnabled) private ShaderAsCompute CreateHostVertexAsComputeProgram(ShaderProgram program, TranslatorContext context, bool tfEnabled)
{ {
ShaderSource source = new(program.Code, program.BinaryCode, ShaderStage.Compute, program.Language); ShaderSource source = new(program.Code, program.BinaryCode, ShaderStage.Compute, program.Language);
ShaderInfo info = ShaderInfoBuilder.BuildForVertexAsCompute(_context, program.Info, tfEnabled); ShaderInfo info = ShaderInfoBuilder.BuildForVertexAsCompute(_context, program.Info, context.GetVertexAsComputeInfo(), tfEnabled);
return new(_context.Renderer.CreateProgram(new[] { source }, info), program.Info, context.GetResourceReservations()); return new(_context.Renderer.CreateProgram(new[] { source }, info), program.Info, context.GetResourceReservations());
} }

View file

@ -98,7 +98,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
private void PopulateDescriptorAndUsages(ResourceStages stages, ResourceType type, int setIndex, int start, int count, bool write = false) private void PopulateDescriptorAndUsages(ResourceStages stages, ResourceType type, int setIndex, int start, int count, bool write = false)
{ {
AddDescriptor(stages, type, setIndex, start, count); AddDescriptor(stages, type, setIndex, start, count);
AddUsage(stages, type, setIndex, start, count, write); // AddUsage(stages, type, setIndex, start, count, write);
} }
/// <summary> /// <summary>
@ -162,6 +162,25 @@ namespace Ryujinx.Graphics.Gpu.Shader
AddUsage(info.Images, stages, isImage: true); AddUsage(info.Images, stages, isImage: true);
} }
public void AddStageInfoVac(ShaderProgramInfo info)
{
ResourceStages stages = info.Stage switch
{
ShaderStage.Compute => ResourceStages.Compute,
ShaderStage.Vertex => ResourceStages.Vertex,
ShaderStage.TessellationControl => ResourceStages.TessellationControl,
ShaderStage.TessellationEvaluation => ResourceStages.TessellationEvaluation,
ShaderStage.Geometry => ResourceStages.Geometry,
ShaderStage.Fragment => ResourceStages.Fragment,
_ => ResourceStages.None,
};
AddUsage(info.CBuffers, stages, isStorage: false);
AddUsage(info.SBuffers, stages, isStorage: true);
AddUsage(info.Textures, stages, isImage: false);
AddUsage(info.Images, stages, isImage: true);
}
/// <summary> /// <summary>
/// Adds a resource descriptor to the list of descriptors. /// Adds a resource descriptor to the list of descriptors.
/// </summary> /// </summary>
@ -421,11 +440,12 @@ namespace Ryujinx.Graphics.Gpu.Shader
/// <param name="tfEnabled">Indicates if the graphics shader is used with transform feedback enabled</param> /// <param name="tfEnabled">Indicates if the graphics shader is used with transform feedback enabled</param>
/// <param name="fromCache">True if the compute shader comes from a disk cache, false otherwise</param> /// <param name="fromCache">True if the compute shader comes from a disk cache, false otherwise</param>
/// <returns>Shader information</returns> /// <returns>Shader information</returns>
public static ShaderInfo BuildForVertexAsCompute(GpuContext context, ShaderProgramInfo info, bool tfEnabled, bool fromCache = false) public static ShaderInfo BuildForVertexAsCompute(GpuContext context, ShaderProgramInfo info, ShaderProgramInfo info2, bool tfEnabled, bool fromCache = false)
{ {
ShaderInfoBuilder builder = new(context, tfEnabled, vertexAsCompute: true, computeLocalSize: ComputeSize.VtgAsCompute); ShaderInfoBuilder builder = new(context, tfEnabled, vertexAsCompute: true, computeLocalSize: ComputeSize.VtgAsCompute);
builder.AddStageInfo(info, vertexAsCompute: true); builder.AddStageInfo(info, vertexAsCompute: true);
builder.AddStageInfoVac(info2);
return builder.Build(null, fromCache); return builder.Build(null, fromCache);
} }

View file

@ -43,6 +43,11 @@ namespace Ryujinx.Graphics.Shader.Translation
private readonly Dictionary<TextureInfo, TextureMeta> _usedTextures; private readonly Dictionary<TextureInfo, TextureMeta> _usedTextures;
private readonly Dictionary<TextureInfo, TextureMeta> _usedImages; private readonly Dictionary<TextureInfo, TextureMeta> _usedImages;
private readonly List<BufferDefinition> _vacConstantBuffers;
private readonly List<BufferDefinition> _vacStorageBuffers;
private readonly List<TextureDefinition> _vacTextures;
private readonly List<TextureDefinition> _vacImages;
public int LocalMemoryId { get; private set; } public int LocalMemoryId { get; private set; }
public int SharedMemoryId { get; private set; } public int SharedMemoryId { get; private set; }
@ -78,6 +83,11 @@ namespace Ryujinx.Graphics.Shader.Translation
_usedTextures = new(); _usedTextures = new();
_usedImages = new(); _usedImages = new();
_vacConstantBuffers = new();
_vacStorageBuffers = new();
_vacTextures = new();
_vacImages = new();
Properties.AddOrUpdateConstantBuffer(new(BufferLayout.Std140, 0, SupportBuffer.Binding, "support_buffer", SupportBuffer.GetStructureType())); Properties.AddOrUpdateConstantBuffer(new(BufferLayout.Std140, 0, SupportBuffer.Binding, "support_buffer", SupportBuffer.GetStructureType()));
LocalMemoryId = -1; LocalMemoryId = -1;
@ -563,6 +573,75 @@ namespace Ryujinx.Graphics.Shader.Translation
return descriptors.ToArray(); return descriptors.ToArray();
} }
public ShaderProgramInfo GetVertexAsComputeInfo()
{
var cbDescriptors = new BufferDescriptor[_vacConstantBuffers.Count];
int cbDescriptorIndex = 0;
foreach (BufferDefinition definition in _vacConstantBuffers)
{
cbDescriptors[cbDescriptorIndex++] = new BufferDescriptor(definition.Set, definition.Binding, 0, 0, 0, BufferUsageFlags.None);
}
var sbDescriptors = new BufferDescriptor[_vacStorageBuffers.Count];
int sbDescriptorIndex = 0;
foreach (BufferDefinition definition in _vacStorageBuffers)
{
sbDescriptors[sbDescriptorIndex++] = new BufferDescriptor(definition.Set, definition.Binding, 0, 0, 0, BufferUsageFlags.Write);
}
var tDescriptors = new TextureDescriptor[_vacTextures.Count];
int tDescriptorIndex = 0;
foreach (TextureDefinition definition in _vacTextures)
{
tDescriptors[tDescriptorIndex++] = new TextureDescriptor(
definition.Set,
definition.Binding,
definition.Type,
definition.Format,
0,
0,
definition.ArrayLength,
definition.Separate,
definition.Flags);
}
var iDescriptors = new TextureDescriptor[_vacImages.Count];
int iDescriptorIndex = 0;
foreach (TextureDefinition definition in _vacImages)
{
iDescriptors[iDescriptorIndex++] = new TextureDescriptor(
definition.Set,
definition.Binding,
definition.Type,
definition.Format,
0,
0,
definition.ArrayLength,
definition.Separate,
definition.Flags);
}
return new ShaderProgramInfo(
cbDescriptors,
sbDescriptors,
tDescriptors,
iDescriptors,
ShaderStage.Compute,
0,
0,
0,
false,
false,
false,
false,
0,
0);
}
public bool TryGetCbufSlotAndHandleForTexture(int binding, out int cbufSlot, out int handle) public bool TryGetCbufSlotAndHandleForTexture(int binding, out int cbufSlot, out int handle)
{ {
foreach ((TextureInfo info, TextureMeta meta) in _usedTextures) foreach ((TextureInfo info, TextureMeta meta) in _usedTextures)
@ -629,6 +708,30 @@ namespace Ryujinx.Graphics.Shader.Translation
Properties.AddOrUpdateStorageBuffer(new(BufferLayout.Std430, setIndex, binding, name, type)); Properties.AddOrUpdateStorageBuffer(new(BufferLayout.Std430, setIndex, binding, name, type));
} }
public void AddVertexAsComputeConstantBuffer(BufferDefinition definition)
{
_vacConstantBuffers.Add(definition);
Properties.AddOrUpdateConstantBuffer(definition);
}
public void AddVertexAsComputeStorageBuffer(BufferDefinition definition)
{
_vacStorageBuffers.Add(definition);
Properties.AddOrUpdateStorageBuffer(definition);
}
public void AddVertexAsComputeTexture(TextureDefinition definition)
{
_vacTextures.Add(definition);
Properties.AddOrUpdateTexture(definition);
}
public void AddVertexAsComputeImage(TextureDefinition definition)
{
_vacImages.Add(definition);
Properties.AddOrUpdateImage(definition);
}
public static string GetShaderStagePrefix(ShaderStage stage) public static string GetShaderStagePrefix(ShaderStage stage)
{ {
uint index = (uint)stage; uint index = (uint)stage;

View file

@ -394,7 +394,7 @@ namespace Ryujinx.Graphics.Shader.Translation
{ {
int binding = resourceManager.Reservations.GetTfeBufferStorageBufferBinding(i); int binding = resourceManager.Reservations.GetTfeBufferStorageBufferBinding(i);
BufferDefinition tfeDataBuffer = new(BufferLayout.Std430, 1, binding, $"tfe_data{i}", tfeDataStruct); BufferDefinition tfeDataBuffer = new(BufferLayout.Std430, 1, binding, $"tfe_data{i}", tfeDataStruct);
resourceManager.Properties.AddOrUpdateStorageBuffer(tfeDataBuffer); resourceManager.AddVertexAsComputeStorageBuffer(tfeDataBuffer);
} }
} }
@ -402,7 +402,7 @@ namespace Ryujinx.Graphics.Shader.Translation
{ {
int vertexInfoCbBinding = resourceManager.Reservations.VertexInfoConstantBufferBinding; int vertexInfoCbBinding = resourceManager.Reservations.VertexInfoConstantBufferBinding;
BufferDefinition vertexInfoBuffer = new(BufferLayout.Std140, 0, vertexInfoCbBinding, "vb_info", VertexInfoBuffer.GetStructureType()); BufferDefinition vertexInfoBuffer = new(BufferLayout.Std140, 0, vertexInfoCbBinding, "vb_info", VertexInfoBuffer.GetStructureType());
resourceManager.Properties.AddOrUpdateConstantBuffer(vertexInfoBuffer); resourceManager.AddVertexAsComputeConstantBuffer(vertexInfoBuffer);
StructureType vertexOutputStruct = new(new StructureField[] StructureType vertexOutputStruct = new(new StructureField[]
{ {
@ -411,13 +411,13 @@ namespace Ryujinx.Graphics.Shader.Translation
int vertexOutputSbBinding = resourceManager.Reservations.VertexOutputStorageBufferBinding; int vertexOutputSbBinding = resourceManager.Reservations.VertexOutputStorageBufferBinding;
BufferDefinition vertexOutputBuffer = new(BufferLayout.Std430, 1, vertexOutputSbBinding, "vertex_output", vertexOutputStruct); BufferDefinition vertexOutputBuffer = new(BufferLayout.Std430, 1, vertexOutputSbBinding, "vertex_output", vertexOutputStruct);
resourceManager.Properties.AddOrUpdateStorageBuffer(vertexOutputBuffer); resourceManager.AddVertexAsComputeStorageBuffer(vertexOutputBuffer);
if (Stage == ShaderStage.Vertex) if (Stage == ShaderStage.Vertex)
{ {
SetBindingPair ibSetAndBinding = resourceManager.Reservations.GetIndexBufferTextureSetAndBinding(); SetBindingPair ibSetAndBinding = resourceManager.Reservations.GetIndexBufferTextureSetAndBinding();
TextureDefinition indexBuffer = new(ibSetAndBinding.SetIndex, ibSetAndBinding.Binding, "ib_data", SamplerType.TextureBuffer); TextureDefinition indexBuffer = new(ibSetAndBinding.SetIndex, ibSetAndBinding.Binding, "ib_data", SamplerType.TextureBuffer);
resourceManager.Properties.AddOrUpdateTexture(indexBuffer); resourceManager.AddVertexAsComputeTexture(indexBuffer);
int inputMap = _program.AttributeUsage.UsedInputAttributes; int inputMap = _program.AttributeUsage.UsedInputAttributes;
@ -426,7 +426,7 @@ namespace Ryujinx.Graphics.Shader.Translation
int location = BitOperations.TrailingZeroCount(inputMap); int location = BitOperations.TrailingZeroCount(inputMap);
SetBindingPair setAndBinding = resourceManager.Reservations.GetVertexBufferTextureSetAndBinding(location); SetBindingPair setAndBinding = resourceManager.Reservations.GetVertexBufferTextureSetAndBinding(location);
TextureDefinition vaBuffer = new(setAndBinding.SetIndex, setAndBinding.Binding, $"vb_data{location}", SamplerType.TextureBuffer); TextureDefinition vaBuffer = new(setAndBinding.SetIndex, setAndBinding.Binding, $"vb_data{location}", SamplerType.TextureBuffer);
resourceManager.Properties.AddOrUpdateTexture(vaBuffer); resourceManager.AddVertexAsComputeTexture(vaBuffer);
inputMap &= ~(1 << location); inputMap &= ~(1 << location);
} }
@ -435,11 +435,11 @@ namespace Ryujinx.Graphics.Shader.Translation
{ {
SetBindingPair trbSetAndBinding = resourceManager.Reservations.GetTopologyRemapBufferTextureSetAndBinding(); SetBindingPair trbSetAndBinding = resourceManager.Reservations.GetTopologyRemapBufferTextureSetAndBinding();
TextureDefinition remapBuffer = new(trbSetAndBinding.SetIndex, trbSetAndBinding.Binding, "trb_data", SamplerType.TextureBuffer); TextureDefinition remapBuffer = new(trbSetAndBinding.SetIndex, trbSetAndBinding.Binding, "trb_data", SamplerType.TextureBuffer);
resourceManager.Properties.AddOrUpdateTexture(remapBuffer); resourceManager.AddVertexAsComputeTexture(remapBuffer);
int geometryVbOutputSbBinding = resourceManager.Reservations.GeometryVertexOutputStorageBufferBinding; int geometryVbOutputSbBinding = resourceManager.Reservations.GeometryVertexOutputStorageBufferBinding;
BufferDefinition geometryVbOutputBuffer = new(BufferLayout.Std430, 1, geometryVbOutputSbBinding, "geometry_vb_output", vertexOutputStruct); BufferDefinition geometryVbOutputBuffer = new(BufferLayout.Std430, 1, geometryVbOutputSbBinding, "geometry_vb_output", vertexOutputStruct);
resourceManager.Properties.AddOrUpdateStorageBuffer(geometryVbOutputBuffer); resourceManager.AddVertexAsComputeStorageBuffer(geometryVbOutputBuffer);
StructureType geometryIbOutputStruct = new(new StructureField[] StructureType geometryIbOutputStruct = new(new StructureField[]
{ {
@ -448,7 +448,7 @@ namespace Ryujinx.Graphics.Shader.Translation
int geometryIbOutputSbBinding = resourceManager.Reservations.GeometryIndexOutputStorageBufferBinding; int geometryIbOutputSbBinding = resourceManager.Reservations.GeometryIndexOutputStorageBufferBinding;
BufferDefinition geometryIbOutputBuffer = new(BufferLayout.Std430, 1, geometryIbOutputSbBinding, "geometry_ib_output", geometryIbOutputStruct); BufferDefinition geometryIbOutputBuffer = new(BufferLayout.Std430, 1, geometryIbOutputSbBinding, "geometry_ib_output", geometryIbOutputStruct);
resourceManager.Properties.AddOrUpdateStorageBuffer(geometryIbOutputBuffer); resourceManager.AddVertexAsComputeStorageBuffer(geometryIbOutputBuffer);
} }
resourceManager.SetVertexAsComputeLocalMemories(Definitions.Stage, Definitions.InputTopology); resourceManager.SetVertexAsComputeLocalMemories(Definitions.Stage, Definitions.InputTopology);
@ -481,6 +481,11 @@ namespace Ryujinx.Graphics.Shader.Translation
return new ResourceReservations(GpuAccessor, IsTransformFeedbackEmulated, vertexAsCompute: true, _vertexOutput, ioUsage); return new ResourceReservations(GpuAccessor, IsTransformFeedbackEmulated, vertexAsCompute: true, _vertexOutput, ioUsage);
} }
public ShaderProgramInfo GetVertexAsComputeInfo()
{
return CreateResourceManager(true).GetVertexAsComputeInfo();
}
public void SetVertexOutputMapForGeometryAsCompute(TranslatorContext vertexContext) public void SetVertexOutputMapForGeometryAsCompute(TranslatorContext vertexContext)
{ {
_vertexOutput = vertexContext._program.GetIoUsage(); _vertexOutput = vertexContext._program.GetIoUsage();
@ -498,7 +503,7 @@ namespace Ryujinx.Graphics.Shader.Translation
if (Stage == ShaderStage.Vertex) if (Stage == ShaderStage.Vertex)
{ {
BufferDefinition vertexInfoBuffer = new(BufferLayout.Std140, 0, vertexInfoCbBinding, "vb_info", VertexInfoBuffer.GetStructureType()); BufferDefinition vertexInfoBuffer = new(BufferLayout.Std140, 0, vertexInfoCbBinding, "vb_info", VertexInfoBuffer.GetStructureType());
resourceManager.Properties.AddOrUpdateConstantBuffer(vertexInfoBuffer); resourceManager.AddVertexAsComputeConstantBuffer(vertexInfoBuffer);
} }
StructureType vertexInputStruct = new(new StructureField[] StructureType vertexInputStruct = new(new StructureField[]
@ -508,7 +513,7 @@ namespace Ryujinx.Graphics.Shader.Translation
int vertexDataSbBinding = reservations.VertexOutputStorageBufferBinding; int vertexDataSbBinding = reservations.VertexOutputStorageBufferBinding;
BufferDefinition vertexOutputBuffer = new(BufferLayout.Std430, 1, vertexDataSbBinding, "vb_input", vertexInputStruct); BufferDefinition vertexOutputBuffer = new(BufferLayout.Std430, 1, vertexDataSbBinding, "vb_input", vertexInputStruct);
resourceManager.Properties.AddOrUpdateStorageBuffer(vertexOutputBuffer); resourceManager.AddVertexAsComputeStorageBuffer(vertexOutputBuffer);
var context = new EmitterContext(); var context = new EmitterContext();