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

198 lines
5.6 KiB
Beef

using System;
using GlitchyEngine.Math;
namespace GlitchyEngine.Renderer
{
using internal GlitchyEngine.Renderer;
public class BufferVariable
{
private ConstantBuffer _constantBuffer;
private String _name ~ delete _;
private ShaderVariableType _type;
internal uint32 _columns;
internal uint32 _rows;
private uint32 _offset;
internal uint32 _sizeInBytes;
// Number of elements in the array
internal uint32 _elements;
private bool _isUsed;
public ConstantBuffer ConstantBuffer => _constantBuffer;
public ShaderVariableType Type => _type;
public String Name => _name;
public bool IsUsed => _isUsed;
/**
* Gets a pointer to the start of the variable in the constant buffers backing data.
*/
[Inline]
internal uint8* firstByte => _constantBuffer.rawData.CArray() + _offset;
public this(ConstantBuffer constantBuffer, ShaderVariableType type, uint32 columns, uint32 rows, uint32 offset, uint32 sizeInBytes, uint32 elements, bool isUsed)
{
_constantBuffer = constantBuffer..AddRef();
_type = type;
_columns = columns;
_rows = rows;
_offset = offset;
_sizeInBytes = sizeInBytes;
_elements = elements;
_isUsed = isUsed;
}
public void EnsureTypeMatch(int rows, int cols, ShaderVariableType type)
{
#if GE_ERROR_SHADER_MATRIX_MISMATCH
Log.EngineLogger.Assert(rows == _rows || cols == _columns, scope $"The matrix-dimensions do not match: Expected {_rows} rows and {_rows} columns but Received {rows} rows and {cols} columns instead. Variable: \"{_name}\" of buffer: \"{_constantBuffer.Name}\"");
#elif GE_WARN_SHADER_MATRIX_MISMATCH
if (rows != _rows || cols != _columns)
Log.EngineLogger.Warning($"The matrix-dimensions do not match: Expected {_rows} rows and {_rows} columns but Received {rows} rows and {cols} columns instead. Variable: \"{_name}\" of buffer: \"{_constantBuffer.Name}\"");
#endif
#if GE_ERROR_SHADER_VAR_TYPE_MISMATCH
Log.EngineLogger.Assert(type == _type, scope $"The types do not match: Expected \"{_type}\" but Received \"{type}\" instead. Variable: \"{_name}\" of buffer: \"{_constantBuffer.Name}\"");
#elif GE_WARN_SHADER_VAR_TYPE_MISMATCH
if (type != _type)
Log.EngineLogger.Warning($"The types do not match: Expected \"{_type}\" but Received \"{type}\" instead. Variable: \"{_name}\" of buffer: \"{_constantBuffer.Name}\"");
#endif
}
public void EnsureTypeMatch<T>()
{
switch(typeof(T))
{
case typeof(bool):
EnsureTypeMatch(1, 1, .Bool);
case typeof(float):
EnsureTypeMatch(1, 1, .Float);
case typeof(Vector2):
EnsureTypeMatch(1, 2, .Float);
case typeof(Vector3):
EnsureTypeMatch(1, 3, .Float);
case typeof(Vector4):
EnsureTypeMatch(1, 4, .Float);
case typeof(int32):
EnsureTypeMatch(1, 1, .Int);
case typeof(Int32_2):
EnsureTypeMatch(1, 2, .Int);
case typeof(Int32_3):
EnsureTypeMatch(1, 3, .Int);
case typeof(Int32_4):
EnsureTypeMatch(1, 4, .Int);
case typeof(Matrix4x3):
EnsureTypeMatch(4, 3, .Float);
case typeof(Matrix3x3):
EnsureTypeMatch(3, 3, .Float);
case typeof(Matrix):
EnsureTypeMatch(4, 4, .Float);
case typeof(ColorRGB):
EnsureTypeMatch(1, 3, .Float);
case typeof(ColorRGBA):
EnsureTypeMatch(1, 4, .Float);
case typeof(Color):
EnsureTypeMatch(1, 4, .Float);
}
}
[Inline]
private void SetData<T>(T value)
{
EnsureTypeMatch<T>();
*(T*)firstByte = value;
}
public void SetData(bool value) => SetData<bool>(value);
public void SetData(float value) => SetData<float>(value);
public void SetData(Vector2 value) => SetData<Vector2>(value);
public void SetData(Vector3 value) => SetData<Vector3>(value);
public void SetData(Vector4 value) => SetData<Vector4>(value);
public void SetData(int32 value) => SetData<int32>(value);
public void SetData(Int32_2 value) => SetData<Int32_2>(value);
public void SetData(Int32_3 value) => SetData<Int32_3>(value);
public void SetData(Int32_4 value) => SetData<Int32_4>(value);
public void SetData(ColorRGB value) => SetData<ColorRGB>(value);
public void SetData(ColorRGBA value) => SetData<ColorRGBA>(value);
public void SetData(Color value) => SetData<ColorRGBA>((ColorRGBA)value);
public void SetData(Matrix4x3 value) => SetData<Matrix4x3>(value);
public void SetData(Matrix4x3[] value)
{
EnsureTypeMatch<Matrix4x3>();
// TODO: assert length
Internal.MemCpy(firstByte, value.Ptr, sizeof(Matrix4x3) * Math.Min(value.Count, _elements));
}
public void SetData(Matrix3x3 value)
{
EnsureTypeMatch<Matrix3x3>();
*(Matrix4x3*)firstByte = Matrix4x3(value);
// Todo: maybe manual copy
}
public void SetData(Matrix3x3[] value)
{
EnsureTypeMatch<Matrix3x3>();
// TODO: assert length
for(int i < Math.Min(value.Count, _elements))
{
((Matrix4x3*)firstByte)[i] = Matrix4x3(value[i]);
}
}
public void SetData(Matrix value) => SetData<Matrix>(value);
public void SetData(Matrix[] value)
{
EnsureTypeMatch<Matrix>();
// TODO: assert length
Internal.MemCpy(firstByte, value.Ptr, sizeof(Matrix) * Math.Min(value.Count, _elements));
}
// Todo: add all the other SetData-Methods
/**
* Sets the raw data of the variable.
* @param rawData The pointer to the raw data. If rawData is null the raw data will be set to zero.
*/
internal void SetRawData(void* rawData)
{
#if DEBUG && !GE_IGNORE_UNUSED_VARIABLE
if(!_isUsed)
{
Log.EngineLogger.Warning($"Setting data for unused Variable \"{_name}\" of constant buffer \"{_constantBuffer.Name}\".");
}
#endif
if(rawData != null)
Internal.MemCpy(firstByte, rawData, _sizeInBytes);
else
Internal.MemSet(firstByte, 0, _sizeInBytes);
}
}
}