#include "XCEngine/RHI/D3D12/D3D12Device.h" #ifdef _DEBUG #include #endif namespace XCEngine { namespace RHI { D3D12Device::D3D12Device() : m_isDeviceRemoved(false) , m_initialized(false) { } D3D12Device::~D3D12Device() { Shutdown(); } bool D3D12Device::Initialize(bool enableDebugLayer) { if (m_initialized) { return true; } if (!CreateDXGIFactory(enableDebugLayer)) { return false; } ComPtr adapter; int adapterIndex = 0; bool adapterFound = false; while (m_factory->EnumAdapters1(adapterIndex, &adapter) != DXGI_ERROR_NOT_FOUND) { DXGI_ADAPTER_DESC1 desc; adapter->GetDesc1(&desc); if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) { adapterIndex++; continue; } HRESULT hr = D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, __uuidof(ID3D12Device), nullptr); if (SUCCEEDED(hr)) { adapterFound = true; m_adapter = adapter; break; } adapterIndex++; } if (!adapterFound) { return false; } if (!CreateDevice(m_adapter.Get())) { return false; } QueryDeviceInfo(); m_initialized = true; return true; } void D3D12Device::Shutdown() { if (m_device) { m_device.Reset(); } if (m_factory) { m_factory.Reset(); } m_adapter.Reset(); m_initialized = false; } bool D3D12Device::CreateDXGIFactory(bool enableDebugLayer) { UINT dxgiFactoryFlags = 0; #ifdef _DEBUG if (enableDebugLayer) { ID3D12Debug* debugController = nullptr; if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController)))) { debugController->EnableDebugLayer(); dxgiFactoryFlags |= DXGI_CREATE_FACTORY_DEBUG; debugController->Release(); } } #endif HRESULT hr = CreateDXGIFactory2(dxgiFactoryFlags, IID_PPV_ARGS(&m_factory)); return SUCCEEDED(hr); } bool D3D12Device::CreateDevice(IDXGIAdapter1* adapter) { HRESULT hr = D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&m_device)); return SUCCEEDED(hr); } void D3D12Device::QueryDeviceInfo() { if (!m_adapter) { return; } DXGI_ADAPTER_DESC1 desc; m_adapter->GetDesc1(&desc); m_deviceInfo.vendorId = desc.VendorId; m_deviceInfo.deviceId = desc.DeviceId; m_deviceInfo.dedicatedVideoMemory = desc.DedicatedVideoMemory; m_deviceInfo.dedicatedSystemMemory = desc.DedicatedSystemMemory; m_deviceInfo.sharedSystemMemory = desc.SharedSystemMemory; m_deviceInfo.deviceName = desc.Description; m_deviceInfo.supportsRaytracing = false; m_deviceInfo.supportsMeshShaders = false; m_deviceInfo.supportsSamplerFeedback = false; D3D12_FEATURE_DATA_D3D12_OPTIONS5 options5 = {}; if (SUCCEEDED(m_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS5, &options5, sizeof(options5)))) { m_deviceInfo.supportsRaytracing = (options5.RaytracingTier != D3D12_RAYTRACING_TIER_NOT_SUPPORTED); } D3D12_FEATURE_DATA_D3D12_OPTIONS7 options7 = {}; if (SUCCEEDED(m_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS7, &options7, sizeof(options7)))) { m_deviceInfo.supportsSamplerFeedback = (options7.SamplerFeedbackTier != D3D12_SAMPLER_FEEDBACK_TIER_NOT_SUPPORTED); m_deviceInfo.supportsMeshShaders = (options7.MeshShaderTier != D3D12_MESH_SHADER_TIER_NOT_SUPPORTED); } } bool D3D12Device::CheckFeatureSupport(D3D12_FEATURE feature, void* featureSupportData, uint32_t featureSupportDataSize) { return SUCCEEDED(m_device->CheckFeatureSupport(feature, featureSupportData, featureSupportDataSize)); } std::vector D3D12Device::EnumerateAdapters() { std::vector adapters; if (!m_factory) { return adapters; } ComPtr adapter; int adapterIndex = 0; while (m_factory->EnumAdapters1(adapterIndex, &adapter) != DXGI_ERROR_NOT_FOUND) { DXGI_ADAPTER_DESC1 desc; adapter->GetDesc1(&desc); AdapterInfo info; info.description = desc.Description; info.dedicatedVideoMemory = desc.DedicatedVideoMemory; info.dedicatedSystemMemory = desc.DedicatedSystemMemory; info.sharedSystemMemory = desc.SharedSystemMemory; info.vendorId = desc.VendorId; info.deviceId = desc.DeviceId; info.isSoftware = (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) != 0; adapters.push_back(info); adapterIndex++; } return adapters; } } // namespace RHI } // namespace XCEngine