Files
2026-07-13 13:13:17 +08:00

91 lines
3.5 KiB
C#

using SharpDX.Direct3D11;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using T3.Core.Utils;
using Buffer = SharpDX.Direct3D11.Buffer;
namespace T3.Core.Rendering
{
public static class ResourceUtils
{
//Constant buffers are always aligned to 16 bytes
private const int CBufferAlignment = 16;
private const int CBufferAlignmentMinusOne = CBufferAlignment - 1;
/*It should be preferable to use this, even is driver does not enforce 256 alignment on creation,
driver will do it anyway, so that avoids recreating resources for very small buffers */
private const int CBufferReadAlignment = 256;
private const int CBufferReadAlignmentMinusOne = 255;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int GetBufferSize(int requestedSize)
{
int size = ((requestedSize + CBufferAlignmentMinusOne) / CBufferAlignment) * CBufferAlignment;
return size;
}
public static Buffer CreateDynamicConstantBuffer(Device device, int requestedSize)
{
int size = GetBufferSize(requestedSize);
var bufferDesc = new BufferDescription
{
Usage = ResourceUsage.Dynamic,
CpuAccessFlags = CpuAccessFlags.Write,
SizeInBytes = size,
BindFlags = BindFlags.ConstantBuffer
};
return new Buffer(device, bufferDesc);
}
public static bool GetDynamicConstantBuffer(Device device, ref Buffer buffer, int requestedSize)
{
int size = GetBufferSize(requestedSize);
if (buffer != null && buffer.Description.SizeInBytes != size)
{
Utilities.Dispose(ref buffer);
}
if (buffer == null)
{
buffer = CreateDynamicConstantBuffer(device, requestedSize);
return true;
}
else
{
return false;
}
}
public static unsafe void WriteDynamicBufferData<T>(DeviceContext deviceContext, Buffer buffer, ReadOnlySpan<T> data) where T : unmanaged
{
// Use the no-DataStream MapSubresource overload — the (..., out DataStream) overloads
// allocate a managed DataStream wrapper per call which becomes the dominant per-iteration
// allocation under heavy [Loop] use.
SharpDX.DataBox box = deviceContext.MapSubresource(buffer, 0, MapMode.WriteDiscard, MapFlags.None);
Span<T> boxData = new Span<T>((void*)box.DataPointer, data.Length);
data.CopyTo(boxData);
deviceContext.UnmapSubresource(buffer, 0);
}
public static unsafe void WriteDynamicBufferData<T>(DeviceContext deviceContext, Buffer buffer, T data) where T : unmanaged
{
SharpDX.DataBox box = deviceContext.MapSubresource(buffer, 0, MapMode.WriteDiscard, MapFlags.None);
Unsafe.Write((void*)box.DataPointer, data);
deviceContext.UnmapSubresource(buffer, 0);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool GetDynamicConstantBuffer<T>(Device device, ref Buffer buffer, int elementCount) where T : unmanaged
{
return GetDynamicConstantBuffer(device, ref buffer, elementCount * Unsafe.SizeOf<T>());
}
}
}