using Ghost.Core; using Win32; using Win32.Graphics.Direct3D; using Win32.Graphics.Direct3D12; using Win32.Graphics.Dxgi; namespace Ghost.Graphics.D3D12; /// /// Legacy D3D12 GraphicsDevice - DEPRECATED /// Use D3D12RenderDevice instead for new code /// This class remains for compatibility during migration /// [Obsolete("Use D3D12RenderDevice instead")] internal unsafe class GraphicsDevice { private ComPtr _dxgiFactory; private ComPtr _device; private ComPtr _adapter; private ComPtr _commandQueue; private bool _disposed; public ConstPtr NativeDevice => new(_device.Get()); public ConstPtr DXGIFactory => new(_dxgiFactory.Get()); public ConstPtr Adapter => new(_adapter.Get()); public ConstPtr CommandQueue => new(_commandQueue.Get()); public GraphicsDevice() { InitializeDevice(); InitializeCommandQueue(); } private void InitializeDevice() { #if DEBUG CreateDXGIFactory2(true, __uuidof(), _dxgiFactory.GetVoidAddressOf()); #else CreateDXGIFactory2(false, __uuidof(), _dxgiFactory.GetVoidAddressOf()); #endif using ComPtr adapter = default; for (uint adapterIndex = 0; _dxgiFactory.Get()->EnumAdapterByGpuPreference(adapterIndex, GpuPreference.HighPerformance, __uuidof(), 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(), _device.GetVoidAddressOf()).Success) { _adapter = adapter.Move(); 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(), (void**)queuePtr); } } public void Dispose() { if (_disposed) { return; } _commandQueue.Dispose(); _device.Reset(); _dxgiFactory.Dispose(); _disposed = true; } }