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;
}
internal void SetNativeDepthStencilTarget(ID3D11DepthStencilView* depthStencilTarget)
{
_depthStencilTarget = depthStencilTarget;
}
public override void SetRenderTarget(RenderTarget2D renderTarget, int slot, bool setDepthTarget)
{
_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()
{
for (var rt in ref _renderTargets)
@@ -206,8 +219,8 @@ namespace GlitchyEngine.Renderer
for(let entry in shader.Textures)
{
_textures[entry.Index] = entry.Texture?._nativeResourceView;
_samplers[entry.Index] = entry.Texture?.SamplerState?.nativeSamplerState;
_textures[entry.Index] = entry.BoundTexture._nativeShaderResourceView;
_samplers[entry.Index] = entry.BoundTexture._nativeSamplerState;
if(entry.Index >= _textureCount)
_textureCount = entry.Index + 1;
@@ -118,6 +118,262 @@ namespace GlitchyEngine.Renderer
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);
}
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)
{
Debug.Profiler.ProfileRendererFunction!();
@@ -68,6 +102,22 @@ namespace GlitchyEngine.Renderer
_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)
{
Debug.Profiler.ProfileRendererFunction!();
@@ -100,7 +100,7 @@ namespace GlitchyEngine.Renderer
buffer.ReleaseRef();
}
case .Texture:
_textures.Add(scope String(bindDesc.Name), bindDesc.BindPoint, null);
_textures.Add(scope String(bindDesc.Name), bindDesc.BindPoint, TextureViewBinding(null, null));
case .Sampler:
// TODO: do we have to do something for samplers?
default:
@@ -256,6 +256,11 @@ namespace GlitchyEngine.Renderer
nativeTexture, D3D11.CalcSubresource(mipSlice, arraySlice, MipLevels), (.)&sourceBox);
}
}
protected override TextureViewBinding PlatformGetViewBinding()
{
return .(_nativeResourceView, _samplerState.nativeSamplerState);
}
}
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.");
// 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 _;
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 _;
public Dictionary<String, TextureEntry> Textures => _textures;
@@ -220,7 +220,7 @@ namespace GlitchyEngine.Renderer
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];
entry.Texture?.ReleaseRef();
entry.Texture = texture;
entry.Texture?.AddRef();
entry.BoundTexture.ReleaseRef();
entry.BoundTexture = texture.GetViewBinding();
}
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()
@@ -241,13 +264,13 @@ namespace GlitchyEngine.Renderer
for(let (name, entry) in _textures)
{
entry.VsSlot?.Texture?.ReleaseRef();
entry.VsSlot?.Texture = entry.Texture;
entry.VsSlot?.Texture?.AddRef();
entry.VsSlot?.BoundTexture.ReleaseRef();
entry.VsSlot?.BoundTexture = entry.BoundTexture;
entry.VsSlot?.BoundTexture.AddRef();
entry.PsSlot?.Texture?.ReleaseRef();
entry.PsSlot?.Texture = entry.Texture;
entry.PsSlot?.Texture?.AddRef();
entry.PsSlot?.BoundTexture.ReleaseRef();
entry.PsSlot?.BoundTexture = entry.BoundTexture;
entry.PsSlot?.BoundTexture.AddRef();
}
}
@@ -650,8 +673,8 @@ namespace GlitchyEngine.Renderer
// Get existing entry or create new
if(!_textures.TryGetValue(shaderEntry.Name, out entry))
{
entry = (shaderEntry.Texture, null, null);
entry.Texture?.AddRef();
entry = (shaderEntry.BoundTexture, null, null);
entry.BoundTexture.AddRef();
}
// 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(entry.Texture == null && shaderEntry.Texture != null)
if(entry.BoundTexture.IsEmpty && !shaderEntry.BoundTexture.IsEmpty)
{
entry.Texture = shaderEntry.Texture;
entry.Texture?.AddRef();
entry.BoundTexture = shaderEntry.BoundTexture;
entry.BoundTexture.AddRef();
}
// save entry
+7 -7
View File
@@ -13,7 +13,7 @@ namespace GlitchyEngine.Renderer
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 _;
@@ -27,8 +27,8 @@ namespace GlitchyEngine.Renderer
for(let (name, entry) in _effect.Textures)
{
var texture = entry.Texture;
texture?.AddRef();
var texture = entry.BoundTexture;
texture.AddRef();
_textures.Add(name, texture);
}
@@ -40,7 +40,7 @@ namespace GlitchyEngine.Renderer
{
for(let (name, texture) in _textures)
{
texture?.ReleaseRef();
texture.ReleaseRef();
}
delete _textures;
@@ -90,9 +90,9 @@ namespace GlitchyEngine.Renderer
{
if(_textures.TryGetValue(name, var entry))
{
entry?.ReleaseRef();
_textures[name] = texture;
texture?.AddRef();
entry.ReleaseRef();
_textures[name] = texture.GetViewBinding();
//texture?.AddRef();
}
else
{
@@ -53,11 +53,21 @@ namespace GlitchyEngine.Renderer
_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)
{
_rendererAPI.SetRenderTarget(renderTarget, slot, setDepthBuffer);
}
public static void SetRenderTargetGroup(RenderTargetGroup renderTarget, bool setDepthBuffer = true)
{
_rendererAPI.SetRenderTargetGroup(renderTarget, setDepthBuffer);
}
public static void SetDepthStencilTarget(DepthStencilTarget target)
{
_rendererAPI.SetDepthStencilTarget(target);
+159
View File
@@ -1,4 +1,7 @@
using GlitchyEngine.Core;
using System;
using System.Collections;
using GlitchyEngine.Math;
namespace GlitchyEngine.Renderer
{
@@ -68,5 +71,161 @@ namespace GlitchyEngine.Renderer
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 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 _height;
public DepthStencilTarget DepthStencil;
//public DepthStencilTarget DepthStencil;
public uint32 Width => _width;
public uint32 Height => _height;
public Int2 Size => .(_width, _height);
// RGB: Albedo.rgb A: ?
/*// RGB: Albedo.rgb A: ?
public RenderTarget2D Albedo ~ _?.ReleaseRef();
// RG: TextureNormal.xy BA: GeometryNormal.xy
public RenderTarget2D Normal ~ _?.ReleaseRef();
@@ -41,7 +41,9 @@ namespace GlitchyEngine.Renderer
// RGB: Worldspace Position A: ?
public RenderTarget2D Position ~ _?.ReleaseRef();
// 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)
{
@@ -51,7 +53,7 @@ namespace GlitchyEngine.Renderer
if (_width == 0 || _height == 0)
{
// 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);
RenderTarget2DDescription normalDesc = .(.R16G16B16A16_SNorm, width, height);
@@ -64,42 +66,66 @@ namespace GlitchyEngine.Renderer
Position = new RenderTarget2D(positionDesc);
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;
_height = height;
Albedo.Resize(_width, _height);
/*Albedo.Resize(_width, _height);
Normal.Resize(_width, _height);
Tangent.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()
{
RenderCommand.SetDepthStencilTarget(DepthStencil);
/*RenderCommand.SetDepthStencilTarget(DepthStencil);
RenderCommand.UnbindRenderTargets();
RenderCommand.SetRenderTarget(Albedo, 0);
RenderCommand.SetRenderTarget(Normal, 1);
RenderCommand.SetRenderTarget(Tangent, 2);
RenderCommand.SetRenderTarget(Position, 3);
RenderCommand.SetRenderTarget(Material, 4);
RenderCommand.SetRenderTarget(Material, 4);*/
RenderCommand.SetRenderTargetGroup(Target);
RenderCommand.BindRenderTargets();
}
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.Tangent, .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;
_gBuffer.Albedo.SamplerState = SamplerStateManager.PointClamp;
TestFullscreenEffect.SetTexture("GBuffer_Albedo", _gBuffer.Albedo);
TestFullscreenEffect.SetTexture("GBuffer_Normal", _gBuffer.Normal);
TestFullscreenEffect.SetTexture("GBuffer_Tangent", _gBuffer.Tangent);
TestFullscreenEffect.SetTexture("GBuffer_Position", _gBuffer.Position);
TestFullscreenEffect.SetTexture("GBuffer_Material", _gBuffer.Material);
TestFullscreenEffect.SetTexture("GBuffer_Albedo", _gBuffer.Target, 0);
TestFullscreenEffect.SetTexture("GBuffer_Normal", _gBuffer.Target, 1);
TestFullscreenEffect.SetTexture("GBuffer_Tangent", _gBuffer.Target, 2);
TestFullscreenEffect.SetTexture("GBuffer_Position", _gBuffer.Target, 3);
TestFullscreenEffect.SetTexture("GBuffer_Material", _gBuffer.Target, 4);
TestFullscreenEffect.Variables["LightColor"].SetData(light.Light.Color);
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(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)
{
Debug.Profiler.ProfileRendererFunction!();
@@ -36,6 +38,8 @@ namespace GlitchyEngine.Renderer
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 UnbindRenderTargets();
@@ -3,9 +3,9 @@ using System.Collections;
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!(_);
@@ -31,7 +31,7 @@ namespace GlitchyEngine.Renderer
for(let entry in entries)
{
delete entry.Name;
entry.Texture?.ReleaseRef();
entry.BoundTexture.ReleaseRef();
}
delete entries;
@@ -39,15 +39,15 @@ namespace GlitchyEngine.Renderer
// 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));
}
public void Add(ResourceEntry entry)
{
ResourceEntry copy = (new String(entry.Name), entry.Index, entry.Texture);
entry.Texture?.AddRef();
ResourceEntry copy = (new String(entry.Name), entry.Index, entry.BoundTexture);
entry.BoundTexture.AddRef();
_textures.Add(copy);
+16
View File
@@ -27,6 +27,8 @@ namespace GlitchyEngine.Renderer
public abstract uint32 Depth {get;}
public abstract uint32 ArraySize {get;}
public abstract uint32 MipLevels {get;}
public abstract TextureViewBinding GetViewBinding();
}
public struct Texture2DDesc
@@ -183,6 +185,13 @@ namespace GlitchyEngine.Renderer
* Copies the data to the given destination.
*/
public extern void CopyTo(Texture2D destination);
public override TextureViewBinding GetViewBinding()
{
return PlatformGetViewBinding();
}
protected extern TextureViewBinding PlatformGetViewBinding();
}
public class TextureCube : Texture
@@ -212,5 +221,12 @@ namespace GlitchyEngine.Renderer
}
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();
}
}