TransferUsage change

what_if_no_video_threads
cosmonaut 2024-03-08 15:29:44 -08:00
parent 9195e445b2
commit 69d2c9cc31
6 changed files with 77 additions and 31 deletions

@ -1 +1 @@
Subproject commit 029f19196a94e13b8ed98d10f47a701221951f2f
Subproject commit 8f42783fd15cfea57cfae421fd6ab36070df9946

View File

@ -35,7 +35,7 @@ namespace MoonWorks.Graphics.Font
VertexBuffer = GpuBuffer.Create<Vertex>(GraphicsDevice, BufferUsageFlags.Vertex, INITIAL_VERTEX_COUNT);
IndexBuffer = GpuBuffer.Create<uint>(GraphicsDevice, BufferUsageFlags.Index, INITIAL_INDEX_COUNT);
TransferBuffer = TransferBuffer.Create<byte>(GraphicsDevice, VertexBuffer.Size + IndexBuffer.Size);
TransferBuffer = TransferBuffer.Create<byte>(GraphicsDevice, TransferUsage.Buffer, VertexBuffer.Size + IndexBuffer.Size);
}
// Call this to initialize or reset the batch.
@ -119,7 +119,7 @@ namespace MoonWorks.Graphics.Font
if (newTransferBufferNeeded)
{
TransferBuffer.Dispose();
TransferBuffer = new TransferBuffer(GraphicsDevice, VertexBuffer.Size + IndexBuffer.Size);
TransferBuffer = new TransferBuffer(GraphicsDevice, TransferUsage.Buffer, VertexBuffer.Size + IndexBuffer.Size);
}
if (vertexDataLengthInBytes > 0 && indexDataLengthInBytes > 0)

View File

@ -297,6 +297,12 @@ namespace MoonWorks.Graphics
IntOpaqueWhite
}
public enum TransferUsage
{
Buffer,
Texture
}
public enum TransferOptions
{
Cycle,

View File

@ -15,18 +15,24 @@ namespace MoonWorks.Graphics
/// </summary>
public unsafe class ResourceUploader : GraphicsResource
{
TransferBuffer TransferBuffer;
TransferBuffer BufferTransferBuffer;
TransferBuffer TextureTransferBuffer;
byte* data;
uint dataOffset = 0;
uint dataSize = 1024;
byte* bufferData;
uint bufferDataOffset = 0;
uint bufferDataSize = 1024;
byte* textureData;
uint textureDataOffset = 0;
uint textureDataSize = 1024;
List<(GpuBuffer, BufferCopy, WriteOptions)> BufferUploads = new List<(GpuBuffer, BufferCopy, WriteOptions)>();
List<(TextureRegion, uint, WriteOptions)> TextureUploads = new List<(TextureRegion, uint, WriteOptions)>();
public ResourceUploader(GraphicsDevice device) : base(device)
{
data = (byte*) NativeMemory.Alloc(dataSize);
bufferData = (byte*) NativeMemory.Alloc(bufferDataSize);
textureData = (byte*) NativeMemory.Alloc(textureDataSize);
}
// Buffers
@ -56,7 +62,7 @@ namespace MoonWorks.Graphics
uint resourceOffset;
fixed (void* spanPtr = data)
{
resourceOffset = CopyData(spanPtr, lengthInBytes);
resourceOffset = CopyBufferData(spanPtr, lengthInBytes);
}
var bufferCopyParams = new BufferCopy(resourceOffset, offsetInBytes, lengthInBytes);
@ -213,7 +219,7 @@ namespace MoonWorks.Graphics
uint resourceOffset;
fixed (T* dataPtr = data)
{
resourceOffset = CopyDataAligned(dataPtr, dataLengthInBytes, Texture.TexelSize(textureRegion.TextureSlice.Texture.Format));
resourceOffset = CopyTextureData(dataPtr, dataLengthInBytes, Texture.TexelSize(textureRegion.TextureSlice.Texture.Format));
}
TextureUploads.Add((textureRegion, resourceOffset, option));
@ -252,14 +258,30 @@ namespace MoonWorks.Graphics
private void CopyToTransferBuffer()
{
if (TransferBuffer == null || TransferBuffer.Size < dataSize)
if (BufferUploads.Count > 0)
{
TransferBuffer?.Dispose();
TransferBuffer = new TransferBuffer(Device, dataSize);
if (BufferTransferBuffer == null || BufferTransferBuffer.Size < bufferDataSize)
{
BufferTransferBuffer?.Dispose();
BufferTransferBuffer = new TransferBuffer(Device, TransferUsage.Buffer, bufferDataSize);
}
var dataSpan = new Span<byte>(bufferData, (int) bufferDataSize);
BufferTransferBuffer.SetData(dataSpan, TransferOptions.Cycle);
}
var dataSpan = new Span<byte>(data, (int) dataSize);
TransferBuffer.SetData(dataSpan, TransferOptions.Cycle);
if (TextureUploads.Count > 0)
{
if (TextureTransferBuffer == null || TextureTransferBuffer.Size < textureDataSize)
{
TextureTransferBuffer?.Dispose();
TextureTransferBuffer = new TransferBuffer(Device, TransferUsage.Texture, textureDataSize);
}
var dataSpan = new Span<byte>(textureData, (int) textureDataSize);
TextureTransferBuffer.SetData(dataSpan, TransferOptions.Cycle);
}
}
private void RecordUploadCommands(CommandBuffer commandBuffer)
@ -269,7 +291,7 @@ namespace MoonWorks.Graphics
foreach (var (gpuBuffer, bufferCopyParams, option) in BufferUploads)
{
commandBuffer.UploadToBuffer(
TransferBuffer,
BufferTransferBuffer,
gpuBuffer,
bufferCopyParams,
option
@ -279,7 +301,7 @@ namespace MoonWorks.Graphics
foreach (var (textureRegion, offset, option) in TextureUploads)
{
commandBuffer.UploadToTexture(
TransferBuffer,
TextureTransferBuffer,
textureRegion,
new BufferImageCopy(
offset,
@ -294,29 +316,41 @@ namespace MoonWorks.Graphics
BufferUploads.Clear();
TextureUploads.Clear();
dataOffset = 0;
bufferDataOffset = 0;
}
private uint CopyData(void* ptr, uint lengthInBytes)
private uint CopyBufferData(void* ptr, uint lengthInBytes)
{
if (dataOffset + lengthInBytes >= dataSize)
if (bufferDataOffset + lengthInBytes >= bufferDataSize)
{
dataSize = dataOffset + lengthInBytes;
data = (byte*) NativeMemory.Realloc(data, dataSize);
bufferDataSize = bufferDataOffset + lengthInBytes;
bufferData = (byte*) NativeMemory.Realloc(bufferData, bufferDataSize);
}
var resourceOffset = dataOffset;
var resourceOffset = bufferDataOffset;
NativeMemory.Copy(ptr, data + dataOffset, lengthInBytes);
dataOffset += lengthInBytes;
NativeMemory.Copy(ptr, bufferData + bufferDataOffset, lengthInBytes);
bufferDataOffset += lengthInBytes;
return resourceOffset;
}
private uint CopyDataAligned(void* ptr, uint lengthInBytes, uint alignment)
private uint CopyTextureData(void* ptr, uint lengthInBytes, uint alignment)
{
dataOffset = RoundToAlignment(dataOffset, alignment);
return CopyData(ptr, lengthInBytes);
textureDataOffset = RoundToAlignment(textureDataOffset, alignment);
if (textureDataOffset + lengthInBytes >= textureDataSize)
{
textureDataSize = textureDataOffset + lengthInBytes;
textureData = (byte*) NativeMemory.Realloc(textureData, textureDataSize);
}
var resourceOffset = textureDataOffset;
NativeMemory.Copy(ptr, textureData + textureDataOffset, lengthInBytes);
textureDataOffset += lengthInBytes;
return resourceOffset;
}
private uint RoundToAlignment(uint value, uint alignment)
@ -335,10 +369,11 @@ namespace MoonWorks.Graphics
{
if (disposing)
{
TransferBuffer?.Dispose();
BufferTransferBuffer?.Dispose();
TextureTransferBuffer?.Dispose();
}
NativeMemory.Free(data);
NativeMemory.Free(bufferData);
}
base.Dispose(disposing);
}

View File

@ -22,11 +22,13 @@ namespace MoonWorks.Graphics
/// <returns></returns>
public unsafe static TransferBuffer Create<T>(
GraphicsDevice device,
TransferUsage usage,
uint elementCount
) where T : unmanaged
{
return new TransferBuffer(
device,
usage,
(uint) Marshal.SizeOf<T>() * elementCount
);
}
@ -36,13 +38,16 @@ namespace MoonWorks.Graphics
/// </summary>
/// <param name="device">An initialized GraphicsDevice.</param>
/// <param name="sizeInBytes">The length of the buffer. Cannot be resized.</param>
/// <param name="usage">Whether this will be used to upload buffers or textures.</param>
public TransferBuffer(
GraphicsDevice device,
TransferUsage usage,
uint sizeInBytes
) : base(device)
{
Handle = Refresh.Refresh_CreateTransferBuffer(
device.Handle,
(Refresh.TransferUsage) usage,
sizeInBytes
);
Size = sizeInBytes;

View File

@ -241,7 +241,7 @@ namespace MoonWorks.Video
if (TransferBuffer == null || TransferBuffer.Size < ySpan.Length + uSpan.Length + vSpan.Length)
{
TransferBuffer?.Dispose();
TransferBuffer = new TransferBuffer(Device, (uint) (ySpan.Length + uSpan.Length + vSpan.Length));
TransferBuffer = new TransferBuffer(Device, TransferUsage.Texture, (uint) (ySpan.Length + uSpan.Length + vSpan.Length));
}
TransferBuffer.SetData(ySpan, 0, TransferOptions.Cycle);
TransferBuffer.SetData(uSpan, (uint) ySpan.Length, TransferOptions.Overwrite);