Added simple SamplerStateManager

This commit is contained in:
Simon Lübeß
2021-02-08 19:36:21 +01:00
parent 9219ccf9d8
commit 7e3bb932fc
3 changed files with 94 additions and 3 deletions
+7
View File
@@ -36,6 +36,8 @@ namespace GlitchyEngine
_rendererApi = new RendererAPI(); _rendererApi = new RendererAPI();
_rendererApi.Context = _window.Context; _rendererApi.Context = _window.Context;
SamplerStateManager.Init(_window.Context);
RenderCommand.RendererAPI = _rendererApi; RenderCommand.RendererAPI = _rendererApi;
Renderer.Init(_window.Context); Renderer.Init(_window.Context);
@@ -44,6 +46,11 @@ namespace GlitchyEngine
PushOverlay(_imGuiLayer); PushOverlay(_imGuiLayer);
} }
public ~this()
{
SamplerStateManager.Uninit();
}
public void OnEvent(Event e) public void OnEvent(Event e)
{ {
EventDispatcher dispatcher = scope .(e); EventDispatcher dispatcher = scope .(e);
+86 -2
View File
@@ -1,8 +1,12 @@
using System; using System;
using GlitchyEngine.Math; using GlitchyEngine.Math;
using System.Collections;
namespace GlitchyEngine.Renderer namespace GlitchyEngine.Renderer
{ {
/**
* Defines the filter function used when sampling from a texture.
*/
public enum FilterFunction public enum FilterFunction
{ {
/// Use point filtering (nearest neighbor) for sampling. /// Use point filtering (nearest neighbor) for sampling.
@@ -88,7 +92,7 @@ namespace GlitchyEngine.Renderer
MirrorOnce MirrorOnce
} }
public struct SamplerStateDescription public struct SamplerStateDescription : IHashable
{ {
public FilterFunction MinFilter = .Linear; public FilterFunction MinFilter = .Linear;
public FilterFunction MagFilter = .Linear; public FilterFunction MagFilter = .Linear;
@@ -126,12 +130,84 @@ namespace GlitchyEngine.Renderer
* Clamping value used if FilterMode.Anisotropic is specified in the Filters. * Clamping value used if FilterMode.Anisotropic is specified in the Filters.
* Valid values are between 1 and 16. * Valid values are between 1 and 16.
*/ */
public uint32 MaxAnisotropy = 1; // TODO: we could use a smaller int public uint8 MaxAnisotropy = 1; // TODO: we could use a smaller int
/** /**
* Border color to use if TextureAddressMode.Border is specified for AddressModeU, AddressModeV, or AddressModeW. * Border color to use if TextureAddressMode.Border is specified for AddressModeU, AddressModeV, or AddressModeW.
*/ */
public ColorRGBA BorderColor = .White; public ColorRGBA BorderColor = .White;
public int GetHashCode()
{
// Put integers into one integer
int intHash = ((int)MinFilter) | ((int)MagFilter << 2) | ((int)MipFilter << 4) | ((int)FilterMode << 6) | ((int)ComparisonFunction << 8) |
((int)AddressModeU << 12) | ((int)AddressModeU << 15) | ((int)AddressModeU << 18) | ((int)(MaxAnisotropy & 0x1F) << 21); // (26 bit)
// Put BorderColor into hash.
int colorHash = ((BorderColor.R.GetHashCode() * 397 ^ BorderColor.G.GetHashCode()) * 397 ^ BorderColor.B.GetHashCode()) * 397 ^ BorderColor.A.GetHashCode();
return (((colorHash * 397 ^ MipLODBias.GetHashCode()) * 397 ^ MipMinLOD.GetHashCode()) * 397 ^ MipMaxLOD.GetHashCode()) * 397 ^ intHash;
}
}
public static class SamplerStateManager
{
static GraphicsContext _context;
static Dictionary<SamplerStateDescription, SamplerState> _samplers;
public static void Init(GraphicsContext context)
{
_context = context..AddRef();
_samplers = new .();
}
public static void Uninit()
{
_context?.ReleaseRef();
delete _samplers;
_samplers = null;
}
/**
* Returns a Sampler State that has the specified settings.
* @param desc The Struct containing the sampler state options.
* @returns A SamplerState with the given options.
* @remarks This Function increases the SamplerStates reference counter, so remember to release it.
*/
public static SamplerState GetSampler(SamplerStateDescription desc)
{
Log.EngineLogger.AssertDebug(_samplers != null, "SamplerStateManager was not initialized.");
if(_samplers.TryGetValue(desc, let sampler))
{
return sampler..AddRef();
}
SamplerState newState = new SamplerState(_context, desc);
ManageSampler(newState);
return newState;
}
public static void ManageSampler(SamplerState samplerState)
{
Log.EngineLogger.AssertDebug(_samplers != null, "SamplerStateManager was not initialized.");
_samplers.Add(samplerState.Description, samplerState);
}
/**
* Removes the given SamplerState from the manager.
* Only allows to remove samplerState with a reference count of 0.
*/
internal static void Remove(SamplerState samplerState)
{
Log.EngineLogger.AssertDebug(samplerState.RefCount == 0, "Tried to delete sampler with nonzero reference count.");
_samplers?.Remove(samplerState.Description);
}
} }
public class SamplerState : RefCounted public class SamplerState : RefCounted
@@ -149,6 +225,9 @@ namespace GlitchyEngine.Renderer
[Inline] [Inline]
public FilterMode FilterMode => _desc.FilterMode; public FilterMode FilterMode => _desc.FilterMode;
[Inline]
public SamplerStateDescription Description => _desc;
protected this(GraphicsContext context) protected this(GraphicsContext context)
{ {
_context = context..AddRef(); _context = context..AddRef();
@@ -161,6 +240,11 @@ namespace GlitchyEngine.Renderer
PlatformCreateSamplerState(); PlatformCreateSamplerState();
} }
public ~this()
{
SamplerStateManager.[Friend]Remove(this);
}
/// Creates the platform specific Sampler State /// Creates the platform specific Sampler State
protected extern void PlatformCreateSamplerState(); protected extern void PlatformCreateSamplerState();
+1 -1
View File
@@ -194,7 +194,7 @@ namespace Sandbox
_texture = new Texture2D(_context, "content/Textures/Checkerboard.dds"); _texture = new Texture2D(_context, "content/Textures/Checkerboard.dds");
let sampler = new SamplerState(_context, let sampler = SamplerStateManager.GetSampler(
SamplerStateDescription() SamplerStateDescription()
{ {
MagFilter = .Point MagFilter = .Point