Files
glitchy-engine-beef/GlitchyEngine/src/Renderer/ConstantBuffer.bf
T

129 lines
2.9 KiB
Beef

using System;
using GlitchyEngine.Math;
using DirectX.D3D11Shader;
using internal GlitchyEngine.Renderer;
namespace GlitchyEngine.Renderer
{
public class ConstantBuffer : Buffer
{
protected String _name ~ delete _;
protected String _engineBufferName ~ delete _;
/**
* The buffer that contains the buffer data on the CPU.
*/
protected internal uint8[] rawData ~ delete _;
protected BufferVariableCollection _variables = new BufferVariableCollection() ~ delete _;
protected bool _isDirty = true;
protected internal int _generation = 0;
/// Gets the name of the constant buffer.
public StringView Name => _name;
public StringView EngineBufferName => _engineBufferName;
public BufferVariableCollection Variables => _variables;
/// Gets a span to the rawData held on the CPU.
public Span<uint8> RawData => rawData;
protected this() {}
public this(StringView name, int64 size, StringView engineBufferName = "")
{
_name = new String(name);
if (!engineBufferName.IsEmpty)
{
_engineBufferName = new String(engineBufferName);
}
rawData = new uint8[size];
ConstructBuffer();
}
protected internal void AddVariable(BufferVariable ownVariable)
{
_variables.Add(ownVariable);
}
public void AddVariable(StringView name, StringView previewName, StringView editorTypeName, uint64 offset, uint64 sizeInBytes, bool isUsed, ShaderVariableType type, uint8 rows, uint8 columns, uint64 arraySize)
{
_variables.Add(new BufferVariable(name, this, type, columns, rows, (uint32)offset, (uint32)sizeInBytes, (uint32)arraySize, isUsed, previewName, editorTypeName));
}
/**
* Construct the buffer description.
*/
protected void ConstructBuffer()
{
_description.Size = (.)rawData.Count;
_description.BindFlags = .Constant;
_description.CPUAccess = .Write;
_description.Usage = .Dynamic;
_description.MiscFlags = .None;
}
/**
* Uploads the date to the GPU.
* @returns true if the GPU buffer was updated, false otherwise (i.e. it wasn't dirty).
*/
public virtual Result<void> Apply()
{
bool isDirty = false;
for (BufferVariable variable in _variables)
{
if (variable.IsDirty)
{
isDirty = true;
Enum.ClearFlag(ref variable.[Friend]_flags, .Dirty);
}
}
if (isDirty)
{
Result<void> setDataResult = PlatformSetData(rawData.CArray(), (uint32)rawData.Count, 0, .WriteDiscard);
if (setDataResult case .Err)
return .Err;
_generation++;
}
return .Ok;
}
}
public enum ShaderVariableType
{
case Bool;
case Float;
case Int;
case UInt;
// todo
public int ElementSizeInBytes()
{
switch (this)
{
case .Bool:
// TODO: I'm pretty sure this is wrong and should be 4 as well!
return 1;
case .Float:
return 4;
case .Int:
return 4;
case .UInt:
return 4;
default:
return 0;
}
}
}
}