Render extraction system & ECS/graphics refactor
Introduced RenderExtractionSystem for entity-based render data extraction. Added MeshInstance and MeshPalette components with shadow casting support. Refactored QueryBuilder API, SharedComponentStore, and component registration for clarity and flexibility. Updated SystemManager and SystemGroup to use SystemAPI. Replaced RenderingConfig with GraphicsEngineDesc/RenderSystemDesc. RenderFrame now uses CPU/GPU fence values for sync. Removed Camera.cs in favor of ECS-based rendering. Improved Material, RenderingLayerMask, Mesh, and RenderList APIs. Updated package references and fixed naming, error handling, and disposal issues.
This commit is contained in:
@@ -1,85 +0,0 @@
|
||||
using Ghost.Core;
|
||||
using Ghost.Graphics.RenderGraphModule;
|
||||
using Ghost.Graphics.RHI;
|
||||
|
||||
namespace Ghost.Graphics.Core;
|
||||
|
||||
public class Camera
|
||||
{
|
||||
private readonly IRenderer _renderer;
|
||||
|
||||
// History buffers.
|
||||
private Handle<Texture> _colorTexture;
|
||||
private Handle<Texture> _depthTexture;
|
||||
|
||||
private uint _actualWidth;
|
||||
private uint _actualHeight;
|
||||
|
||||
private uint _virtualWidth;
|
||||
private uint _virtualHeight;
|
||||
|
||||
public IRenderer Renderer => _renderer;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the actual width of the camera's render target in pixels. If upscaler is used, this is the width before upscaling.
|
||||
/// </summary>
|
||||
public uint ActualWidth => _actualWidth;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the actual height of the camera's render target in pixels. If upscaler is used, this is the height before upscaling.
|
||||
/// </summary>
|
||||
public uint ActualHeight => _actualHeight;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the virtual width of the camera's render target in pixels. If upscaler is used, this is the width after upscaling.
|
||||
/// </summary>
|
||||
public uint VirtualWidth => _virtualWidth;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the virtual height of the camera's render target in pixels. If upscaler is used, this is the height after upscaling.
|
||||
/// </summary>
|
||||
public uint VirtualHeight => _virtualHeight;
|
||||
|
||||
public RenderGraph? RenderGraph
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public Camera(IGraphicsEngine graphicsEngine)
|
||||
{
|
||||
_renderer = graphicsEngine.CreateRenderer();
|
||||
}
|
||||
|
||||
public Camera(IGraphicsEngine graphicsEngine, RenderGraph renderGraph)
|
||||
{
|
||||
_renderer = graphicsEngine.CreateRenderer();
|
||||
RenderGraph = renderGraph;
|
||||
|
||||
_renderer.RenderFunc = DefaultRenderFunc;
|
||||
}
|
||||
|
||||
private Error DefaultRenderFunc(RenderContext context)
|
||||
{
|
||||
if (RenderGraph == null)
|
||||
{
|
||||
return Error.None;
|
||||
}
|
||||
|
||||
RenderGraph.Reset();
|
||||
|
||||
var view = new ViewState(_virtualWidth, _virtualHeight, _actualWidth, _actualHeight);
|
||||
var e = RenderGraph.Compile(in view);
|
||||
if (e != Error.None)
|
||||
{
|
||||
return e;
|
||||
}
|
||||
|
||||
e = RenderGraph.Execute(context.CommandBuffer);
|
||||
if (e != Error.None)
|
||||
{
|
||||
return e;
|
||||
}
|
||||
|
||||
return Error.None;
|
||||
}
|
||||
}
|
||||
@@ -65,17 +65,17 @@ public struct Material : IResourceReleasable
|
||||
get; set;
|
||||
}
|
||||
|
||||
public Error SetShader(Identifier<Shader> shaderId, IResourceManager manager)
|
||||
public Error SetShader(Identifier<Shader> shaderId, IResourceManager resourceManager, IResourceDatabase resourceDatabase, IResourceAllocator resourceAllocator)
|
||||
{
|
||||
if (!shaderId.IsValid)
|
||||
{
|
||||
return Error.InvalidArgument;
|
||||
}
|
||||
|
||||
_cBufferCache.ReleaseResource(manager.ResourceDatabase);
|
||||
_cBufferCache.ReleaseResource(resourceDatabase);
|
||||
_shader = shaderId;
|
||||
|
||||
var r = manager.GetShaderReference(shaderId);
|
||||
var r = resourceManager.GetShaderReference(shaderId);
|
||||
if (r.IsFailure)
|
||||
{
|
||||
return r.Error;
|
||||
@@ -114,7 +114,7 @@ public struct Material : IResourceReleasable
|
||||
MemoryType = ResourceMemoryType.Default,
|
||||
};
|
||||
|
||||
var buffer = manager.ResourceAllocator.CreateBuffer(ref desc, "MaterialCBuffer");
|
||||
var buffer = resourceAllocator.CreateBuffer(ref desc, "MaterialCBuffer");
|
||||
_cBufferCache = new CBufferCache(buffer, shader.CBufferSize);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ using Misaki.HighPerformance.Mathematics.Geometry;
|
||||
|
||||
namespace Ghost.Graphics.Core;
|
||||
|
||||
// TODO: Support sub-meshes and meshlets.
|
||||
public struct Mesh : IResourceReleasable
|
||||
{
|
||||
private UnsafeList<Vertex> _vertices;
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
using Ghost.Core;
|
||||
using Misaki.HighPerformance.LowLevel.Buffer;
|
||||
using Misaki.HighPerformance.LowLevel.Collections;
|
||||
using Misaki.HighPerformance.Mathematics;
|
||||
|
||||
namespace Ghost.Graphics.Core;
|
||||
|
||||
public record struct RenderRecord
|
||||
{
|
||||
public float4x4 localToWorld;
|
||||
public Handle<Material> material;
|
||||
public Handle<Mesh> mesh;
|
||||
public RenderingLayerMask renderingLayerMask;
|
||||
public byte subMeshIndex;
|
||||
}
|
||||
|
||||
public struct RenderList : IDisposable
|
||||
|
||||
@@ -2,7 +2,7 @@ using System.Diagnostics;
|
||||
|
||||
namespace Ghost.Graphics.Core;
|
||||
|
||||
public struct RenderingLayerMask
|
||||
public struct RenderingLayerMask : IEquatable<RenderingLayerMask>
|
||||
{
|
||||
private static readonly Dictionary<string, uint> _layerNameToBit = new (32);
|
||||
private static readonly Dictionary<uint, string> _bitToLayerName = new (32);
|
||||
@@ -28,6 +28,38 @@ public struct RenderingLayerMask
|
||||
|
||||
public uint value;
|
||||
|
||||
public static implicit operator uint(RenderingLayerMask mask) => mask.value;
|
||||
public static implicit operator RenderingLayerMask(uint value) => new RenderingLayerMask { value = value };
|
||||
public readonly bool Equals(RenderingLayerMask other)
|
||||
{
|
||||
return value == other.value;
|
||||
}
|
||||
|
||||
public override readonly bool Equals(object? obj)
|
||||
{
|
||||
return obj is RenderingLayerMask mask && Equals(mask);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public static bool operator ==(RenderingLayerMask left, RenderingLayerMask right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
public static bool operator !=(RenderingLayerMask left, RenderingLayerMask right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
public static implicit operator uint(RenderingLayerMask mask)
|
||||
{
|
||||
return mask.value;
|
||||
}
|
||||
|
||||
public static implicit operator RenderingLayerMask(uint value)
|
||||
{
|
||||
return new RenderingLayerMask { value = value };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,8 @@ public unsafe partial class GhostRenderPipeline : IRenderPipeline
|
||||
{
|
||||
request.renderFunc(in ctx, in request);
|
||||
}
|
||||
|
||||
// TODO: Set up the rendering pipeline using render graph based on the request data
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ public enum GraphicsAPI
|
||||
Direct3D12
|
||||
}
|
||||
|
||||
public struct RenderingConfig
|
||||
public struct RenderSystemDesc
|
||||
{
|
||||
public GraphicsAPI GraphicsAPI
|
||||
{
|
||||
@@ -83,7 +83,7 @@ internal class RenderSystem : IRenderSystem
|
||||
}
|
||||
}
|
||||
|
||||
private readonly RenderingConfig _config;
|
||||
private readonly RenderSystemDesc _config;
|
||||
private readonly IGraphicsEngine _graphicsEngine;
|
||||
private readonly IResourceManager _resourceManager;
|
||||
|
||||
@@ -108,16 +108,21 @@ internal class RenderSystem : IRenderSystem
|
||||
public uint FrameIndex => _frameIndex;
|
||||
public uint MaxFrameLatency => _config.FrameBufferCount;
|
||||
|
||||
public RenderSystem(RenderingConfig config)
|
||||
public RenderSystem(RenderSystemDesc desc)
|
||||
{
|
||||
_config = config;
|
||||
_config = desc;
|
||||
|
||||
switch (config.GraphicsAPI)
|
||||
var engineDesc = new GraphicsEngineDesc
|
||||
{
|
||||
FrameBufferCount = desc.FrameBufferCount
|
||||
};
|
||||
|
||||
switch (desc.GraphicsAPI)
|
||||
{
|
||||
case GraphicsAPI.Direct3D12:
|
||||
if (OperatingSystem.IsWindowsVersionAtLeast(10, 0, 19041))
|
||||
{
|
||||
_graphicsEngine = D3D12GraphicsEngineFactory.Create(this);
|
||||
_graphicsEngine = D3D12GraphicsEngineFactory.Create(engineDesc);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -128,14 +133,14 @@ internal class RenderSystem : IRenderSystem
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new NotSupportedException($"The specified graphics API '{config.GraphicsAPI}' is not supported.");
|
||||
throw new NotSupportedException($"The specified graphics API '{desc.GraphicsAPI}' is not supported.");
|
||||
}
|
||||
|
||||
_resourceManager = new ResourceManager(_graphicsEngine.ResourceAllocator, _graphicsEngine.ResourceDatabase);
|
||||
|
||||
// Create frame resources for synchronization
|
||||
_frameResources = new FrameResource[config.FrameBufferCount];
|
||||
for (var i = 0; i < config.FrameBufferCount; i++)
|
||||
_frameResources = new FrameResource[desc.FrameBufferCount];
|
||||
for (var i = 0; i < desc.FrameBufferCount; i++)
|
||||
{
|
||||
_frameResources[i] = new FrameResource
|
||||
{
|
||||
@@ -275,11 +280,13 @@ internal class RenderSystem : IRenderSystem
|
||||
}
|
||||
|
||||
_resizeRequest.Clear();
|
||||
|
||||
continue; // Skip rendering this frame since we just resized and may have invalid render targets
|
||||
}
|
||||
|
||||
frameResource.CommandAllocator.Reset();
|
||||
|
||||
var r = _graphicsEngine.RenderFrame(frameResource.CommandAllocator);
|
||||
var r = _graphicsEngine.RenderFrame(frameResource.CommandAllocator, _cpuFenceValue, _gpuFenceValue);
|
||||
if (r.IsFailure)
|
||||
{
|
||||
_isRunning = false;
|
||||
|
||||
Reference in New Issue
Block a user