diff options
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Memory')
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Memory/BufferManager.cs | 60 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Memory/BufferTextureBinding.cs | 60 |
2 files changed, 102 insertions, 18 deletions
diff --git a/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs b/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs index 08d52faa..b2cd1ced 100644 --- a/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs +++ b/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs @@ -1,9 +1,11 @@ using Ryujinx.Common; using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.Gpu.Image; using Ryujinx.Graphics.Gpu.State; using Ryujinx.Graphics.Shader; using Ryujinx.Memory.Range; using System; +using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; @@ -31,6 +33,7 @@ namespace Ryujinx.Graphics.Gpu.Memory private IndexBuffer _indexBuffer; private VertexBuffer[] _vertexBuffers; private BufferBounds[] _transformFeedbackBuffers; + private List<BufferTextureBinding> _bufferTextures; /// <summary> /// Holds shader stage buffer state and binding information. @@ -138,6 +141,8 @@ namespace Ryujinx.Graphics.Gpu.Memory _gpStorageBuffers[index] = new BuffersPerStage(Constants.TotalGpStorageBuffers); _gpUniformBuffers[index] = new BuffersPerStage(Constants.TotalGpUniformBuffers); } + + _bufferTextures = new List<BufferTextureBinding>(); } /// <summary> @@ -620,11 +625,40 @@ namespace Ryujinx.Graphics.Gpu.Memory _context.Renderer.Pipeline.SetUniformBuffers(uRanges); + CommitBufferTextureBindings(); + // Force rebind after doing compute work. _rebind = true; } /// <summary> + /// Commit any queued buffer texture bindings. + /// </summary> + private void CommitBufferTextureBindings() + { + if (_bufferTextures.Count > 0) + { + foreach (var binding in _bufferTextures) + { + binding.Texture.SetStorage(GetBufferRange(binding.Address, binding.Size, binding.BindingInfo.Flags.HasFlag(TextureUsageFlags.ImageStore))); + + // The texture must be rebound to use the new storage if it was updated. + + if (binding.IsImage) + { + _context.Renderer.Pipeline.SetImage(binding.BindingInfo.Binding, binding.Texture, binding.Format); + } + else + { + _context.Renderer.Pipeline.SetTexture(binding.BindingInfo.Binding, binding.Texture); + } + } + + _bufferTextures.Clear(); + } + } + + /// <summary> /// Ensures that the graphics engine bindings are visible to the host GPU. /// Note: this actually performs the binding using the host graphics API. /// </summary> @@ -743,6 +777,8 @@ namespace Ryujinx.Graphics.Gpu.Memory UpdateBuffers(_gpUniformBuffers); } + CommitBufferTextureBindings(); + _rebind = false; } @@ -813,31 +849,19 @@ namespace Ryujinx.Graphics.Gpu.Memory } /// <summary> - /// Sets the buffer storage of a buffer texture. + /// Sets the buffer storage of a buffer texture. This will be bound when the buffer manager commits bindings. /// </summary> /// <param name="texture">Buffer texture</param> /// <param name="address">Address of the buffer in memory</param> /// <param name="size">Size of the buffer in bytes</param> - /// <param name="compute">Indicates if the buffer texture belongs to the compute or graphics pipeline</param> - public void SetBufferTextureStorage(ITexture texture, ulong address, ulong size, bool compute) + /// <param name="bindingInfo">Binding info for the buffer texture</param> + /// <param name="format">Format of the buffer texture</param> + /// <param name="isImage">Whether the binding is for an image or a sampler</param> + public void SetBufferTextureStorage(ITexture texture, ulong address, ulong size, TextureBindingInfo bindingInfo, Format format, bool isImage) { CreateBuffer(address, size); - if (_rebind) - { - // We probably had to modify existing buffers to create the texture buffer, - // so rebind everything to ensure we're using the new buffers for all bound resources. - if (compute) - { - CommitComputeBindings(); - } - else - { - CommitGraphicsBindings(); - } - } - - texture.SetStorage(GetBufferRange(address, size)); + _bufferTextures.Add(new BufferTextureBinding(texture, address, size, bindingInfo, format, isImage)); } /// <summary> diff --git a/Ryujinx.Graphics.Gpu/Memory/BufferTextureBinding.cs b/Ryujinx.Graphics.Gpu/Memory/BufferTextureBinding.cs new file mode 100644 index 00000000..cf0d225e --- /dev/null +++ b/Ryujinx.Graphics.Gpu/Memory/BufferTextureBinding.cs @@ -0,0 +1,60 @@ +using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.Gpu.Image; + +namespace Ryujinx.Graphics.Gpu.Memory +{ + /// <summary> + /// A buffer binding to apply to a buffer texture. + /// </summary> + struct BufferTextureBinding + { + /// <summary> + /// The buffer texture. + /// </summary> + public ITexture Texture { get; } + + /// <summary> + /// The base address of the buffer binding. + /// </summary> + public ulong Address { get; } + + /// <summary> + /// The size of the buffer binding in bytes. + /// </summary> + public ulong Size { get; } + + /// <summary> + /// The image or sampler binding info for the buffer texture. + /// </summary> + public TextureBindingInfo BindingInfo { get; } + + /// <summary> + /// The image format for the binding. + /// </summary> + public Format Format { get; } + + /// <summary> + /// Whether the binding is for an image or a sampler. + /// </summary> + public bool IsImage { get; } + + /// <summary> + /// Create a new buffer texture binding. + /// </summary> + /// <param name="texture">Buffer texture</param> + /// <param name="address">Base address</param> + /// <param name="size">Size in bytes</param> + /// <param name="bindingInfo">Binding info</param> + /// <param name="format">Binding format</param> + /// <param name="isImage">Whether the binding is for an image or a sampler</param> + public BufferTextureBinding(ITexture texture, ulong address, ulong size, TextureBindingInfo bindingInfo, Format format, bool isImage) + { + Texture = texture; + Address = address; + Size = size; + BindingInfo = bindingInfo; + Format = format; + IsImage = isImage; + } + } +} |
