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
+40 -17
View File
@@ -123,8 +123,8 @@ namespace GlitchyEngine.Renderer
BufferCollection _bufferCollection ~ 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 _;
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();
}
}