#include "adapter-dx.hpp" #include "../helpers.hpp" namespace xna { UGraphicsAdapter IGraphicsAdapter::DefaultAdapter() { IDXGIFactory1* pFactory = nullptr; if FAILED(CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&pFactory)) return nullptr; IDXGIAdapter1* pAdapter = nullptr; if (pFactory->EnumAdapters1(0, &pAdapter) != DXGI_ERROR_NOT_FOUND) { auto adp = uNew(); adp->_index = 0; adp->_adapter = pAdapter; return std::move(adp); } pFactory->Release(); pFactory = nullptr; return nullptr; } void IGraphicsAdapter::Adapters(std::vector& adapters){ IDXGIFactory1* pFactory = nullptr; if FAILED(CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&pFactory)) return; IDXGIAdapter1* pAdapter = nullptr; UINT count = 0; for (; pFactory->EnumAdapters1(count, &pAdapter) != DXGI_ERROR_NOT_FOUND; ++count) { auto adp = New(); adp->_index = count; adp->_adapter = pAdapter; adapters.push_back(adp); } pFactory->Release(); pFactory = nullptr; } void IGraphicsAdapter::Adapters(std::vector& adapters) { IDXGIFactory1* pFactory = nullptr; if FAILED(CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&pFactory)) return; IDXGIAdapter1* pAdapter = nullptr; UINT count = 0; for (; pFactory->EnumAdapters1(count, &pAdapter) != DXGI_ERROR_NOT_FOUND; ++count) { auto adp = uNew(); adp->_index = count; adp->_adapter = pAdapter; adapters.push_back(std::move(adp)); } pFactory->Release(); pFactory = nullptr; } String GraphicsAdapter::Description() const { if (!_adapter) return String(); DXGI_ADAPTER_DESC1 desc; _adapter->GetDesc1(&desc); String description = XnaHToString(desc.Description); return description; } Uint GraphicsAdapter::DeviceId() const { if (!_adapter) return 0; DXGI_ADAPTER_DESC1 desc; _adapter->GetDesc1(&desc); return static_cast(desc.DeviceId); } String GraphicsAdapter::DeviceName() const { if (!_adapter) return String(); IDXGIOutput* pOutput = nullptr; DXGI_OUTPUT_DESC outputDesc; if (_adapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) { pOutput->GetDesc(&outputDesc); String deviceName = XnaHToString(outputDesc.DeviceName); pOutput->Release(); pOutput = nullptr; return deviceName; } return String(); } intptr_t GraphicsAdapter::MonitorHandle() const { if (!_adapter) return 0; IDXGIOutput* pOutput = nullptr; DXGI_OUTPUT_DESC outputDesc; if (_adapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) { pOutput->GetDesc(&outputDesc); pOutput->Release(); pOutput = nullptr; return reinterpret_cast(outputDesc.Monitor); } return 0; } Uint GraphicsAdapter::Revision() const { if (!_adapter) return 0; DXGI_ADAPTER_DESC1 desc; _adapter->GetDesc1(&desc); return static_cast(desc.Revision); } Uint GraphicsAdapter::SubSystemId() const { if (!_adapter) return 0; DXGI_ADAPTER_DESC1 desc; _adapter->GetDesc1(&desc); return static_cast(desc.SubSysId); } Uint GraphicsAdapter::VendorId() const { if (!_adapter) return 0; DXGI_ADAPTER_DESC1 desc; _adapter->GetDesc1(&desc); return static_cast(desc.VendorId); } static UINT getDisplayModesCount(IDXGIAdapter* adapter) { IDXGIOutput* pOutput = nullptr; UINT numModes = 0; if (adapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) { for (size_t f = 0; f < SURFACE_FORMAT_COUNT; ++f) { const auto currentSurface = static_cast(f); DXGI_FORMAT format = GraphicsAdapter::ToDXGI(currentSurface); UINT num = 0; pOutput->GetDisplayModeList(format, 0, &num, nullptr); numModes += num; } pOutput->Release(); pOutput = nullptr; } return numModes; } UDisplayModeCollection GraphicsAdapter::SupportedDisplayModes() const { if (!_adapter) return nullptr; IDXGIOutput* pOutput = nullptr; UINT numModes = 0; UINT totalModes = 0; const auto totalDisplay = getDisplayModesCount(_adapter); std::vector buffer(totalDisplay); if (_adapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) { for (size_t f = 0; f < SURFACE_FORMAT_COUNT; ++f) { const auto currentSurface = static_cast(f); DXGI_FORMAT format = GraphicsAdapter::ToDXGI(currentSurface); pOutput->GetDisplayModeList(format, 0, &numModes, nullptr); if (numModes == 0) continue; pOutput->GetDisplayModeList(format, 0, &numModes, buffer.data() + totalModes); totalModes += numModes; } } if (!pOutput) return nullptr; pOutput->Release(); pOutput = nullptr; auto collection = uNew(); DisplayMode currentDisplayMode; std::vector displayList; PDisplayMode pDisplay = nullptr; for (size_t i = 0; i < totalModes; ++i) { auto& modedesc = buffer[i]; DisplayModeDescription description; description._refreshRate = modedesc.RefreshRate; description._scaling = static_cast(modedesc.Scaling); description._scanlineOrdering = static_cast(modedesc.ScanlineOrdering); if (pDisplay && pDisplay->_width == modedesc.Width && pDisplay->_height == modedesc.Height && pDisplay->_format == GraphicsAdapter::ToSurface(modedesc.Format)) { pDisplay->_descriptions.push_back(description); } else { pDisplay = New(); pDisplay->_width = modedesc.Width; pDisplay->_height = modedesc.Height; pDisplay->_format = GraphicsAdapter::ToSurface(modedesc.Format); pDisplay->_descriptions.push_back(description); displayList.push_back(pDisplay); } } collection->_displayModes = displayList; return std::move(collection); } }