RenderTargetGroup

This commit is contained in:
Simon Lübeß
2022-05-20 18:37:59 +02:00
parent 4cd0bff91d
commit 1418063d68
15 changed files with 667 additions and 53 deletions
@@ -120,6 +120,11 @@ namespace GlitchyEngine.Renderer
_depthStencilTarget = target?.nativeView; _depthStencilTarget = target?.nativeView;
} }
internal void SetNativeDepthStencilTarget(ID3D11DepthStencilView* depthStencilTarget)
{
_depthStencilTarget = depthStencilTarget;
}
public override void SetRenderTarget(RenderTarget2D renderTarget, int slot, bool setDepthTarget) public override void SetRenderTarget(RenderTarget2D renderTarget, int slot, bool setDepthTarget)
{ {
_renderTargets[slot] = (renderTarget ?? _swapChain.BackBuffer)._nativeRenderTargetView; _renderTargets[slot] = (renderTarget ?? _swapChain.BackBuffer)._nativeRenderTargetView;
@@ -130,6 +135,14 @@ namespace GlitchyEngine.Renderer
} }
} }
internal void SetNativeRenderTargets(Span<ID3D11RenderTargetView*> renderTargets, int startSlot)
{
for (int i < renderTargets.Length)
{
_renderTargets[i + startSlot] = renderTargets[i];
}
}
public override void UnbindRenderTargets() public override void UnbindRenderTargets()
{ {
for (var rt in ref _renderTargets) for (var rt in ref _renderTargets)
@@ -206,8 +219,8 @@ namespace GlitchyEngine.Renderer
for(let entry in shader.Textures) for(let entry in shader.Textures)
{ {
_textures[entry.Index] = entry.Texture?._nativeResourceView; _textures[entry.Index] = entry.BoundTexture._nativeShaderResourceView;
_samplers[entry.Index] = entry.Texture?.SamplerState?.nativeSamplerState; _samplers[entry.Index] = entry.BoundTexture._nativeSamplerState;
if(entry.Index >= _textureCount) if(entry.Index >= _textureCount)
_textureCount = entry.Index + 1; _textureCount = entry.Index + 1;
@@ -118,6 +118,262 @@ namespace GlitchyEngine.Renderer
Log.EngineLogger.Assert(result.Succeeded, "Failed to create render target view"); Log.EngineLogger.Assert(result.Succeeded, "Failed to create render target view");
} }
} }
protected override TextureViewBinding PlatformGetViewBinding()
{
return .(_nativeResourceView, _samplerState.nativeSamplerState);
}
}
extension RenderTargetFormat
{
public DirectX.DXGI.Format GetTextureFormat()
{
switch(this)
{
case .R8G8B8A8_UNorm:
return .R8G8B8A8_UNorm;
case .R8G8B8A8_SNorm:
return .R8G8B8A8_SNorm;
case .R16G16B16A16_SNorm:
return .R16G16B16A16_SNorm;
case .R16G16B16A16_Float:
return .R16G16B16A16_Float;
case .R32G32B32A32_Float:
return .R32G32B32A32_Float;
case .D24_UNorm_S8_UInt:
return .R24G8_Typeless;
default:
return .Unknown;
}
}
public DirectX.DXGI.Format GetShaderViewFormat()
{
switch(this)
{
case .D24_UNorm_S8_UInt:
return .R24_UNorm_X8_Typeless;
default:
return GetTextureFormat();
}
}
public DirectX.DXGI.Format GetTargetViewFormat()
{
switch(this)
{
case .D24_UNorm_S8_UInt:
return .D24_UNorm_S8_UInt;
default:
return GetTextureFormat();
}
}
}
extension RenderTargetGroup
{
internal ID3D11Texture2D*[] _nativeTextures;
internal ID3D11RenderTargetView*[] _renderTargetViews;
internal ID3D11ShaderResourceView*[] _nativeResourceViews;
internal ID3D11Texture2D* _nativeDepthTexture;
internal ID3D11DepthStencilView* _nativeDepthTargetView;
internal ID3D11ShaderResourceView* _nativeDepthResourceView;
~this()
{
ReleaseEveryThing();
}
private ID3D11Texture2D* PlatformCreateTexture(TargetDescription target)
{
Debug.Profiler.ProfileResourceFunction!();
Texture2DDescription desc = .()
{
Width = _description.Width,
Height = _description.Height,
ArraySize = _description.ArraySize,
MipLevels = _description.MipLevels,
Format = target.Format.GetTextureFormat(),
// Always bindable as ShaderResource and RenderTarget
BindFlags = .ShaderResource | (target.Format.IsDepth ? .DepthStencil : .RenderTarget),
// TODO: CpuAccessFlags = (.)_description.CpuAccess,
//CpuAccessFlags = (.)_description.CpuAccess,
// 2D RenderTarget never has misc flags
MiscFlags = .None,
SampleDesc = .(_description.Samples, 0), // TODO: SampleQuality?
// RenderTarget always has Default usage
Usage = .Default
};
ID3D11Texture2D* texture = null;
var result = NativeDevice.CreateTexture2D(ref desc, null, &texture);
Log.EngineLogger.Assert(result.Succeeded, "Failed to create RenderTarget2D");
return texture;
}
private (ID3D11ShaderResourceView* ResourceView, ID3D11DeviceChild* TargetOrDepthView) CreateViews(TargetDescription target, ID3D11Texture2D* texture)
{
Debug.Profiler.ProfileResourceFunction!();
ShaderResourceViewDescription svDesc = .();
RenderTargetViewDescription rtDesc = .();
DepthStencilViewDescription dsDesc = .();
svDesc.Format = target.Format.GetShaderViewFormat();
rtDesc.Format = target.Format.GetTargetViewFormat();
dsDesc.Format = target.Format.GetTargetViewFormat();
if (_description.ArraySize > 1)
{
if (_description.Samples > 1)
{
svDesc.ViewDimension = .Texture2DMultisampledArray;
rtDesc.ViewDimension = .Texture2DArrayMultisample;
dsDesc.ViewDimension = .Texture2DMultisampledArray;
}
else
{
svDesc.ViewDimension = .Texture2DArray;
rtDesc.ViewDimension = .Texture2DArray;
dsDesc.ViewDimension = .Texture2DArray;
}
}
else
{
if (_description.Samples > 1)
{
svDesc.ViewDimension = .Texture2DMultisampled;
rtDesc.ViewDimension = .Texture2DMultisample;
dsDesc.ViewDimension = .Texture2DMultisampled;
}
else
{
svDesc.ViewDimension = .Texture2D;
rtDesc.ViewDimension = .Texture2D;
dsDesc.ViewDimension = .Texture2D;
}
}
svDesc.Description = .(svDesc.ViewDimension);
rtDesc.Description = .(rtDesc.ViewDimension);
dsDesc.Description = .(dsDesc.ViewDimension);
ID3D11ShaderResourceView* resourceView = null;
ID3D11DeviceChild* targetOrDepthView = null;
var result = NativeDevice.CreateShaderResourceView(texture, &svDesc, &resourceView);
Log.EngineLogger.Assert(result.Succeeded, "Failed to create resource view");
if (target.Format.IsDepth)
result = NativeDevice.CreateDepthStencilView(texture, &dsDesc, (.)&targetOrDepthView);
else
result = NativeDevice.CreateRenderTargetView(texture, &rtDesc, (.)&targetOrDepthView);
Log.EngineLogger.Assert(result.Succeeded, "Failed to create render target view");
// TODO: UAVs
return (resourceView, targetOrDepthView);
}
mixin DeleteContainerReleaseItemsAndNullify(var container)
{
if (container != null)
{
for (var tex in container)
{
tex.Release();
}
DeleteAndNullify!(container);
}
}
private void ReleaseEveryThing()
{
DeleteContainerReleaseItemsAndNullify!(_nativeTextures);
DeleteContainerReleaseItemsAndNullify!(_renderTargetViews);
DeleteContainerReleaseItemsAndNullify!(_nativeResourceViews);
ReleaseAndNullify!(_nativeDepthTexture);
ReleaseAndNullify!(_nativeDepthTargetView);
ReleaseAndNullify!(_nativeDepthResourceView);
}
public override void ApplyChanges()
{
Debug.Profiler.ProfileResourceFunction!();
ReleaseEveryThing();
if (_colorTargetDescriptions != null)
{
_nativeTextures = new .[_colorTargetDescriptions.Count];
_renderTargetViews = new .[_colorTargetDescriptions.Count];
_nativeResourceViews = new .[_colorTargetDescriptions.Count];
for (int i < _nativeTextures.Count)
{
TargetDescription target = _colorTargetDescriptions[i];
if (target.IsSwapchainTarget)
{
// TODO: if the engine supports multiple windows it has to support multiple swap chains.
// kinda dirty...
var context = GraphicsContext.Get();
context.SwapChain.GetBackbuffer(out _nativeTextures[i]);
}
else
{
_nativeTextures[i] = PlatformCreateTexture(target);
}
(_nativeResourceViews[i], _renderTargetViews[i]) = (.)CreateViews(target, _nativeTextures[i]);
}
}
if (_depthTargetDescription.Format != .None)
{
_nativeDepthTexture = PlatformCreateTexture(_depthTargetDescription);
(_nativeDepthResourceView, _nativeDepthTargetView) = (.)CreateViews(_depthTargetDescription, _nativeDepthTexture);
}
}
public override void Resize(uint32 width, uint32 height)
{
Debug.Profiler.ProfileResourceFunction!();
_description.Width = width;
_description.Height = height;
ApplyChanges();
}
protected override TextureViewBinding PlatformGetViewBinding(int index)
{
if (index == -1)
{
return .(_nativeDepthResourceView, _depthSamplerState.nativeSamplerState);
}
else
{
Log.EngineLogger.AssertDebug(index < _nativeResourceViews.Count);
return .(_nativeResourceViews[index], _colorSamplerStates[index].nativeSamplerState);
}
}
} }
} }
@@ -61,6 +61,40 @@ namespace GlitchyEngine.Renderer
NativeContext.ClearDepthStencilView(target.nativeView, flags, depth, stencil); NativeContext.ClearDepthStencilView(target.nativeView, flags, depth, stencil);
} }
public override void Clear(RenderTargetGroup renderTarget, ClearOptions options, ColorRGBA? color = null, float? depth = null, uint8? stencil = null)
{
if (options.HasFlag(.Color) && renderTarget._renderTargetViews != null)
{
for (int i < renderTarget._renderTargetViews.Count)
{
NativeContext.ClearRenderTargetView(renderTarget._renderTargetViews[i],
color ?? renderTarget._colorTargetDescriptions[i].ClearColor);
}
}
if (renderTarget._nativeDepthTargetView != null)
{
DirectX.D3D11.ClearFlag flags = default;
if(options.HasFlag(.Depth))
{
flags |= .Depth;
}
if(options.HasFlag(.Stencil))
{
flags |= .Stencil;
}
if (flags != default)
{
NativeContext.ClearDepthStencilView(renderTarget._nativeDepthTargetView, flags,
renderTarget._depthTargetDescription.ClearColor.R,
(uint8)renderTarget._depthTargetDescription.ClearColor.G);
}
}
}
public override void SetRenderTarget(RenderTarget2D renderTarget, int slot, bool setDepthBuffer) public override void SetRenderTarget(RenderTarget2D renderTarget, int slot, bool setDepthBuffer)
{ {
Debug.Profiler.ProfileRendererFunction!(); Debug.Profiler.ProfileRendererFunction!();
@@ -68,6 +102,22 @@ namespace GlitchyEngine.Renderer
_context.SetRenderTarget(renderTarget, slot, setDepthBuffer); _context.SetRenderTarget(renderTarget, slot, setDepthBuffer);
} }
public override void SetRenderTargetGroup(RenderTargetGroup renderTarget, bool setDepthBuffer)
{
if (renderTarget._renderTargetViews != null)
{
for (int i < renderTarget._renderTargetViews.Count)
{
_context.SetNativeRenderTargets(renderTarget._renderTargetViews, 0);
}
}
if (setDepthBuffer)
{
_context.SetNativeDepthStencilTarget(renderTarget._nativeDepthTargetView);
}
}
public override void SetDepthStencilTarget(DepthStencilTarget target) public override void SetDepthStencilTarget(DepthStencilTarget target)
{ {
Debug.Profiler.ProfileRendererFunction!(); Debug.Profiler.ProfileRendererFunction!();
@@ -100,7 +100,7 @@ namespace GlitchyEngine.Renderer
buffer.ReleaseRef(); buffer.ReleaseRef();
} }
case .Texture: case .Texture:
_textures.Add(scope String(bindDesc.Name), bindDesc.BindPoint, null); _textures.Add(scope String(bindDesc.Name), bindDesc.BindPoint, TextureViewBinding(null, null));
case .Sampler: case .Sampler:
// TODO: do we have to do something for samplers? // TODO: do we have to do something for samplers?
default: default:
@@ -256,6 +256,11 @@ namespace GlitchyEngine.Renderer
nativeTexture, D3D11.CalcSubresource(mipSlice, arraySlice, MipLevels), (.)&sourceBox); nativeTexture, D3D11.CalcSubresource(mipSlice, arraySlice, MipLevels), (.)&sourceBox);
} }
} }
protected override TextureViewBinding PlatformGetViewBinding()
{
return .(_nativeResourceView, _samplerState.nativeSamplerState);
}
} }
extension TextureCube extension TextureCube
@@ -282,6 +287,11 @@ namespace GlitchyEngine.Renderer
Log.EngineLogger.Assert(nativeDesc.MiscFlags.HasFlag(.TextureCube), scope $"The texture \"{_path}\" is not a texture cube."); Log.EngineLogger.Assert(nativeDesc.MiscFlags.HasFlag(.TextureCube), scope $"The texture \"{_path}\" is not a texture cube.");
// TODO: load fallback texture // TODO: load fallback texture
} }
protected override TextureViewBinding PlatformGetViewBinding()
{
return .(_nativeResourceView, _samplerState.nativeSamplerState);
}
} }
} }
@@ -0,0 +1,33 @@
using DirectX.D3D11;
namespace GlitchyEngine.Renderer
{
extension TextureViewBinding
{
internal ID3D11ShaderResourceView* _nativeShaderResourceView;
internal ID3D11SamplerState* _nativeSamplerState;
public override bool IsEmpty => _nativeShaderResourceView != null;
internal this(ID3D11ShaderResourceView* shaderResourceView, ID3D11SamplerState* samplerState)
{
_nativeShaderResourceView = shaderResourceView;
_nativeShaderResourceView?.AddRef();
_nativeSamplerState = samplerState;
_nativeSamplerState?.AddRef();
}
public override void AddRef()
{
_nativeShaderResourceView?.AddRef();
_nativeSamplerState?.AddRef();
}
public override void ReleaseRef()
{
_nativeShaderResourceView?.Release();
_nativeSamplerState?.Release();
}
}
}
+39 -16
View File
@@ -124,7 +124,7 @@ namespace GlitchyEngine.Renderer
BufferVariableCollection _variables ~ delete _; BufferVariableCollection _variables ~ delete _;
typealias TextureEntry = (Texture Texture, ShaderTextureCollection.ResourceEntry* VsSlot, ShaderTextureCollection.ResourceEntry* PsSlot); typealias TextureEntry = (TextureViewBinding BoundTexture, ShaderTextureCollection.ResourceEntry* VsSlot, ShaderTextureCollection.ResourceEntry* PsSlot);
Dictionary<String, TextureEntry> _textures ~ delete _; Dictionary<String, TextureEntry> _textures ~ delete _;
public Dictionary<String, TextureEntry> Textures => _textures; public Dictionary<String, TextureEntry> Textures => _textures;
@@ -220,7 +220,7 @@ namespace GlitchyEngine.Renderer
for(let entry in _textures) for(let entry in _textures)
{ {
entry.value.Texture?.ReleaseRef(); entry.value.BoundTexture.ReleaseRef();
} }
} }
@@ -230,9 +230,32 @@ namespace GlitchyEngine.Renderer
ref TextureEntry entry = ref _textures[name]; ref TextureEntry entry = ref _textures[name];
entry.Texture?.ReleaseRef(); entry.BoundTexture.ReleaseRef();
entry.Texture = texture; entry.BoundTexture = texture.GetViewBinding();
entry.Texture?.AddRef(); }
public void SetTexture(String name, RenderTargetGroup renderTargetGroup, int32 firstTarget, uint32 targetCount = 1)
{
Debug.Profiler.ProfileRendererFunction!();
if (targetCount != 1)
Runtime.NotImplemented("Binding multiple rendertargets to a slot is not yet implemented.");
ref TextureEntry entry = ref _textures[name];
entry.BoundTexture.ReleaseRef();
//entry.BoundTexture = .RenderTargetGroup(renderTargetGroup..AddRef(), firstTarget, targetCount);
entry.BoundTexture = renderTargetGroup.GetViewBinding(firstTarget);
}
public void SetTexture(String name, TextureViewBinding textureViewBinding)
{
Debug.Profiler.ProfileRendererFunction!();
ref TextureEntry entry = ref _textures[name];
entry.BoundTexture.ReleaseRef();
entry.BoundTexture = textureViewBinding..AddRef();
} }
private void ApplyTextures() private void ApplyTextures()
@@ -241,13 +264,13 @@ namespace GlitchyEngine.Renderer
for(let (name, entry) in _textures) for(let (name, entry) in _textures)
{ {
entry.VsSlot?.Texture?.ReleaseRef(); entry.VsSlot?.BoundTexture.ReleaseRef();
entry.VsSlot?.Texture = entry.Texture; entry.VsSlot?.BoundTexture = entry.BoundTexture;
entry.VsSlot?.Texture?.AddRef(); entry.VsSlot?.BoundTexture.AddRef();
entry.PsSlot?.Texture?.ReleaseRef(); entry.PsSlot?.BoundTexture.ReleaseRef();
entry.PsSlot?.Texture = entry.Texture; entry.PsSlot?.BoundTexture = entry.BoundTexture;
entry.PsSlot?.Texture?.AddRef(); entry.PsSlot?.BoundTexture.AddRef();
} }
} }
@@ -650,8 +673,8 @@ namespace GlitchyEngine.Renderer
// Get existing entry or create new // Get existing entry or create new
if(!_textures.TryGetValue(shaderEntry.Name, out entry)) if(!_textures.TryGetValue(shaderEntry.Name, out entry))
{ {
entry = (shaderEntry.Texture, null, null); entry = (shaderEntry.BoundTexture, null, null);
entry.Texture?.AddRef(); entry.BoundTexture.AddRef();
} }
// Set the corresponding shader resource slot // Set the corresponding shader resource slot
@@ -665,10 +688,10 @@ namespace GlitchyEngine.Renderer
} }
// If the entry has no texture but the shader has one -> set texture // If the entry has no texture but the shader has one -> set texture
if(entry.Texture == null && shaderEntry.Texture != null) if(entry.BoundTexture.IsEmpty && !shaderEntry.BoundTexture.IsEmpty)
{ {
entry.Texture = shaderEntry.Texture; entry.BoundTexture = shaderEntry.BoundTexture;
entry.Texture?.AddRef(); entry.BoundTexture.AddRef();
} }
// save entry // save entry
+7 -7
View File
@@ -13,7 +13,7 @@ namespace GlitchyEngine.Renderer
private uint8[] _rawVariables ~ delete _; private uint8[] _rawVariables ~ delete _;
private Dictionary<String, Texture> _textures = new .(); private Dictionary<String, TextureViewBinding> _textures = new .();
private Dictionary<String, (uint32 Offset, BufferVariable Variable)> _variables = new .() ~ delete _; private Dictionary<String, (uint32 Offset, BufferVariable Variable)> _variables = new .() ~ delete _;
@@ -27,8 +27,8 @@ namespace GlitchyEngine.Renderer
for(let (name, entry) in _effect.Textures) for(let (name, entry) in _effect.Textures)
{ {
var texture = entry.Texture; var texture = entry.BoundTexture;
texture?.AddRef(); texture.AddRef();
_textures.Add(name, texture); _textures.Add(name, texture);
} }
@@ -40,7 +40,7 @@ namespace GlitchyEngine.Renderer
{ {
for(let (name, texture) in _textures) for(let (name, texture) in _textures)
{ {
texture?.ReleaseRef(); texture.ReleaseRef();
} }
delete _textures; delete _textures;
@@ -90,9 +90,9 @@ namespace GlitchyEngine.Renderer
{ {
if(_textures.TryGetValue(name, var entry)) if(_textures.TryGetValue(name, var entry))
{ {
entry?.ReleaseRef(); entry.ReleaseRef();
_textures[name] = texture; _textures[name] = texture.GetViewBinding();
texture?.AddRef(); //texture?.AddRef();
} }
else else
{ {
@@ -53,11 +53,21 @@ namespace GlitchyEngine.Renderer
_rendererAPI.Clear(renderTarget, options, color, depth, stencil); _rendererAPI.Clear(renderTarget, options, color, depth, stencil);
} }
public static void Clear(RenderTargetGroup renderTarget, ClearOptions options, ColorRGBA? color = null, float? depth = null, uint8? stencil = null)
{
_rendererAPI.Clear(renderTarget, options, color, depth, stencil);
}
public static void SetRenderTarget(RenderTarget2D renderTarget, int slot = 0, bool setDepthBuffer = false) public static void SetRenderTarget(RenderTarget2D renderTarget, int slot = 0, bool setDepthBuffer = false)
{ {
_rendererAPI.SetRenderTarget(renderTarget, slot, setDepthBuffer); _rendererAPI.SetRenderTarget(renderTarget, slot, setDepthBuffer);
} }
public static void SetRenderTargetGroup(RenderTargetGroup renderTarget, bool setDepthBuffer = true)
{
_rendererAPI.SetRenderTargetGroup(renderTarget, setDepthBuffer);
}
public static void SetDepthStencilTarget(DepthStencilTarget target) public static void SetDepthStencilTarget(DepthStencilTarget target)
{ {
_rendererAPI.SetDepthStencilTarget(target); _rendererAPI.SetDepthStencilTarget(target);
+159
View File
@@ -1,4 +1,7 @@
using GlitchyEngine.Core; using GlitchyEngine.Core;
using System;
using System.Collections;
using GlitchyEngine.Math;
namespace GlitchyEngine.Renderer namespace GlitchyEngine.Renderer
{ {
@@ -68,5 +71,161 @@ namespace GlitchyEngine.Renderer
public extern void Resize(uint32 width, uint32 height); public extern void Resize(uint32 width, uint32 height);
protected extern void PlatformApplyChanges(); 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 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 struct TargetDescription
{
public RenderTargetFormat Format = .None;
public bool IsSwapchainTarget = false;
public bool IsShaderReadable = true;
/// Clear color. For DepthStencilBuffers: R is Depth, G is Stencil
public ColorRGBA ClearColor = .Black;
public SamplerStateDescription SamplerDescription = .();
public this() { }
public this(RenderTargetFormat format, bool isSwapchainTarget = false, bool isShaderReadable = true, ColorRGBA clearColor = .Black, 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;
[AllowAppend]
public this(RenderTargetGroupDescription description)
{
_description = description;
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);
}
}
_depthTargetDescription = description.DepthTargetDescription;
Log.EngineLogger.AssertDebug(_depthTargetDescription.Format.IsDepth, "Depth target must have depth format.");
if (_depthTargetDescription.Format != .None)
{
_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);
} }
} }
+43 -19
View File
@@ -25,14 +25,14 @@ namespace GlitchyEngine.Renderer
private uint32 _width; private uint32 _width;
private uint32 _height; private uint32 _height;
public DepthStencilTarget DepthStencil; //public DepthStencilTarget DepthStencil;
public uint32 Width => _width; public uint32 Width => _width;
public uint32 Height => _height; public uint32 Height => _height;
public Int2 Size => .(_width, _height); public Int2 Size => .(_width, _height);
// RGB: Albedo.rgb A: ? /*// RGB: Albedo.rgb A: ?
public RenderTarget2D Albedo ~ _?.ReleaseRef(); public RenderTarget2D Albedo ~ _?.ReleaseRef();
// RG: TextureNormal.xy BA: GeometryNormal.xy // RG: TextureNormal.xy BA: GeometryNormal.xy
public RenderTarget2D Normal ~ _?.ReleaseRef(); public RenderTarget2D Normal ~ _?.ReleaseRef();
@@ -41,7 +41,9 @@ namespace GlitchyEngine.Renderer
// RGB: Worldspace Position A: ? // RGB: Worldspace Position A: ?
public RenderTarget2D Position ~ _?.ReleaseRef(); public RenderTarget2D Position ~ _?.ReleaseRef();
// R: Metallicity G: Roughness B: Ambient A: ? // R: Metallicity G: Roughness B: Ambient A: ?
public RenderTarget2D Material ~ _?.ReleaseRef(); public RenderTarget2D Material ~ _?.ReleaseRef();*/
public RenderTargetGroup Target ~ _?.ReleaseRef();
public void EnsureSize(uint32 width, uint32 height) public void EnsureSize(uint32 width, uint32 height)
{ {
@@ -51,7 +53,7 @@ namespace GlitchyEngine.Renderer
if (_width == 0 || _height == 0) if (_width == 0 || _height == 0)
{ {
// Note: Depth-Buffer in Color-Target for convenience // Note: Depth-Buffer in Color-Target for convenience
RenderTarget2DDescription albedoDesc = .(.R8G8B8A8_UNorm, width, height, 1, 1, .D24_UNorm_S8_UInt); /*RenderTarget2DDescription albedoDesc = .(.R8G8B8A8_UNorm, width, height, 1, 1, .D24_UNorm_S8_UInt);
Albedo = new RenderTarget2D(albedoDesc); Albedo = new RenderTarget2D(albedoDesc);
RenderTarget2DDescription normalDesc = .(.R16G16B16A16_SNorm, width, height); RenderTarget2DDescription normalDesc = .(.R16G16B16A16_SNorm, width, height);
@@ -64,42 +66,66 @@ namespace GlitchyEngine.Renderer
Position = new RenderTarget2D(positionDesc); Position = new RenderTarget2D(positionDesc);
RenderTarget2DDescription materialDesc = .(.R8G8B8A8_UNorm, width, height); RenderTarget2DDescription materialDesc = .(.R8G8B8A8_UNorm, width, height);
Material = new RenderTarget2D(materialDesc); Material = new RenderTarget2D(materialDesc);*/
SamplerStateDescription desc = .();
desc.MinFilter = .Point;
desc.MagFilter = .Point;
RenderTargetGroupDescription targetDesc = .(width, height,
TargetDescription[](
.(RenderTargetFormat.R8G8B8A8_UNorm){SamplerDescription = desc},
.(RenderTargetFormat.R16G16B16A16_SNorm){SamplerDescription = desc},
.(RenderTargetFormat.R16G16B16A16_SNorm){SamplerDescription = desc},
.(RenderTargetFormat.R32G32B32A32_Float){SamplerDescription = desc},
.(RenderTargetFormat.R8G8B8A8_UNorm){SamplerDescription = desc}
),
TargetDescription(.D24_UNorm_S8_UInt){
SamplerDescription = desc,
ClearColor = .(1.0f, 0, 0)
});
Target = new RenderTargetGroup(targetDesc);
} }
_width = width; _width = width;
_height = height; _height = height;
Albedo.Resize(_width, _height); /*Albedo.Resize(_width, _height);
Normal.Resize(_width, _height); Normal.Resize(_width, _height);
Tangent.Resize(_width, _height); Tangent.Resize(_width, _height);
Position.Resize(_width, _height); Position.Resize(_width, _height);
Material.Resize(_width, _height); Material.Resize(_width, _height);*/
DepthStencil = Albedo.DepthStencilTarget; //DepthStencil = Albedo.DepthStencilTarget;
Target.Resize(_width, _height);
} }
public void Bind() public void Bind()
{ {
RenderCommand.SetDepthStencilTarget(DepthStencil); /*RenderCommand.SetDepthStencilTarget(DepthStencil);
RenderCommand.UnbindRenderTargets(); RenderCommand.UnbindRenderTargets();
RenderCommand.SetRenderTarget(Albedo, 0); RenderCommand.SetRenderTarget(Albedo, 0);
RenderCommand.SetRenderTarget(Normal, 1); RenderCommand.SetRenderTarget(Normal, 1);
RenderCommand.SetRenderTarget(Tangent, 2); RenderCommand.SetRenderTarget(Tangent, 2);
RenderCommand.SetRenderTarget(Position, 3); RenderCommand.SetRenderTarget(Position, 3);
RenderCommand.SetRenderTarget(Material, 4); RenderCommand.SetRenderTarget(Material, 4);*/
RenderCommand.SetRenderTargetGroup(Target);
RenderCommand.BindRenderTargets(); RenderCommand.BindRenderTargets();
} }
public void Clear() public void Clear()
{ {
RenderCommand.Clear(_gBuffer.Albedo, .Color | .Depth, .HotPink, 1, 0); /*RenderCommand.Clear(_gBuffer.Albedo, .Color | .Depth, .HotPink, 1, 0);
RenderCommand.Clear(_gBuffer.Normal, .HotPink); RenderCommand.Clear(_gBuffer.Normal, .HotPink);
RenderCommand.Clear(_gBuffer.Tangent, .HotPink); RenderCommand.Clear(_gBuffer.Tangent, .HotPink);
RenderCommand.Clear(_gBuffer.Position, .HotPink); RenderCommand.Clear(_gBuffer.Position, .HotPink);
RenderCommand.Clear(_gBuffer.Material, .HotPink); RenderCommand.Clear(_gBuffer.Material, .HotPink);*/
RenderCommand.Clear(Target, .Color | .Depth);
} }
} }
@@ -396,13 +422,11 @@ namespace GlitchyEngine.Renderer
Vector3 lightDir = -light.Transform.Forward; Vector3 lightDir = -light.Transform.Forward;
_gBuffer.Albedo.SamplerState = SamplerStateManager.PointClamp; TestFullscreenEffect.SetTexture("GBuffer_Albedo", _gBuffer.Target, 0);
TestFullscreenEffect.SetTexture("GBuffer_Normal", _gBuffer.Target, 1);
TestFullscreenEffect.SetTexture("GBuffer_Albedo", _gBuffer.Albedo); TestFullscreenEffect.SetTexture("GBuffer_Tangent", _gBuffer.Target, 2);
TestFullscreenEffect.SetTexture("GBuffer_Normal", _gBuffer.Normal); TestFullscreenEffect.SetTexture("GBuffer_Position", _gBuffer.Target, 3);
TestFullscreenEffect.SetTexture("GBuffer_Tangent", _gBuffer.Tangent); TestFullscreenEffect.SetTexture("GBuffer_Material", _gBuffer.Target, 4);
TestFullscreenEffect.SetTexture("GBuffer_Position", _gBuffer.Position);
TestFullscreenEffect.SetTexture("GBuffer_Material", _gBuffer.Material);
TestFullscreenEffect.Variables["LightColor"].SetData(light.Light.Color); TestFullscreenEffect.Variables["LightColor"].SetData(light.Light.Color);
TestFullscreenEffect.Variables["Illuminance"].SetData(light.Light.Illuminance); TestFullscreenEffect.Variables["Illuminance"].SetData(light.Light.Illuminance);
@@ -21,6 +21,8 @@ namespace GlitchyEngine.Renderer
public extern void Clear(DepthStencilTarget target, ClearOptions options, float depth, uint8 stencil); public extern void Clear(DepthStencilTarget target, ClearOptions options, float depth, uint8 stencil);
public extern void Clear(RenderTargetGroup renderTarget, ClearOptions options, ColorRGBA? color = null, float? depth = null, uint8? stencil = null);
public void Clear(RenderTarget2D renderTarget, ClearOptions options, ColorRGBA color, float depth, uint8 stencil) public void Clear(RenderTarget2D renderTarget, ClearOptions options, ColorRGBA color, float depth, uint8 stencil)
{ {
Debug.Profiler.ProfileRendererFunction!(); Debug.Profiler.ProfileRendererFunction!();
@@ -36,6 +38,8 @@ namespace GlitchyEngine.Renderer
public extern void SetRenderTarget(RenderTarget2D renderTarget, int slot, bool setDepthBuffer); public extern void SetRenderTarget(RenderTarget2D renderTarget, int slot, bool setDepthBuffer);
public extern void SetRenderTargetGroup(RenderTargetGroup renderTarget, bool setDepthBuffer);
public extern void SetDepthStencilTarget(DepthStencilTarget target); public extern void SetDepthStencilTarget(DepthStencilTarget target);
public extern void UnbindRenderTargets(); public extern void UnbindRenderTargets();
@@ -3,9 +3,9 @@ using System.Collections;
namespace GlitchyEngine.Renderer namespace GlitchyEngine.Renderer
{ {
public class ShaderTextureCollection : IEnumerable<(String Name, uint32 Index, Texture Texture)> public class ShaderTextureCollection : IEnumerable<(String Name, uint32 Index, TextureViewBinding BoundTexture)>
{ {
public typealias ResourceEntry = (String Name, uint32 Index, Texture Texture); public typealias ResourceEntry = (String Name, uint32 Index, TextureViewBinding BoundTexture);
List<ResourceEntry> _textures ~ DeleteTextureEntries!(_); List<ResourceEntry> _textures ~ DeleteTextureEntries!(_);
@@ -31,7 +31,7 @@ namespace GlitchyEngine.Renderer
for(let entry in entries) for(let entry in entries)
{ {
delete entry.Name; delete entry.Name;
entry.Texture?.ReleaseRef(); entry.BoundTexture.ReleaseRef();
} }
delete entries; delete entries;
@@ -39,15 +39,15 @@ namespace GlitchyEngine.Renderer
// TODO: finish implementation (like BufferCollection) // TODO: finish implementation (like BufferCollection)
public void Add(String name, uint32 index, Texture texture) public void Add(String name, uint32 index, TextureViewBinding texture)
{ {
Add((name, index, texture)); Add((name, index, texture));
} }
public void Add(ResourceEntry entry) public void Add(ResourceEntry entry)
{ {
ResourceEntry copy = (new String(entry.Name), entry.Index, entry.Texture); ResourceEntry copy = (new String(entry.Name), entry.Index, entry.BoundTexture);
entry.Texture?.AddRef(); entry.BoundTexture.AddRef();
_textures.Add(copy); _textures.Add(copy);
+16
View File
@@ -27,6 +27,8 @@ namespace GlitchyEngine.Renderer
public abstract uint32 Depth {get;} public abstract uint32 Depth {get;}
public abstract uint32 ArraySize {get;} public abstract uint32 ArraySize {get;}
public abstract uint32 MipLevels {get;} public abstract uint32 MipLevels {get;}
public abstract TextureViewBinding GetViewBinding();
} }
public struct Texture2DDesc public struct Texture2DDesc
@@ -183,6 +185,13 @@ namespace GlitchyEngine.Renderer
* Copies the data to the given destination. * Copies the data to the given destination.
*/ */
public extern void CopyTo(Texture2D destination); public extern void CopyTo(Texture2D destination);
public override TextureViewBinding GetViewBinding()
{
return PlatformGetViewBinding();
}
protected extern TextureViewBinding PlatformGetViewBinding();
} }
public class TextureCube : Texture public class TextureCube : Texture
@@ -212,5 +221,12 @@ namespace GlitchyEngine.Renderer
} }
protected extern void LoadTexturePlatform(Stream stream); protected extern void LoadTexturePlatform(Stream stream);
public override TextureViewBinding GetViewBinding()
{
return PlatformGetViewBinding();
}
protected extern TextureViewBinding PlatformGetViewBinding();
} }
} }
@@ -0,0 +1,16 @@
using System;
namespace GlitchyEngine.Renderer
{
/// Represents a reference to a texture that can be used as shader input resource.
public struct TextureViewBinding : IRefCounted, IDisposable
{
/// True if the view binding actually has a texture. False otherwise.
public extern bool IsEmpty { get; }
public extern void AddRef();
public extern void ReleaseRef();
public void Dispose() => ReleaseRef();
}
}