diff options
Diffstat (limited to 'src/Ryujinx.Graphics.Gpu/Shader/ShaderInfoBuilder.cs')
-rw-r--r-- | src/Ryujinx.Graphics.Gpu/Shader/ShaderInfoBuilder.cs | 63 |
1 files changed, 55 insertions, 8 deletions
diff --git a/src/Ryujinx.Graphics.Gpu/Shader/ShaderInfoBuilder.cs b/src/Ryujinx.Graphics.Gpu/Shader/ShaderInfoBuilder.cs index 3fc32d71..83d92edc 100644 --- a/src/Ryujinx.Graphics.Gpu/Shader/ShaderInfoBuilder.cs +++ b/src/Ryujinx.Graphics.Gpu/Shader/ShaderInfoBuilder.cs @@ -16,15 +16,24 @@ namespace Ryujinx.Graphics.Gpu.Shader private const int TextureSetIndex = 2; private const int ImageSetIndex = 3; - private const ResourceStages SupportBufferStags = + private const ResourceStages SupportBufferStages = ResourceStages.Compute | ResourceStages.Vertex | ResourceStages.Fragment; + private const ResourceStages VtgStages = + ResourceStages.Vertex | + ResourceStages.TessellationControl | + ResourceStages.TessellationEvaluation | + ResourceStages.Geometry; + private readonly GpuContext _context; private int _fragmentOutputMap; + private readonly int _reservedConstantBuffers; + private readonly int _reservedStorageBuffers; + private readonly List<ResourceDescriptor>[] _resourceDescriptors; private readonly List<ResourceUsage>[] _resourceUsages; @@ -32,7 +41,8 @@ namespace Ryujinx.Graphics.Gpu.Shader /// Creates a new shader info builder. /// </summary> /// <param name="context">GPU context that owns the shaders that will be added to the builder</param> - public ShaderInfoBuilder(GpuContext context) + /// <param name="tfEnabled">Indicates if the graphics shader is used with transform feedback enabled</param> + public ShaderInfoBuilder(GpuContext context, bool tfEnabled) { _context = context; @@ -47,7 +57,22 @@ namespace Ryujinx.Graphics.Gpu.Shader _resourceUsages[index] = new(); } - AddDescriptor(SupportBufferStags, ResourceType.UniformBuffer, UniformSetIndex, 0, 1); + AddDescriptor(SupportBufferStages, ResourceType.UniformBuffer, UniformSetIndex, 0, 1); + + _reservedConstantBuffers = 1; // For the support buffer. + + if (!context.Capabilities.SupportsTransformFeedback && tfEnabled) + { + _reservedStorageBuffers = 5; + + AddDescriptor(VtgStages, ResourceType.StorageBuffer, StorageSetIndex, 0, 5); + AddUsage(VtgStages, ResourceType.StorageBuffer, ResourceAccess.Read, StorageSetIndex, 0, 1); + AddUsage(VtgStages, ResourceType.StorageBuffer, ResourceAccess.Write, StorageSetIndex, 1, 4); + } + else + { + _reservedStorageBuffers = 0; + } } /// <summary> @@ -86,8 +111,8 @@ namespace Ryujinx.Graphics.Gpu.Shader int texturesPerStage = (int)_context.Capabilities.MaximumTexturesPerStage; int imagesPerStage = (int)_context.Capabilities.MaximumImagesPerStage; - int uniformBinding = 1 + stageIndex * uniformsPerStage; - int storageBinding = stageIndex * storagesPerStage; + int uniformBinding = _reservedConstantBuffers + stageIndex * uniformsPerStage; + int storageBinding = _reservedStorageBuffers + stageIndex * storagesPerStage; int textureBinding = stageIndex * texturesPerStage * 2; int imageBinding = stageIndex * imagesPerStage * 2; @@ -136,6 +161,23 @@ namespace Ryujinx.Graphics.Gpu.Shader /// <summary> /// Adds buffer usage information to the list of usages. /// </summary> + /// <param name="stages">Shader stages where the resource is used</param> + /// <param name="type">Type of the resource</param> + /// <param name="access">How the resource is accessed by the shader stages where it is used</param> + /// <param name="setIndex">Descriptor set number where the resource will be bound</param> + /// <param name="binding">Binding number where the resource will be bound</param> + /// <param name="count">Number of resources bound at the binding location</param> + private void AddUsage(ResourceStages stages, ResourceType type, ResourceAccess access, int setIndex, int binding, int count) + { + for (int index = 0; index < count; index++) + { + _resourceUsages[setIndex].Add(new ResourceUsage(binding + index, type, stages, access)); + } + } + + /// <summary> + /// Adds buffer usage information to the list of usages. + /// </summary> /// <param name="buffers">Buffers to be added</param> /// <param name="stages">Stages where the buffers are used</param> /// <param name="setIndex">Descriptor set index where the buffers will be bound</param> @@ -212,10 +254,15 @@ namespace Ryujinx.Graphics.Gpu.Shader /// <param name="context">GPU context that owns the shaders</param> /// <param name="programs">Shaders from the disk cache</param> /// <param name="pipeline">Optional pipeline for background compilation</param> + /// <param name="tfEnabled">Indicates if the graphics shader is used with transform feedback enabled</param> /// <returns>Shader information</returns> - public static ShaderInfo BuildForCache(GpuContext context, IEnumerable<CachedShaderStage> programs, ProgramPipelineState? pipeline) + public static ShaderInfo BuildForCache( + GpuContext context, + IEnumerable<CachedShaderStage> programs, + ProgramPipelineState? pipeline, + bool tfEnabled) { - ShaderInfoBuilder builder = new ShaderInfoBuilder(context); + ShaderInfoBuilder builder = new ShaderInfoBuilder(context, tfEnabled); foreach (CachedShaderStage program in programs) { @@ -237,7 +284,7 @@ namespace Ryujinx.Graphics.Gpu.Shader /// <returns>Shader information</returns> public static ShaderInfo BuildForCompute(GpuContext context, ShaderProgramInfo info, bool fromCache = false) { - ShaderInfoBuilder builder = new ShaderInfoBuilder(context); + ShaderInfoBuilder builder = new ShaderInfoBuilder(context, tfEnabled: false); builder.AddStageInfo(info); |