|
@@ -1,9 +1,11 @@
|
|
|
using Ryujinx.Common;
|
|
using Ryujinx.Common;
|
|
|
using Ryujinx.Graphics.GAL;
|
|
using Ryujinx.Graphics.GAL;
|
|
|
|
|
+using Ryujinx.Graphics.Gpu.Image;
|
|
|
using Ryujinx.Graphics.Gpu.State;
|
|
using Ryujinx.Graphics.Gpu.State;
|
|
|
using Ryujinx.Graphics.Shader;
|
|
using Ryujinx.Graphics.Shader;
|
|
|
using Ryujinx.Memory.Range;
|
|
using Ryujinx.Memory.Range;
|
|
|
using System;
|
|
using System;
|
|
|
|
|
+using System.Collections.Generic;
|
|
|
using System.Collections.ObjectModel;
|
|
using System.Collections.ObjectModel;
|
|
|
using System.Linq;
|
|
using System.Linq;
|
|
|
|
|
|
|
@@ -31,6 +33,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|
|
private IndexBuffer _indexBuffer;
|
|
private IndexBuffer _indexBuffer;
|
|
|
private VertexBuffer[] _vertexBuffers;
|
|
private VertexBuffer[] _vertexBuffers;
|
|
|
private BufferBounds[] _transformFeedbackBuffers;
|
|
private BufferBounds[] _transformFeedbackBuffers;
|
|
|
|
|
+ private List<BufferTextureBinding> _bufferTextures;
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
|
/// Holds shader stage buffer state and binding information.
|
|
/// Holds shader stage buffer state and binding information.
|
|
@@ -138,6 +141,8 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|
|
_gpStorageBuffers[index] = new BuffersPerStage(Constants.TotalGpStorageBuffers);
|
|
_gpStorageBuffers[index] = new BuffersPerStage(Constants.TotalGpStorageBuffers);
|
|
|
_gpUniformBuffers[index] = new BuffersPerStage(Constants.TotalGpUniformBuffers);
|
|
_gpUniformBuffers[index] = new BuffersPerStage(Constants.TotalGpUniformBuffers);
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ _bufferTextures = new List<BufferTextureBinding>();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
@@ -620,10 +625,39 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|
|
|
|
|
|
|
_context.Renderer.Pipeline.SetUniformBuffers(uRanges);
|
|
_context.Renderer.Pipeline.SetUniformBuffers(uRanges);
|
|
|
|
|
|
|
|
|
|
+ CommitBufferTextureBindings();
|
|
|
|
|
+
|
|
|
// Force rebind after doing compute work.
|
|
// Force rebind after doing compute work.
|
|
|
_rebind = true;
|
|
_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>
|
|
/// <summary>
|
|
|
/// Ensures that the graphics engine bindings are visible to the host GPU.
|
|
/// Ensures that the graphics engine bindings are visible to the host GPU.
|
|
|
/// Note: this actually performs the binding using the host graphics API.
|
|
/// Note: this actually performs the binding using the host graphics API.
|
|
@@ -743,6 +777,8 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|
|
UpdateBuffers(_gpUniformBuffers);
|
|
UpdateBuffers(_gpUniformBuffers);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ CommitBufferTextureBindings();
|
|
|
|
|
+
|
|
|
_rebind = false;
|
|
_rebind = false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -813,31 +849,19 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// <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>
|
|
/// </summary>
|
|
|
/// <param name="texture">Buffer texture</param>
|
|
/// <param name="texture">Buffer texture</param>
|
|
|
/// <param name="address">Address of the buffer in memory</param>
|
|
/// <param name="address">Address of the buffer in memory</param>
|
|
|
/// <param name="size">Size of the buffer in bytes</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);
|
|
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>
|
|
/// <summary>
|