forked from Misaki/GhostEngine
Refactor graphics architecture and resource management
Added DescriptorAllocator.cs to manage descriptor allocations for Direct3D 12. Added Texture2D.cs to handle 2D textures and GPU resource creation. Added DescriptorAllocatorExample.cs to demonstrate the new descriptor allocator interface. Changed project files to reference Misaki.HighPerformance.LowLevel instead of Misaki.HighPerformance.Unsafe. Changed _renderView type from IRenderer? to Renderer? in ScenePage.xaml.cs. Changed EngineCore.cs to remove explicit graphics API specification during initialization. Changed Logger.cs to enhance the Assert method with a DoesNotReturnIf attribute. Changed resource types in Mesh.cs from IResource to GraphicsResource. Removed multiple interfaces including ICommandBuffer, IDebugLayer, IGraphicsDevice, IPipelineResource, IRenderPass, IRenderer, IResource, and IResourceAllocator to simplify the graphics architecture. Removed D3D12DebugLayer class from DebugLayer.cs to streamline the debug layer implementation. Updated CommandList.cs and D3D12CommandBuffer.cs to implement a new command list structure for Direct3D 12. Updated Material.cs to improve handling of constant buffers and textures. Updated Shader.cs to include new structures for texture and property information. Updated GraphicsPipeline.cs to support the new graphics device and resource management system. Updated UnitTestAppWindow.xaml.cs to reflect changes in the renderer type and ensure proper resource management. Updated BindlessMeshRenderPass.cs and MeshRenderPass.cs to implement modern rendering techniques, including bindless textures and improved shader management. Updated CBufferCache.cs to align with the new resource management system and improve memory handling.
This commit is contained in:
158
Ghost.Graphics/D3D12/GraphicsDevice.cs
Normal file
158
Ghost.Graphics/D3D12/GraphicsDevice.cs
Normal file
@@ -0,0 +1,158 @@
|
||||
using Ghost.Core;
|
||||
using Ghost.Graphics.Data;
|
||||
using System.Collections.Immutable;
|
||||
using Win32;
|
||||
using Win32.Graphics.Direct3D;
|
||||
using Win32.Graphics.Direct3D12;
|
||||
using Win32.Graphics.Dxgi;
|
||||
|
||||
namespace Ghost.Graphics.D3D12;
|
||||
|
||||
internal unsafe class GraphicsDevice
|
||||
{
|
||||
#if DEBUG
|
||||
private readonly DebugLayer _debugLayer;
|
||||
#endif
|
||||
private ComPtr<IDXGIFactory7> _dxgiFactory;
|
||||
private ComPtr<ID3D12Device14> _device;
|
||||
private ComPtr<ID3D12CommandQueue> _commandQueue;
|
||||
|
||||
private ImmutableArray<Renderer> _initializeQueue;
|
||||
private ImmutableArray<Renderer> _renderers;
|
||||
|
||||
private bool _disposed;
|
||||
|
||||
public ReadOnlySpan<Renderer> InitializeQueue => _initializeQueue.AsSpan();
|
||||
public ReadOnlySpan<Renderer> Renderers => _renderers.AsSpan();
|
||||
|
||||
public ConstPtr<ID3D12Device14> NativeDevice => new(_device.Get());
|
||||
public ConstPtr<IDXGIFactory7> DXGIFactory => new(_dxgiFactory.Get());
|
||||
public ConstPtr<ID3D12CommandQueue> CommandQueue => new(_commandQueue.Get());
|
||||
|
||||
public GraphicsDevice()
|
||||
{
|
||||
#if DEBUG
|
||||
_debugLayer = new DebugLayer();
|
||||
#endif
|
||||
|
||||
InitializeDevice();
|
||||
InitializeCommandQueue();
|
||||
|
||||
_initializeQueue = ImmutableArray<Renderer>.Empty;
|
||||
_renderers = ImmutableArray<Renderer>.Empty;
|
||||
}
|
||||
|
||||
private void InitializeDevice()
|
||||
{
|
||||
#if DEBUG
|
||||
CreateDXGIFactory2(true, __uuidof<IDXGIFactory7>(), _dxgiFactory.GetVoidAddressOf());
|
||||
#else
|
||||
CreateDXGIFactory2(false, __uuidof<IDXGIFactory7>(), _dxgiFactory.GetVoidAddressOf());
|
||||
#endif
|
||||
|
||||
using ComPtr<IDXGIAdapter1> adapter = default;
|
||||
|
||||
for (uint adapterIndex = 0;
|
||||
_dxgiFactory.Get()->EnumAdapterByGpuPreference(adapterIndex, GpuPreference.HighPerformance, __uuidof<IDXGIAdapter1>(), adapter.ReleaseAndGetVoidAddressOf()).Success;
|
||||
adapterIndex++)
|
||||
{
|
||||
AdapterDescription1 desc = default;
|
||||
adapter.Get()->GetDesc1(&desc);
|
||||
|
||||
// Don't select the Basic Render Driver adapter.
|
||||
if ((desc.Flags & AdapterFlags.Software) != AdapterFlags.None)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (D3D12CreateDevice((IUnknown*)adapter.Get(), FeatureLevel.Level_12_0, __uuidof<ID3D12Device14>(), _device.GetVoidAddressOf()).Success)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_device.Get() == null)
|
||||
{
|
||||
throw new PlatformNotSupportedException("Cannot create ID3D12Device with feature level 12.0");
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeCommandQueue()
|
||||
{
|
||||
var queueDesc = new CommandQueueDescription
|
||||
{
|
||||
Type = CommandListType.Direct,
|
||||
Priority = (int)CommandQueuePriority.High,
|
||||
Flags = CommandQueueFlags.None,
|
||||
};
|
||||
|
||||
fixed (void* queuePtr = &_commandQueue)
|
||||
{
|
||||
_device.Get()->CreateCommandQueue(&queueDesc, __uuidof<ID3D12CommandQueue>(), (void**)queuePtr);
|
||||
}
|
||||
}
|
||||
|
||||
public Renderer CreateRenderer(in SwapChainPresenter presenter)
|
||||
{
|
||||
var renderView = new Renderer(this, in presenter);
|
||||
ImmutableInterlocked.Update(ref _initializeQueue, old => old.Add(renderView));
|
||||
|
||||
return renderView;
|
||||
}
|
||||
|
||||
public void RemoveRenderer(Renderer renderer)
|
||||
{
|
||||
if (renderer is Renderer dx12RenderView)
|
||||
{
|
||||
dx12RenderView.Dispose();
|
||||
|
||||
var index = _initializeQueue.IndexOf(dx12RenderView);
|
||||
if (index > -1)
|
||||
{
|
||||
ImmutableInterlocked.Update(ref _initializeQueue, old => old.RemoveAt(index));
|
||||
}
|
||||
else
|
||||
{
|
||||
ImmutableInterlocked.Update(ref _renderers, old => old.Remove(dx12RenderView));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void InitializePendingRenderers()
|
||||
{
|
||||
if (_initializeQueue.IsEmpty)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var renderer in _initializeQueue.AsSpan())
|
||||
{
|
||||
renderer.Initialize();
|
||||
}
|
||||
|
||||
ImmutableInterlocked.Update(ref _renderers, old => old.AddRange(_initializeQueue));
|
||||
_initializeQueue = _initializeQueue.Clear();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var renderer in _renderers)
|
||||
{
|
||||
renderer.Dispose();
|
||||
}
|
||||
|
||||
_commandQueue.Dispose();
|
||||
_device.Reset();
|
||||
_dxgiFactory.Dispose();
|
||||
|
||||
#if DEBUG
|
||||
_debugLayer.Dispose();
|
||||
#endif
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user