mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 21:01:52 +00:00
Added RefCounting, added ConstantBuffers
This commit is contained in:
@@ -120,7 +120,7 @@ namespace GlitchyEngine.Renderer
|
||||
}
|
||||
|
||||
/// Represents a buffer containing binary data on the GPU.
|
||||
public class Buffer
|
||||
public class Buffer : RefCounted
|
||||
{
|
||||
internal GraphicsContext _context;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace GlitchyEngine.Renderer
|
||||
{
|
||||
public class BufferCollection
|
||||
{
|
||||
typealias BufferEntry = (String Name, int Index, Buffer Buffer, bool OwnsBuffer);
|
||||
typealias BufferEntry = (String Name, int Index, Buffer Buffer);//, bool OwnsBuffer
|
||||
|
||||
List<BufferEntry> _buffers ~ DeleteBufferEntries!(_);
|
||||
|
||||
@@ -33,8 +33,7 @@ namespace GlitchyEngine.Renderer
|
||||
for(let entry in entries)
|
||||
{
|
||||
delete entry.Name;
|
||||
if(entry.OwnsBuffer)
|
||||
delete entry.Buffer;
|
||||
entry.Buffer.ReleaseRef();
|
||||
}
|
||||
|
||||
delete entries;
|
||||
@@ -49,7 +48,7 @@ namespace GlitchyEngine.Renderer
|
||||
* @param buffer The new buffer.
|
||||
* @param If set to true, the Collection will take ownership of the buffer; if false, the ownership will remain with the caller.
|
||||
*/
|
||||
public void ReplaceBuffer(int idx, Buffer buffer, bool passOwnership = false)
|
||||
public void ReplaceBuffer(int idx, Buffer buffer)//, bool passOwnership = false
|
||||
{
|
||||
if(_idxToBuf.TryGetValue(idx, let oldBuffer))
|
||||
{
|
||||
@@ -59,11 +58,13 @@ namespace GlitchyEngine.Renderer
|
||||
|
||||
Log.EngineLogger.Assert(idx == bufferDesc.Index);
|
||||
|
||||
if(bufferDesc.OwnsBuffer)
|
||||
delete bufferDesc.Buffer;
|
||||
oldBuffer.ReleaseRef();
|
||||
//if(bufferDesc.OwnsBuffer)
|
||||
// delete bufferDesc.Buffer;
|
||||
|
||||
buffer.AddRef();
|
||||
bufferDesc.Buffer = buffer;
|
||||
bufferDesc.OwnsBuffer = passOwnership;
|
||||
//bufferDesc.OwnsBuffer = passOwnership;
|
||||
|
||||
_strToBuf[bufferDesc.Name] = buffer;
|
||||
_idxToBuf[bufferDesc.Index] = buffer;
|
||||
@@ -80,7 +81,7 @@ namespace GlitchyEngine.Renderer
|
||||
* @param buffer The new buffer.
|
||||
* @param If set to true, the Collection will take ownership of the buffer; if false, the ownership will remain with the caller.
|
||||
*/
|
||||
public void ReplaceBuffer(StringView name, Buffer buffer, bool passOwnership = false)
|
||||
public void ReplaceBuffer(StringView name, Buffer buffer) // , bool passOwnership = false
|
||||
{
|
||||
if(_strToBuf.TryGetValue(name, let oldBuffer))
|
||||
{
|
||||
@@ -90,11 +91,13 @@ namespace GlitchyEngine.Renderer
|
||||
|
||||
Log.EngineLogger.Assert(name == bufferDesc.Name);
|
||||
|
||||
if(bufferDesc.OwnsBuffer)
|
||||
delete bufferDesc.Buffer;
|
||||
|
||||
oldBuffer.ReleaseRef();
|
||||
//if(bufferDesc.OwnsBuffer)
|
||||
// delete bufferDesc.Buffer;
|
||||
|
||||
buffer.AddRef();
|
||||
bufferDesc.Buffer = buffer;
|
||||
bufferDesc.OwnsBuffer = passOwnership;
|
||||
//bufferDesc.OwnsBuffer = passOwnership;
|
||||
|
||||
_strToBuf[bufferDesc.Name] = buffer;
|
||||
_idxToBuf[bufferDesc.Index] = buffer;
|
||||
@@ -111,7 +114,7 @@ namespace GlitchyEngine.Renderer
|
||||
* @param buffer The new buffer.
|
||||
* @param If set to true, the Collection will take ownership of the buffer; if false, the ownership will remain with the caller.
|
||||
*/
|
||||
public bool TryReplaceBuffer(StringView name, Buffer buffer, bool passOwnership = false)
|
||||
public bool TryReplaceBuffer(StringView name, Buffer buffer) // , bool passOwnership = false
|
||||
{
|
||||
if(_strToBuf.TryGetValue(name, let oldBuffer))
|
||||
{
|
||||
@@ -121,11 +124,13 @@ namespace GlitchyEngine.Renderer
|
||||
|
||||
Log.EngineLogger.Assert(name == bufferDesc.Name);
|
||||
|
||||
if(bufferDesc.OwnsBuffer)
|
||||
delete bufferDesc.Buffer;
|
||||
|
||||
//if(bufferDesc.OwnsBuffer)
|
||||
// delete bufferDesc.Buffer;
|
||||
oldBuffer.ReleaseRef();
|
||||
|
||||
buffer.AddRef();
|
||||
bufferDesc.Buffer = buffer;
|
||||
bufferDesc.OwnsBuffer = passOwnership;
|
||||
//bufferDesc.OwnsBuffer = passOwnership;
|
||||
|
||||
_strToBuf[bufferDesc.Name] = buffer;
|
||||
_idxToBuf[bufferDesc.Index] = buffer;
|
||||
@@ -138,11 +143,12 @@ namespace GlitchyEngine.Renderer
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(int index, StringView name, Buffer buffer, bool passOwnership = false)
|
||||
public void Add(int index, StringView name, Buffer buffer) //, bool passOwnership = false
|
||||
{
|
||||
String nameStr = new String(name);
|
||||
BufferEntry entry = (nameStr, index, buffer, passOwnership);
|
||||
BufferEntry entry = (nameStr, index, buffer); //, passOwnership
|
||||
|
||||
buffer.AddRef();
|
||||
_buffers.Add(entry);
|
||||
_strToBuf.Add(entry.Name, entry.Buffer);
|
||||
_idxToBuf.Add(entry.Index, entry.Buffer);
|
||||
|
||||
@@ -0,0 +1,212 @@
|
||||
using DirectX.D3D11Shader;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using GlitchyEngine.Math;
|
||||
|
||||
using internal GlitchyEngine.Renderer;
|
||||
|
||||
namespace GlitchyEngine.Renderer
|
||||
{
|
||||
public class ConstantBuffer : Buffer
|
||||
{
|
||||
protected String _name ~ delete _;
|
||||
|
||||
/**
|
||||
* The buffer that contains the buffer data on the CPU.
|
||||
*/
|
||||
protected internal uint8[] rawData ~ delete _;
|
||||
|
||||
protected List<BufferVariable> _variables = new .() ~ DeleteContainerAndItems!(_);
|
||||
protected Dictionary<String, BufferVariable> _nameToVariable = new .() ~ delete _;
|
||||
|
||||
/// Gets the name of the constant buffer.
|
||||
public String Name => _name;
|
||||
|
||||
protected this(GraphicsContext context) : base(context) {}
|
||||
|
||||
public BufferVariable this[String name] => _nameToVariable[name];
|
||||
|
||||
protected internal void AddVariable(BufferVariable ownVariable)
|
||||
{
|
||||
_variables.Add(ownVariable);
|
||||
_nameToVariable.Add(ownVariable.Name, ownVariable);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
public void Update()
|
||||
{
|
||||
PlatformSetData(rawData.CArray(), (uint32)rawData.Count, 0, .WriteDiscard);
|
||||
}
|
||||
}
|
||||
|
||||
public enum ShaderVariableType
|
||||
{
|
||||
Float,
|
||||
// todo
|
||||
}
|
||||
|
||||
public class BufferVariable
|
||||
{
|
||||
private ConstantBuffer _constantBuffer ~ _constantBuffer?.ReleaseRef();
|
||||
|
||||
private String _name ~ delete _;
|
||||
|
||||
private ShaderVariableType _type;
|
||||
|
||||
private uint32 _columns;
|
||||
private uint32 _rows;
|
||||
private uint32 _offset;
|
||||
private uint32 _sizeInBytes;
|
||||
|
||||
private bool _isUsed;
|
||||
|
||||
public ConstantBuffer ConstantBuffer => _constantBuffer;
|
||||
|
||||
public ShaderVariableType Type => _type;
|
||||
|
||||
public String Name => _name;
|
||||
|
||||
/**
|
||||
* 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, bool isUsed)
|
||||
{
|
||||
_constantBuffer = constantBuffer..AddRef();
|
||||
_type = type;
|
||||
_columns = columns;
|
||||
_rows = rows;
|
||||
_offset = offset;
|
||||
_sizeInBytes = sizeInBytes;
|
||||
_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 SetData(float value)
|
||||
{
|
||||
EnsureTypeMatch(1, 1, .Float);
|
||||
|
||||
*(float*)firstByte = value;
|
||||
}
|
||||
|
||||
public void SetData(Vector2 value)
|
||||
{
|
||||
EnsureTypeMatch(1, 2, .Float);
|
||||
|
||||
*(Vector2*)firstByte = value;
|
||||
}
|
||||
|
||||
public void SetData(Vector3 value)
|
||||
{
|
||||
EnsureTypeMatch(1, 3, .Float);
|
||||
|
||||
*(Vector3*)firstByte = value;
|
||||
}
|
||||
|
||||
public void SetData(Vector4 value)
|
||||
{
|
||||
EnsureTypeMatch(1, 4, .Float);
|
||||
|
||||
*(Vector4*)firstByte = value;
|
||||
}
|
||||
|
||||
public void SetData(Matrix4x3 value)
|
||||
{
|
||||
// I think this is right
|
||||
EnsureTypeMatch(4, 3, .Float);
|
||||
|
||||
*(Matrix4x3*)firstByte = value;
|
||||
}
|
||||
|
||||
public void SetData(Matrix3x3 value)
|
||||
{
|
||||
EnsureTypeMatch(3, 3, .Float);
|
||||
|
||||
*(Matrix4x3*)firstByte = Matrix4x3(value);
|
||||
|
||||
// Todo: maybe manual copy
|
||||
}
|
||||
|
||||
public void SetData(Matrix value)
|
||||
{
|
||||
EnsureTypeMatch(4, 4, .Float);
|
||||
|
||||
*(Matrix*)firstByte = value;
|
||||
}
|
||||
|
||||
public void SetData(ColorRGB value)
|
||||
{
|
||||
EnsureTypeMatch(1, 3, .Float);
|
||||
|
||||
*(ColorRGB*)firstByte = value;
|
||||
}
|
||||
|
||||
public void SetData(ColorRGBA value)
|
||||
{
|
||||
EnsureTypeMatch(1, 4, .Float);
|
||||
|
||||
*(ColorRGBA*)firstByte = value;
|
||||
}
|
||||
|
||||
public void SetData(Color value)
|
||||
{
|
||||
EnsureTypeMatch(1, 4, .Float);
|
||||
|
||||
*(ColorRGBA*)firstByte = (ColorRGBA)value;
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,24 +2,34 @@ using System;
|
||||
|
||||
namespace GlitchyEngine.Renderer
|
||||
{
|
||||
public class Effect
|
||||
public class Effect : RefCounted
|
||||
{
|
||||
protected GraphicsContext _context;
|
||||
internal VertexShader _vs;
|
||||
internal PixelShader _ps;
|
||||
internal VertexShader _vs ~ _?.ReleaseRef();
|
||||
internal PixelShader _ps ~ _?.ReleaseRef();
|
||||
|
||||
public GraphicsContext Context => _context;
|
||||
|
||||
public VertexShader VertexShader
|
||||
{
|
||||
get => _vs;
|
||||
set => _vs = value;
|
||||
set
|
||||
{
|
||||
_vs?.ReleaseRef();
|
||||
_vs = value;
|
||||
_vs?.AddRef();
|
||||
}
|
||||
}
|
||||
|
||||
public PixelShader PixelShader
|
||||
{
|
||||
get => _ps;
|
||||
set => _ps = value;
|
||||
set
|
||||
{
|
||||
_ps?.ReleaseRef();
|
||||
_ps = value;
|
||||
_ps?.AddRef();
|
||||
}
|
||||
}
|
||||
|
||||
public void Bind(GraphicsContext context)
|
||||
@@ -27,5 +37,18 @@ namespace GlitchyEngine.Renderer
|
||||
context.SetVertexShader(_vs);
|
||||
context.SetPixelShader(_ps);
|
||||
}
|
||||
|
||||
[Obsolete("Will be removed in the future", false)]
|
||||
public this()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public this(String vsPath, String vsEntry, String psPath, String psEntry)
|
||||
{
|
||||
Compile(vsPath, vsEntry, psPath, psEntry);
|
||||
}
|
||||
|
||||
protected extern void Compile(String vsPath, String vsEntry, String psPath, String psEntry);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using GlitchyEngine.Math;
|
||||
|
||||
namespace GlitchyEngine.Renderer
|
||||
{
|
||||
public class Material : RefCounted
|
||||
{
|
||||
private Effect _effect ~ _?.ReleaseRef();
|
||||
|
||||
public this(Effect effect)
|
||||
{
|
||||
_effect = effect;
|
||||
}
|
||||
|
||||
// public void Set(String name, VALUE)...
|
||||
|
||||
// Float, Float2, Float3, Float4
|
||||
// Color, ColorRGB, ColorRGBA
|
||||
// Matrix3x3, Matrix4x3, Matrix
|
||||
// Int, Int2, Int3, Int4
|
||||
// UInt, UInt2, UInt3, UInt4
|
||||
// Bool, Bool2, Bool3, Bool4
|
||||
// Half, Half2, Half3, Half4
|
||||
// Byte, Byte2, Byte3, Byte4
|
||||
|
||||
// Texture
|
||||
// Sampler
|
||||
}
|
||||
}
|
||||
@@ -9,15 +9,25 @@ namespace GlitchyEngine.Renderer
|
||||
public Matrix ViewProjection;
|
||||
}
|
||||
|
||||
struct ObjectConstants
|
||||
{
|
||||
public Matrix Transform;
|
||||
}
|
||||
|
||||
static GraphicsContext _context;
|
||||
|
||||
static Buffer<SceneConstants> _sceneConstants ~ delete _;
|
||||
static Buffer<SceneConstants> _sceneConstants ~ _?.ReleaseRef();
|
||||
|
||||
static Buffer<ObjectConstants> _objectConstants ~ _?.ReleaseRef();
|
||||
|
||||
public static void Init(GraphicsContext context)
|
||||
{
|
||||
_context = context;
|
||||
_sceneConstants = new Buffer<SceneConstants>(_context, .(0, .Constant, .Dynamic, .Write));
|
||||
_sceneConstants.Update();
|
||||
|
||||
_objectConstants = new Buffer<ObjectConstants>(_context, .(0, .Constant, .Dynamic, .Write));
|
||||
_objectConstants.Update();
|
||||
}
|
||||
|
||||
public static void BeginScene(Camera camera)
|
||||
@@ -28,13 +38,19 @@ namespace GlitchyEngine.Renderer
|
||||
|
||||
public static void EndScene(){}
|
||||
|
||||
public static void Submit(GeometryBinding geometry, Effect effect)
|
||||
public static void Submit(GeometryBinding geometry, Effect effect, Matrix transform = .Identity)
|
||||
{
|
||||
effect.Bind(_context);
|
||||
|
||||
effect.PixelShader?.Buffers.TryReplaceBuffer("SceneConstants", _sceneConstants);
|
||||
effect.VertexShader?.Buffers.TryReplaceBuffer("SceneConstants", _sceneConstants);
|
||||
|
||||
_objectConstants.Data.Transform = transform;
|
||||
_objectConstants.Update();
|
||||
|
||||
effect.PixelShader?.Buffers.TryReplaceBuffer("ObjectConstants", _objectConstants);
|
||||
effect.VertexShader?.Buffers.TryReplaceBuffer("ObjectConstants", _objectConstants);
|
||||
|
||||
effect.Bind(_context);
|
||||
|
||||
geometry.Bind();
|
||||
RenderCommand.DrawIndexed(geometry);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace GlitchyEngine.Renderer
|
||||
{
|
||||
@@ -19,7 +18,7 @@ namespace GlitchyEngine.Renderer
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class Shader
|
||||
public abstract class Shader : RefCounted
|
||||
{
|
||||
protected GraphicsContext _context;
|
||||
|
||||
@@ -33,13 +32,18 @@ namespace GlitchyEngine.Renderer
|
||||
public this(GraphicsContext context, String source, String entryPoint, ShaderDefine[] macros = null)
|
||||
{
|
||||
// Todo: append as soon as it's fixed.
|
||||
let buffers = new BufferCollection();
|
||||
_buffers = buffers;
|
||||
//let buffers = new BufferCollection();
|
||||
_buffers = new BufferCollection();
|
||||
|
||||
_context = context;
|
||||
CompileFromSource(source, entryPoint);
|
||||
}
|
||||
|
||||
public ~this()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public static mixin FromFile<T>(GraphicsContext context, String fileName, String entryPoint, ShaderDefine[] macros = null) where T : Shader
|
||||
{
|
||||
String fileContent = new String();
|
||||
|
||||
Reference in New Issue
Block a user