Added RenderList and RenderReques.

Added IRenderPipeline.
This commit is contained in:
2026-02-28 21:31:38 +09:00
parent 6f802ac12b
commit 5e42d699c3
6 changed files with 187 additions and 20 deletions

View File

@@ -3,6 +3,7 @@ using Ghost.Graphics.D3D12.Utilities;
using Ghost.Graphics.RHI; using Ghost.Graphics.RHI;
using Misaki.HighPerformance.LowLevel; using Misaki.HighPerformance.LowLevel;
using Misaki.HighPerformance.LowLevel.Utilities; using Misaki.HighPerformance.LowLevel.Utilities;
using System.Diagnostics;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using TerraFX.Interop.DirectX; using TerraFX.Interop.DirectX;
using TerraFX.Interop.Gdiplus; using TerraFX.Interop.Gdiplus;
@@ -24,9 +25,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
private readonly D3D12DescriptorAllocator _descriptorAllocator; private readonly D3D12DescriptorAllocator _descriptorAllocator;
private readonly CommandBufferType _type; private readonly CommandBufferType _type;
#if !DEBUG
private CommandError _lastError; private CommandError _lastError;
#endif
private ushort _commandCount; private ushort _commandCount;
private bool _isRecording; private bool _isRecording;
private bool _disposed; private bool _disposed;
@@ -112,16 +111,9 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
#if DEBUG
[System.Diagnostics.CodeAnalysis.DoesNotReturn]
private static void RecordError(string cmdName, Error status)
#else
private void RecordError(string cmdName, Error status) private void RecordError(string cmdName, Error status)
#endif
{ {
#if DEBUG Debug.Fail($"Command '{cmdName}' failed with error: {status}");
throw new InvalidOperationException($"Error at {cmdName} with {status}");
#else
_lastError = new CommandError _lastError = new CommandError
{ {
@@ -129,7 +121,6 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
CommandIndex = _commandCount, CommandIndex = _commandCount,
Status = status Status = status
}; };
#endif
} }
public void Begin(ICommandAllocator allocator) public void Begin(ICommandAllocator allocator)

View File

@@ -1,9 +0,0 @@
using Ghost.Graphics.Core;
using Ghost.Graphics.RHI;
namespace Ghost.Graphics.Contracts;
public interface IRenderPipeline
{
void Render(RenderContext ctx, ReadOnlySpan<Camera> cameras);
}

View File

@@ -0,0 +1,96 @@
using Ghost.Core;
using Misaki.HighPerformance.LowLevel.Buffer;
using Misaki.HighPerformance.LowLevel.Collections;
namespace Ghost.Graphics.Core;
public record struct RenderRecord
{
public Handle<Material> material;
public Handle<Mesh> mesh;
}
public struct RenderList : IDisposable
{
public unsafe ref struct Reader
{
private readonly UnsafeList<RenderRecord>* pList;
private readonly int length;
private int _listIndex;
private int _itemIndex;
internal Reader(RenderList List)
{
pList = (UnsafeList<RenderRecord>*)List._threadLocalRecords.GetUnsafePtr();
length = List._threadLocalRecords.Length;
_listIndex = 0;
_itemIndex = -1;
}
public RenderRecord Current => pList[_listIndex][_itemIndex];
public bool MoveNext()
{
while (_listIndex < length)
{
if (_itemIndex < pList[_listIndex].Count)
{
_itemIndex++;
return true;
}
else
{
_listIndex++;
_itemIndex = 0;
}
}
return false;
}
public void Reset()
{
_listIndex = 0;
_itemIndex = -1;
}
}
private UnsafeArray<UnsafeList<RenderRecord>> _threadLocalRecords;
public RenderList(int maxLevelOfConcurrency, int capacity, AllocationHandle allocationHandle)
{
_threadLocalRecords = new UnsafeArray<UnsafeList<RenderRecord>>(maxLevelOfConcurrency, allocationHandle);
for (int i = 0; i < maxLevelOfConcurrency; i++)
{
_threadLocalRecords[i] = new UnsafeList<RenderRecord>(capacity, allocationHandle);
}
}
public RenderList(int maxLevelOfConcurrency, int capacity, Allocator allocator)
: this(maxLevelOfConcurrency, capacity, AllocationManager.GetAllocationHandle(allocator))
{
}
public readonly Reader GetEnumerator()
{
return new Reader(this);
}
public readonly void Add(RenderRecord record, int threadIndex)
{
_threadLocalRecords[threadIndex].Add(record);
}
public void Dispose()
{
for (int i = 0; i < _threadLocalRecords.Length; i++)
{
_threadLocalRecords[i].Dispose();
}
_threadLocalRecords.Dispose();
}
}

View File

@@ -0,0 +1,65 @@
using Ghost.Core;
using Ghost.Graphics.RHI;
using Misaki.HighPerformance.Mathematics;
using System.Runtime.InteropServices;
namespace Ghost.Graphics.Core;
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct Frustum
{
// The data of the 6 planes of the frustum
public float3 normal0;
public float dist0;
public float3 normal1;
public float dist1;
public float3 normal2;
public float dist2;
public float3 normal3;
public float dist3;
public float3 normal4;
public float dist4;
public float3 normal5;
public float dist5;
// The data of the 8 corners of the frustum
public float3 corner0;
public float3 corner1;
public float3 corner2;
public float3 corner3;
public float3 corner4;
public float3 corner5;
public float3 corner6;
public float3 corner7;
}
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct RenderView
{
public float4x4 view;
public float4x4 projection;
public float4x4 viewProjection;
public float3 position;
public Frustum frustum; // 192 bytes
public float nearClipPlane;
public float farClipPlane;
public float2 sensorSize;
public float iso;
public float shutterSpeed;
public float aperture;
public float focalLength;
public float focusDistance;
public uint renderingLayerMask;
}
public unsafe struct RenderRequest
{
public RenderView view;
public Handle<Texture> colorTarget;
public Handle<Texture> depthTarget;
public delegate*<ref readonly RenderingContext, ref readonly RenderRequest, void> renderFunc;
}

View File

@@ -0,0 +1,15 @@
using Ghost.Graphics.Core;
using Ghost.Graphics.RHI;
namespace Ghost.Graphics.RenderPipeline;
public partial class GhostRenderPipeline : IRenderPipeline
{
public void Render(RenderContext ctx, ReadOnlySpan<RenderRequest> requests)
{
}
public void Dispose()
{
}
}

View File

@@ -0,0 +1,9 @@
using Ghost.Graphics.Core;
using Ghost.Graphics.RHI;
namespace Ghost.Graphics.RenderPipeline;
public interface IRenderPipeline : IDisposable
{
void Render(RenderContext ctx, ReadOnlySpan<RenderRequest> requests);
}