mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 21:01:52 +00:00
282 lines
8.4 KiB
Beef
282 lines
8.4 KiB
Beef
using GlitchyEngine.Core;
|
|
using System;
|
|
using System.Collections;
|
|
using GlitchyEngine.Math;
|
|
|
|
namespace GlitchyEngine.Renderer
|
|
{
|
|
public struct RenderTarget2DDescription
|
|
{
|
|
public uint32 Width;
|
|
public uint32 Height;
|
|
public uint32 ArraySize;
|
|
public uint32 MipLevels;
|
|
public Format PixelFormat;
|
|
public CPUAccessFlags CpuAccess;
|
|
public uint32 SampleCount;
|
|
public uint32 SampleQuality;
|
|
public DepthStencilFormat DepthStencilFormat;
|
|
public bool IsSwapchainTarget;
|
|
|
|
public this(Format pixelFormat, uint32 width, uint32 height, uint32 arraySize = 1, uint32 mipLevels = 1,
|
|
DepthStencilFormat depthStencilFormat = .None, CPUAccessFlags cpuAccess = .None, uint32 sampleCount = 1, uint32 sampleQuality = 0, bool isSwapchainTarget = false)
|
|
{
|
|
PixelFormat = pixelFormat;
|
|
Width = width;
|
|
Height = height;
|
|
ArraySize = arraySize;
|
|
MipLevels = mipLevels;
|
|
CpuAccess = cpuAccess;
|
|
DepthStencilFormat = depthStencilFormat;
|
|
|
|
SampleCount = sampleCount;
|
|
SampleQuality = sampleQuality;
|
|
|
|
IsSwapchainTarget = isSwapchainTarget;
|
|
}
|
|
}
|
|
|
|
public class RenderTarget2D : Texture
|
|
{
|
|
private RenderTarget2DDescription _description;
|
|
|
|
public RenderTarget2DDescription Description => _description;
|
|
|
|
public override uint32 Width => _description.Width;
|
|
public override uint32 Height => _description.Height;
|
|
public override uint32 Depth => 1;
|
|
public override uint32 ArraySize => _description.ArraySize;
|
|
public override uint32 MipLevels => _description.MipLevels;
|
|
|
|
protected internal DepthStencilTarget _depthStenilTarget ~ _?.ReleaseRef();
|
|
|
|
// TODO: DepthStencilTarget is just a renderTarget
|
|
public DepthStencilTarget DepthStencilTarget => _depthStenilTarget;
|
|
|
|
public this(RenderTarget2DDescription description)
|
|
{
|
|
Debug.Profiler.ProfileResourceFunction!();
|
|
|
|
_description = description;
|
|
|
|
ApplyChanges();
|
|
}
|
|
|
|
/// Recreates the render target using the current description
|
|
public void ApplyChanges()
|
|
{
|
|
PlatformApplyChanges();
|
|
}
|
|
|
|
public extern void Resize(uint32 width, uint32 height);
|
|
|
|
protected extern void PlatformApplyChanges();
|
|
|
|
public override TextureViewBinding GetViewBinding()
|
|
{
|
|
return PlatformGetViewBinding();
|
|
}
|
|
|
|
protected extern TextureViewBinding PlatformGetViewBinding();
|
|
}
|
|
|
|
[AllowDuplicates]
|
|
public enum RenderTargetFormat : uint8
|
|
{
|
|
/// Sets the most significant bit to 1.
|
|
const uint8 DepthMarker = 1 << 7;
|
|
|
|
case None = 0;
|
|
|
|
case R8_SInt;
|
|
case R32_UInt;
|
|
|
|
case R8G8B8A8_UNorm;
|
|
case R8G8B8A8_SNorm;
|
|
|
|
case R16G16B16A16_SNorm;
|
|
case R16G16B16A16_Float;
|
|
|
|
case R32G32B32A32_Float;
|
|
|
|
case D24_UNorm_S8_UInt = DepthMarker | 1;
|
|
|
|
/// Default depth format
|
|
case Depth = D24_UNorm_S8_UInt;
|
|
|
|
public bool IsDepth => HasFlag(DepthMarker);
|
|
}
|
|
|
|
public enum ClearColor
|
|
{
|
|
/// Clears the render target to the default value (Zero).
|
|
case Default;
|
|
/// The render target will be cleared with a RGBA color.
|
|
case Color(ColorRGBA ClearColor);
|
|
/// The render target will be cleared with a UInt value.
|
|
/// @remarks Some platforms don't support clearing a UInt render target.
|
|
/// In these cases a draw call will be performed that draws a solid color into the target.
|
|
/// This can result in modified context state so it is recommended to rebind effects, etc. after clearing a uint rendertarget.
|
|
case UInt(uint32 ClearValue);
|
|
/// Only valid for depth buffers.
|
|
case DepthStencil(float Depth, uint8 Stencil);
|
|
|
|
public static implicit operator ClearColor(ColorRGBA color)
|
|
{
|
|
return .Color(color);
|
|
}
|
|
}
|
|
|
|
public struct TargetDescription
|
|
{
|
|
public RenderTargetFormat Format = .None;
|
|
|
|
public bool IsSwapchainTarget = false;
|
|
|
|
public bool IsShaderReadable = true;
|
|
|
|
public ClearColor ClearColor = .Default;
|
|
|
|
public SamplerStateDescription SamplerDescription = .();
|
|
|
|
public this() { }
|
|
|
|
public this(RenderTargetFormat format, bool isSwapchainTarget = false, bool isShaderReadable = true, ClearColor clearColor = .Default, SamplerStateDescription samplerDescription = .())
|
|
{
|
|
Format = format;
|
|
IsSwapchainTarget = isSwapchainTarget;
|
|
IsShaderReadable = isShaderReadable;
|
|
SamplerDescription = samplerDescription;
|
|
ClearColor = clearColor;
|
|
}
|
|
|
|
public static implicit operator Self(RenderTargetFormat format)
|
|
{
|
|
return Self(format);
|
|
}
|
|
}
|
|
|
|
public struct RenderTargetGroupDescription
|
|
{
|
|
public uint32 Width = 0, Height = 0, ArraySize = 1, MipLevels = 1;
|
|
|
|
public uint32 Samples = 1; // TODO: SampleQuality?
|
|
|
|
public Span<TargetDescription> ColorTargetDescriptions = null;
|
|
|
|
public TargetDescription DepthTargetDescription = .(.None);
|
|
|
|
// TODO: CpuAccess
|
|
|
|
public this() { }
|
|
|
|
public this(uint32 width, uint32 height, Span<TargetDescription> colorTargetDescriptions = null, TargetDescription depthTargetDescription = .())
|
|
{
|
|
Width = width;
|
|
Height = height;
|
|
ColorTargetDescriptions = colorTargetDescriptions;
|
|
DepthTargetDescription = depthTargetDescription;
|
|
}
|
|
}
|
|
|
|
public class RenderTargetGroup : RefCounter
|
|
{
|
|
internal RenderTargetGroupDescription _description;
|
|
|
|
internal TargetDescription[] _colorTargetDescriptions ~ delete _;
|
|
internal SamplerState[] _colorSamplerStates ~ DeleteContainerAndReleaseItems!(_);
|
|
internal SamplerState _depthSamplerState ~ _?.ReleaseRef();
|
|
|
|
internal TargetDescription _depthTargetDescription;
|
|
|
|
public uint32 Width => _description.Width;
|
|
public uint32 Height => _description.Height;
|
|
public uint32 ArraySize => _description.ArraySize;
|
|
public uint32 MipLevels => _description.MipLevels;
|
|
|
|
public uint32 Samples => _description.Samples;
|
|
|
|
public int TargetCount => _colorTargetDescriptions.Count + (_depthTargetDescription.Format.IsDepth ? 1 : 0);
|
|
public int ColorTargetCount => _colorTargetDescriptions.Count;
|
|
|
|
[AllowAppend]
|
|
public this(RenderTargetGroupDescription description)
|
|
{
|
|
_description = description;
|
|
|
|
Log.EngineLogger.AssertDebug(_description.Width != 0);
|
|
Log.EngineLogger.AssertDebug(_description.Height != 0);
|
|
|
|
var colorTargets = description.ColorTargetDescriptions;
|
|
|
|
if (!colorTargets.IsNull && !colorTargets.IsEmpty)
|
|
{
|
|
_colorTargetDescriptions = new TargetDescription[colorTargets.Length];
|
|
_colorSamplerStates = new SamplerState[colorTargets.Length];
|
|
|
|
bool swapchainTargetBound = false;
|
|
|
|
for (int i < colorTargets.Length)
|
|
{
|
|
Log.EngineLogger.AssertDebug(!colorTargets[i].Format.IsDepth, "Cannot use depth format as color target.");
|
|
|
|
_colorTargetDescriptions[i] = colorTargets[i];
|
|
|
|
if (colorTargets[i].IsSwapchainTarget)
|
|
{
|
|
Log.EngineLogger.AssertDebug(!swapchainTargetBound, "Cannot bind swapchaintarget multiple times.");
|
|
|
|
swapchainTargetBound = true;
|
|
}
|
|
|
|
_colorSamplerStates[i] = SamplerStateManager.GetSampler(_colorTargetDescriptions[i].SamplerDescription);
|
|
|
|
if (_colorTargetDescriptions[i].ClearColor case .Default)
|
|
_colorTargetDescriptions[i].ClearColor = .Color(.Black);
|
|
}
|
|
}
|
|
|
|
_depthTargetDescription = description.DepthTargetDescription;
|
|
|
|
if (_depthTargetDescription.Format != .None)
|
|
{
|
|
Log.EngineLogger.AssertDebug(_depthTargetDescription.Format.IsDepth, "Depth target must have depth format.");
|
|
|
|
if (_depthTargetDescription.ClearColor case .Default)
|
|
_depthTargetDescription.ClearColor = .DepthStencil(0.0f, 0);
|
|
|
|
Log.EngineLogger.AssertDebug(_depthTargetDescription.ClearColor case .DepthStencil, "Clear color for depth stencil target must be of type DepthStencil.");
|
|
|
|
_depthSamplerState = SamplerStateManager.GetSampler(_depthTargetDescription.SamplerDescription);
|
|
}
|
|
|
|
ApplyChanges();
|
|
}
|
|
|
|
public extern void ApplyChanges();
|
|
|
|
public extern void Resize(uint32 width, uint32 height);
|
|
|
|
/// -1 for Depthbuffer
|
|
public TextureViewBinding GetViewBinding(int index)
|
|
{
|
|
return PlatformGetViewBinding(index);
|
|
}
|
|
|
|
protected extern TextureViewBinding PlatformGetViewBinding(int index);
|
|
|
|
protected extern Result<void> PlatformGetData(void* destination, uint32 elementSize,
|
|
uint32 x, uint32 y, uint32 width, uint32 height, int renderTarget, uint32 arraySlice, uint32 mipLevel); // mapType?
|
|
|
|
public Result<void> GetData<T>(T* data, int renderTarget, uint32 left, uint32 top, uint32 width, uint32 height, uint32 arraySlice = 0, uint32 mipSlice = 0)
|
|
{
|
|
Log.EngineLogger.AssertDebug(left + width < Width);
|
|
Log.EngineLogger.AssertDebug(top + height < Height);
|
|
|
|
return PlatformGetData(data, (.)sizeof(T), left, top, width, height, renderTarget, arraySlice, mipSlice);
|
|
}
|
|
|
|
public extern void CopyTo(RenderTargetGroup destination, int dstTarget, Int2 dstTopLeft, Int2 size, Int2 srcTopLeft, int srcTarget);
|
|
}
|
|
}
|