2024-03-18 15:41:46 -03:00
|
|
|
#include "adapter-dx.hpp"
|
|
|
|
#include "../helpers.hpp"
|
|
|
|
|
|
|
|
namespace xna {
|
|
|
|
|
2024-04-21 16:06:22 -03:00
|
|
|
UGraphicsAdapter IGraphicsAdapter::DefaultAdapter() {
|
|
|
|
IDXGIFactory1* pFactory = nullptr;
|
2024-04-01 16:18:18 -03:00
|
|
|
|
2024-04-21 16:06:22 -03:00
|
|
|
if FAILED(CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&pFactory))
|
2024-04-01 16:18:18 -03:00
|
|
|
return nullptr;
|
|
|
|
|
2024-04-21 16:06:22 -03:00
|
|
|
IDXGIAdapter1* pAdapter = nullptr;
|
|
|
|
|
|
|
|
if (pFactory->EnumAdapters1(0, &pAdapter) != DXGI_ERROR_NOT_FOUND) {
|
|
|
|
auto adp = uNew<GraphicsAdapter>();
|
|
|
|
|
|
|
|
adp->_index = 0;
|
|
|
|
adp->_adapter = pAdapter;
|
|
|
|
|
|
|
|
return std::move(adp);
|
|
|
|
}
|
|
|
|
|
|
|
|
pFactory->Release();
|
|
|
|
pFactory = nullptr;
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2024-04-21 19:55:50 -03:00
|
|
|
void IGraphicsAdapter::Adapters(std::vector<PGraphicsAdapter>& adapters){
|
2024-04-21 16:06:22 -03:00
|
|
|
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<GraphicsAdapter>();
|
|
|
|
|
|
|
|
adp->_index = count;
|
|
|
|
adp->_adapter = pAdapter;
|
|
|
|
|
|
|
|
adapters.push_back(adp);
|
|
|
|
}
|
|
|
|
|
|
|
|
pFactory->Release();
|
|
|
|
pFactory = nullptr;
|
|
|
|
}
|
|
|
|
|
2024-04-21 19:55:50 -03:00
|
|
|
void IGraphicsAdapter::Adapters(std::vector<UGraphicsAdapter>& adapters) {
|
2024-04-21 16:06:22 -03:00
|
|
|
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<GraphicsAdapter>();
|
|
|
|
|
|
|
|
adp->_index = count;
|
|
|
|
adp->_adapter = pAdapter;
|
|
|
|
|
|
|
|
adapters.push_back(std::move(adp));
|
|
|
|
}
|
|
|
|
|
|
|
|
pFactory->Release();
|
|
|
|
pFactory = nullptr;
|
2024-04-01 16:18:18 -03:00
|
|
|
}
|
|
|
|
|
2024-03-18 15:41:46 -03:00
|
|
|
String GraphicsAdapter::Description() const {
|
2024-04-21 16:06:22 -03:00
|
|
|
if (!_adapter) return String();
|
|
|
|
|
2024-03-18 15:41:46 -03:00
|
|
|
DXGI_ADAPTER_DESC1 desc;
|
2024-03-21 16:01:47 -03:00
|
|
|
_adapter->GetDesc1(&desc);
|
2024-04-14 21:23:09 -03:00
|
|
|
String description = XnaHToString(desc.Description);
|
2024-03-18 15:41:46 -03:00
|
|
|
return description;
|
|
|
|
}
|
|
|
|
|
|
|
|
Uint GraphicsAdapter::DeviceId() const {
|
2024-04-21 16:06:22 -03:00
|
|
|
if (!_adapter) return 0;
|
|
|
|
|
2024-03-18 15:41:46 -03:00
|
|
|
DXGI_ADAPTER_DESC1 desc;
|
2024-03-21 16:01:47 -03:00
|
|
|
_adapter->GetDesc1(&desc);
|
2024-03-18 15:41:46 -03:00
|
|
|
|
|
|
|
return static_cast<Uint>(desc.DeviceId);
|
|
|
|
}
|
|
|
|
|
|
|
|
String GraphicsAdapter::DeviceName() const {
|
2024-04-21 16:06:22 -03:00
|
|
|
if (!_adapter) return String();
|
|
|
|
|
2024-03-18 15:41:46 -03:00
|
|
|
IDXGIOutput* pOutput = nullptr;
|
|
|
|
DXGI_OUTPUT_DESC outputDesc;
|
|
|
|
|
2024-03-21 16:01:47 -03:00
|
|
|
if (_adapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) {
|
2024-03-18 15:41:46 -03:00
|
|
|
pOutput->GetDesc(&outputDesc);
|
2024-04-14 21:23:09 -03:00
|
|
|
String deviceName = XnaHToString(outputDesc.DeviceName);
|
2024-03-18 15:41:46 -03:00
|
|
|
|
|
|
|
pOutput->Release();
|
|
|
|
pOutput = nullptr;
|
|
|
|
|
|
|
|
return deviceName;
|
|
|
|
}
|
|
|
|
|
|
|
|
return String();
|
|
|
|
}
|
|
|
|
|
|
|
|
intptr_t GraphicsAdapter::MonitorHandle() const {
|
2024-04-21 16:06:22 -03:00
|
|
|
if (!_adapter) return 0;
|
|
|
|
|
2024-03-18 15:41:46 -03:00
|
|
|
IDXGIOutput* pOutput = nullptr;
|
|
|
|
DXGI_OUTPUT_DESC outputDesc;
|
|
|
|
|
2024-03-21 16:01:47 -03:00
|
|
|
if (_adapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) {
|
2024-03-18 15:41:46 -03:00
|
|
|
pOutput->GetDesc(&outputDesc);
|
|
|
|
|
|
|
|
pOutput->Release();
|
|
|
|
pOutput = nullptr;
|
|
|
|
|
|
|
|
return reinterpret_cast<intptr_t>(outputDesc.Monitor);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Uint GraphicsAdapter::Revision() const {
|
2024-04-21 16:06:22 -03:00
|
|
|
if (!_adapter) return 0;
|
|
|
|
|
2024-03-18 15:41:46 -03:00
|
|
|
DXGI_ADAPTER_DESC1 desc;
|
2024-03-21 16:01:47 -03:00
|
|
|
_adapter->GetDesc1(&desc);
|
2024-03-18 15:41:46 -03:00
|
|
|
|
|
|
|
return static_cast<Uint>(desc.Revision);
|
|
|
|
}
|
|
|
|
|
|
|
|
Uint GraphicsAdapter::SubSystemId() const {
|
2024-04-21 16:06:22 -03:00
|
|
|
if (!_adapter) return 0;
|
|
|
|
|
2024-03-18 15:41:46 -03:00
|
|
|
DXGI_ADAPTER_DESC1 desc;
|
2024-03-21 16:01:47 -03:00
|
|
|
_adapter->GetDesc1(&desc);
|
2024-03-18 15:41:46 -03:00
|
|
|
|
|
|
|
return static_cast<Uint>(desc.SubSysId);
|
|
|
|
}
|
|
|
|
|
|
|
|
Uint GraphicsAdapter::VendorId() const {
|
2024-04-21 16:06:22 -03:00
|
|
|
if (!_adapter) return 0;
|
|
|
|
|
2024-03-18 15:41:46 -03:00
|
|
|
DXGI_ADAPTER_DESC1 desc;
|
2024-03-21 16:01:47 -03:00
|
|
|
_adapter->GetDesc1(&desc);
|
2024-03-18 15:41:46 -03:00
|
|
|
|
|
|
|
return static_cast<Uint>(desc.VendorId);
|
|
|
|
}
|
|
|
|
|
2024-04-21 21:28:07 -03:00
|
|
|
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<SurfaceFormat>(f);
|
|
|
|
DXGI_FORMAT format = GraphicsAdapter::ToDXGI(currentSurface);
|
|
|
|
|
|
|
|
UINT num = 0;
|
|
|
|
pOutput->GetDisplayModeList(format, 0, &num, nullptr);
|
|
|
|
|
|
|
|
numModes += num;
|
|
|
|
}
|
|
|
|
|
|
|
|
pOutput->Release();
|
|
|
|
pOutput = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
return numModes;
|
|
|
|
}
|
|
|
|
|
2024-04-21 16:06:22 -03:00
|
|
|
UDisplayModeCollection GraphicsAdapter::SupportedDisplayModes() const {
|
|
|
|
if (!_adapter) return nullptr;
|
|
|
|
|
2024-03-18 15:41:46 -03:00
|
|
|
IDXGIOutput* pOutput = nullptr;
|
|
|
|
UINT numModes = 0;
|
|
|
|
UINT totalModes = 0;
|
2024-04-21 21:28:07 -03:00
|
|
|
|
|
|
|
const auto totalDisplay = getDisplayModesCount(_adapter);
|
|
|
|
std::vector<DXGI_MODE_DESC> buffer(totalDisplay);
|
2024-03-18 15:41:46 -03:00
|
|
|
|
2024-03-21 16:01:47 -03:00
|
|
|
if (_adapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) {
|
2024-03-18 15:41:46 -03:00
|
|
|
for (size_t f = 0; f < SURFACE_FORMAT_COUNT; ++f) {
|
|
|
|
const auto currentSurface = static_cast<SurfaceFormat>(f);
|
2024-04-21 16:06:22 -03:00
|
|
|
DXGI_FORMAT format = GraphicsAdapter::ToDXGI(currentSurface);
|
2024-03-18 15:41:46 -03:00
|
|
|
|
|
|
|
pOutput->GetDisplayModeList(format, 0, &numModes, nullptr);
|
|
|
|
|
|
|
|
if (numModes == 0)
|
2024-04-21 21:28:07 -03:00
|
|
|
continue;
|
2024-03-18 15:41:46 -03:00
|
|
|
|
|
|
|
pOutput->GetDisplayModeList(format, 0, &numModes, buffer.data() + totalModes);
|
|
|
|
|
|
|
|
totalModes += numModes;
|
2024-04-21 20:03:36 -03:00
|
|
|
}
|
|
|
|
}
|
2024-03-18 15:41:46 -03:00
|
|
|
|
2024-04-21 20:03:36 -03:00
|
|
|
if (!pOutput)
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
pOutput->Release();
|
|
|
|
pOutput = nullptr;
|
|
|
|
|
|
|
|
auto collection = uNew<DisplayModeCollection>();
|
|
|
|
DisplayMode currentDisplayMode;
|
|
|
|
std::vector<PDisplayMode> 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<DisplayModeScaling>(modedesc.Scaling);
|
|
|
|
description._scanlineOrdering = static_cast<DisplayModeScanlineOrder>(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<DisplayMode>();
|
|
|
|
pDisplay->_width = modedesc.Width;
|
|
|
|
pDisplay->_height = modedesc.Height;
|
|
|
|
pDisplay->_format = GraphicsAdapter::ToSurface(modedesc.Format);
|
|
|
|
pDisplay->_descriptions.push_back(description);
|
|
|
|
displayList.push_back(pDisplay);
|
|
|
|
}
|
2024-03-18 15:41:46 -03:00
|
|
|
}
|
|
|
|
|
2024-04-21 20:03:36 -03:00
|
|
|
collection->_displayModes = displayList;
|
|
|
|
|
|
|
|
return std::move(collection);
|
2024-04-21 19:55:50 -03:00
|
|
|
}
|
2024-03-18 15:41:46 -03:00
|
|
|
}
|