Files
glitchy-engine-beef/GlitchyEngine/src/Platform/DX11/Renderer/Dx11Buffer.bf
T

121 lines
3.1 KiB
Beef

#if GE_D3D11
using System.Diagnostics;
using System;
using DirectX.D3D11;
using internal GlitchyEngine.Renderer;
using GlitchyEngine.Platform.DX11;
using internal GlitchyEngine.Platform.DX11;
namespace GlitchyEngine.Renderer
{
extension BufferDescription
{
public static operator DirectX.D3D11.BufferDescription(Self desc)
{
DirectX.D3D11.BufferDescription result;
result.ByteWidth = desc.Size;
result.Usage = (.)desc.Usage;
result.CpuAccessFlags = (.)desc.CPUAccess;
result.BindFlags = .None;
if(desc.BindFlags.HasFlag(.Constant))
{
result.BindFlags |= .ConstantBuffer;
}
if(desc.BindFlags.HasFlag(.Index))
{
result.BindFlags |= .IndexBuffer;
}
if(desc.BindFlags.HasFlag(.Vertex))
{
result.BindFlags |= .VertexBuffer;
}
result.MiscFlags = .None;
result.StructureByteStride = 0;
return result;
}
}
public extension MapType
{
public static explicit operator DirectX.D3D11.MapType(Self mapType)
{
return (.)(uint32)mapType;
}
}
public extension Buffer
{
// Todo: nativeBuffer contains exactly that!
internal DirectX.D3D11.BufferDescription nativeDescription;
internal ID3D11Buffer* nativeBuffer ~ _?.Release();
private Result<void> InternalCreateBuffer(void* data, uint32 byteLength, uint32 dstByteOffset)
{
nativeDescription = (.)_description;
uint8* byteData = (.)data;
if(dstByteOffset == 0)
{
byteData = new uint8[nativeDescription.ByteWidth]*;
defer:: delete byteData;
Internal.MemCpy(byteData + dstByteOffset, data, byteLength);
}
SubresourceData srData = .(byteData, byteLength, 0);
var result = NativeDevice.CreateBuffer(ref nativeDescription, &srData, &nativeBuffer);
if(result.Failed)
{
Log.EngineLogger.Error($"Failed to create buffer. Message({(int)result}):{result}");
return .Err;
}
return .Ok;
}
protected override Result<void> PlatformSetData(void* data, uint32 byteLength, uint32 dstByteOffset, GlitchyEngine.Renderer.MapType mapType)
{
if(nativeBuffer == null)
{
// We can pass the data while creating the buffer, so we can return here.
return InternalCreateBuffer(data, byteLength, dstByteOffset);
}
Debug.Assert(dstByteOffset + byteLength <= _description.Size, "The destination offset and byte length are too long for the target buffer.");
switch(nativeDescription.Usage)
{
case .Default:
Box dataBox = .(dstByteOffset, 0, 0, dstByteOffset + byteLength, 1, 1);
NativeContext.UpdateSubresource(nativeBuffer, 0, &dataBox, data, byteLength, byteLength);
case .Dynamic:
Debug.Assert(mapType.CanWrite, "The map type has to have write access.");
// Todo: DoNotWaitFlag
MappedSubresource map = ?;
NativeContext.Map(nativeBuffer, 0, (.)mapType, .None, &map);
Internal.MemCpy(((uint8*)map.Data) + dstByteOffset, data, byteLength);
NativeContext.Unmap(nativeBuffer, 0);
case .Immutable:
Log.EngineLogger.Error("Can't set the data of an immutable resource.");
return .Err;
default:
Log.EngineLogger.Error($"Unknown resource usage: engine={_description.Usage}, native={nativeDescription.Usage}");
return .Err;
}
return .Ok;
}
}
}
#endif