#include "D3D12Core.h" #include "D3D12CommonHeader.h" using namespace Microsoft::WRL; namespace XEngine::graphics::d3d12::core { namespace { /** * @brief 主 Direct3D 12 设备指针 * @details 指向 Direct3D 12 设备的智能指针,用于创建渲染管线、管理资源与 GPU 命令 */ ID3D12Device8* main_device{ nullptr }; /** * @brief DXGI 工厂指针 * @details 指向 DXGI 工厂的智能指针,用于创建 Direct3D 12 设备 */ IDXGIFactory7* dxgi_factory{ nullptr }; // 最小支持的 Direct3D 特本级别 constexpr D3D_FEATURE_LEVEL minumum_feature_level{ D3D_FEATURE_LEVEL_11_0 }; bool failed_init() { shutdown(); return false; } /** * @brief 确定要使用的 GPU * @details 枚举所有可用的 GPU,选择支持最小特征级别的 Direct3D 12 设备 * 注意:该功能可通过以下方式扩展:例如,检查是否有任何 * 输出设备(即显示器)已连接,枚举支持的分辨率,提供 * 一种机制供用户在多适配器环境中选择要使用的适配器等 * @return IDXGIAdapter4* 指向确定的 GPU 的智能指针 */ IDXGIAdapter4* determine_main_adapter() { IDXGIAdapter4* adapter; for (u32 i{ 0 }; dxgi_factory->EnumAdapterByGpuPreference(i, DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE, IID_PPV_ARGS(&adapter)) != DXGI_ERROR_NOT_FOUND; ++i) { //获取支持最小特征级别的 Direct3D 12 设备 if (SUCCEEDED(D3D12CreateDevice(adapter, minumum_feature_level, __uuidof(ID3D12Device8), nullptr))) { return adapter; } release(adapter); } return nullptr; } /** * @brief 获取指定适配器支持的最高 Direct3D 特性级别 * @details 检查指定适配器是否支持 Direct3D 12 特性级别 * @param adapter 指向要检查的适配器的智能指针 * @return D3D_FEATURE_LEVEL 支持的最高 Direct3D 特性级别 */ D3D_FEATURE_LEVEL get_max_feature_level(IDXGIAdapter4* adapter) { constexpr D3D_FEATURE_LEVEL feature_levels[4]{ D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_12_0, D3D_FEATURE_LEVEL_12_1, }; D3D12_FEATURE_DATA_FEATURE_LEVELS feature_level_info{}; feature_level_info.NumFeatureLevels = (_countof(feature_levels)); feature_level_info.pFeatureLevelsRequested = feature_levels; ComPtr device; DXCall(D3D12CreateDevice(adapter, minumum_feature_level, IID_PPV_ARGS(&device))); DXCall(device->CheckFeatureSupport(D3D12_FEATURE_FEATURE_LEVELS, &feature_level_info, sizeof(feature_level_info))); return feature_level_info.MaxSupportedFeatureLevel; } }// anonymous namespace bool initialize() { if (main_device) shutdown(); // 在DEBUG模式下,捕获 DXGI 可能抛出的异常 u32 dxgi_factory_flag{ 0 }; // 开启调试层, 需要graphics tools支持 #ifdef _DEBUG { ComPtr debug_interface; DXCall(D3D12GetDebugInterface(IID_PPV_ARGS(&debug_interface))); debug_interface->EnableDebugLayer(); dxgi_factory_flag |= DXGI_CREATE_FACTORY_DEBUG; } #endif // 创建 DXGI 工厂实例,用于枚举显卡适配器和创建交换链等操作 HRESULT hr{ S_OK }; DXCall(hr = CreateDXGIFactory2(dxgi_factory_flag, IID_PPV_ARGS(&dxgi_factory))); if (FAILED(hr)) return failed_init(); // 确定要使用的 GPU ComPtr main_adapter; main_adapter.Attach(determine_main_adapter()); if (!main_adapter) return failed_init(); // 获取主适配器支持的最高 Direct3D 特性级别,并且不得低于最小要求 D3D_FEATURE_LEVEL max_feature_level{ get_max_feature_level(main_adapter.Get()) }; assert(max_feature_level >= minumum_feature_level); if (max_feature_level < minumum_feature_level) return failed_init(); // 使用最高适配特性级别创建Direct3D 12 设备 DXCall(hr = D3D12CreateDevice(main_adapter.Get(), max_feature_level, IID_PPV_ARGS(&main_device))); if (FAILED(hr)) return failed_init(); // 为 Direct3D 12 设备设置名称 NAME_D3D12_OBJECT(main_device, L"Main Device"); #ifdef _DEBUG { ComPtr info_queue; DXCall(main_device->QueryInterface(IID_PPV_ARGS(&info_queue))); info_queue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_CORRUPTION, true); info_queue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_WARNING, true); info_queue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_ERROR, true); } #endif // _DEBUG return true; } void shutdown() { release(dxgi_factory); // 关闭调试层,确保最后只有一个活动的主设备 #ifdef _DEBUG { { ComPtr info_queue; DXCall(main_device->QueryInterface(IID_PPV_ARGS(&info_queue))); info_queue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_CORRUPTION, false); info_queue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_WARNING, false); info_queue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_ERROR, false); } ComPtr debug_device; DXCall(main_device->QueryInterface(IID_PPV_ARGS(&debug_device))); release(main_device); DXCall(debug_device->ReportLiveDeviceObjects( D3D12_RLDO_SUMMARY | D3D12_RLDO_DETAIL | D3D12_RLDO_IGNORE_INTERNAL )); } #endif // _DEBUG release(main_device); } }// namespace XEngine::graphics::d3d12::core