mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-22 16:54:27 +01:00
[dxgi] Removed SDL dependency from DxgiOutput
This commit is contained in:
parent
65d84dabfe
commit
2b5bb16334
@ -59,17 +59,12 @@ namespace dxvk {
|
|||||||
if (ppOutput == nullptr)
|
if (ppOutput == nullptr)
|
||||||
return DXGI_ERROR_INVALID_CALL;
|
return DXGI_ERROR_INVALID_CALL;
|
||||||
|
|
||||||
int numDisplays = SDL_GetNumVideoDisplays();
|
if (Output > 0)
|
||||||
|
|
||||||
if (numDisplays < 0) {
|
|
||||||
Logger::err("DxgiAdapter::EnumOutputs: Failed to query display count");
|
|
||||||
return DXGI_ERROR_DRIVER_INTERNAL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Output >= static_cast<uint32_t>(numDisplays))
|
|
||||||
return DXGI_ERROR_NOT_FOUND;
|
return DXGI_ERROR_NOT_FOUND;
|
||||||
|
|
||||||
*ppOutput = ref(new DxgiOutput(this, Output));
|
// TODO support multiple monitors
|
||||||
|
HMONITOR monitor = ::MonitorFromPoint({ 0, 0 }, MONITOR_DEFAULTTOPRIMARY);
|
||||||
|
*ppOutput = ref(new DxgiOutput(this, monitor));
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,13 +7,15 @@
|
|||||||
#include "dxgi_adapter.h"
|
#include "dxgi_adapter.h"
|
||||||
#include "dxgi_output.h"
|
#include "dxgi_output.h"
|
||||||
|
|
||||||
|
#include "../dxvk/dxvk_format.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
DxgiOutput::DxgiOutput(
|
DxgiOutput::DxgiOutput(
|
||||||
DxgiAdapter* adapter,
|
DxgiAdapter* adapter,
|
||||||
UINT display)
|
HMONITOR monitor)
|
||||||
: m_adapter (adapter),
|
: m_adapter(adapter),
|
||||||
m_display (display) {
|
m_monitor(monitor) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,34 +55,20 @@ namespace dxvk {
|
|||||||
if (pDesc == nullptr)
|
if (pDesc == nullptr)
|
||||||
return DXGI_ERROR_INVALID_CALL;
|
return DXGI_ERROR_INVALID_CALL;
|
||||||
|
|
||||||
// Display name, Windows requires wide chars
|
::MONITORINFOEX monInfo = { sizeof(monInfo) };
|
||||||
const char* displayName = SDL_GetDisplayName(m_display);
|
|
||||||
|
|
||||||
if (displayName == nullptr) {
|
if (!::GetMonitorInfo(m_monitor, &monInfo)) {
|
||||||
Logger::err("DxgiOutput::GetDesc: Failed to get display name");
|
Logger::err("DxgiOutput: Failed to query monitor info");
|
||||||
return DXGI_ERROR_DRIVER_INTERNAL_ERROR;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::memset(pDesc->DeviceName, 0, sizeof(pDesc->DeviceName));
|
std::memset(pDesc->DeviceName, 0, sizeof(pDesc->DeviceName));
|
||||||
std::mbstowcs(pDesc->DeviceName, displayName, _countof(pDesc->DeviceName) - 1);
|
std::mbstowcs(pDesc->DeviceName, monInfo.szDevice, _countof(pDesc->DeviceName) - 1);
|
||||||
|
|
||||||
// Current desktop rect of the display
|
pDesc->DesktopCoordinates = monInfo.rcMonitor;
|
||||||
SDL_Rect rect;
|
|
||||||
|
|
||||||
if (SDL_GetDisplayBounds(m_display, &rect)) {
|
|
||||||
Logger::err("DxgiOutput::GetDesc: Failed to get display bounds");
|
|
||||||
return DXGI_ERROR_DRIVER_INTERNAL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
pDesc->DesktopCoordinates.left = rect.x;
|
|
||||||
pDesc->DesktopCoordinates.top = rect.y;
|
|
||||||
pDesc->DesktopCoordinates.right = rect.x + rect.w;
|
|
||||||
pDesc->DesktopCoordinates.bottom = rect.y + rect.h;
|
|
||||||
|
|
||||||
// We don't have any info for these
|
|
||||||
pDesc->AttachedToDesktop = 1;
|
pDesc->AttachedToDesktop = 1;
|
||||||
pDesc->Rotation = DXGI_MODE_ROTATION_UNSPECIFIED;
|
pDesc->Rotation = DXGI_MODE_ROTATION_UNSPECIFIED;
|
||||||
pDesc->Monitor = nullptr;
|
pDesc->Monitor = m_monitor;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,88 +81,50 @@ namespace dxvk {
|
|||||||
if (pNumModes == nullptr)
|
if (pNumModes == nullptr)
|
||||||
return DXGI_ERROR_INVALID_CALL;
|
return DXGI_ERROR_INVALID_CALL;
|
||||||
|
|
||||||
// In order to check whether a display mode is 'centered' or
|
// Query monitor info to get the device name
|
||||||
// 'streched' in DXGI terms, we compare its size to the desktop
|
::MONITORINFOEX monInfo = { sizeof(monInfo) };
|
||||||
// 'mode. If they are the same, we consider the mode to be
|
|
||||||
// 'centered', which most games will prefer over 'streched'.
|
|
||||||
SDL_DisplayMode desktopMode;
|
|
||||||
|
|
||||||
if (SDL_GetDesktopDisplayMode(m_display, &desktopMode)) {
|
if (!::GetMonitorInfo(m_monitor, &monInfo)) {
|
||||||
Logger::err("DxgiOutput::GetDisplayModeList: Failed to list display modes");
|
Logger::err("DxgiOutput: Failed to query monitor info");
|
||||||
return DXGI_ERROR_DRIVER_INTERNAL_ERROR;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a list of suitable display modes. Because of the way DXGI
|
// Walk over all modes that the display supports and
|
||||||
// swapchains are handled by DXVK, we can ignore the format constraints
|
// return those that match the requested format etc.
|
||||||
// here and just pick whatever modes SDL returns for the current display.
|
DEVMODE devMode;
|
||||||
std::vector<DXGI_MODE_DESC> modes;
|
|
||||||
|
|
||||||
int numDisplayModes = SDL_GetNumDisplayModes(m_display);
|
uint32_t srcModeId = 0;
|
||||||
|
uint32_t dstModeId = 0;
|
||||||
|
|
||||||
if (numDisplayModes < 0) {
|
while (::EnumDisplaySettings(monInfo.szDevice, srcModeId++, &devMode)) {
|
||||||
Logger::err("DxgiOutput::GetDisplayModeList: Failed to list display modes");
|
// Skip interlaced modes altogether
|
||||||
return DXGI_ERROR_DRIVER_INTERNAL_ERROR;
|
if (devMode.dmDisplayFlags & DM_INTERLACED)
|
||||||
}
|
continue;
|
||||||
|
|
||||||
for (int i = 0; i < numDisplayModes; i++) {
|
// Skip modes with incompatible formats
|
||||||
SDL_DisplayMode currMode;
|
if (devMode.dmBitsPerPel != GetFormatBpp(EnumFormat))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (SDL_GetDisplayMode(m_display, i, &currMode)) {
|
// Write back display mode
|
||||||
Logger::err("DxgiOutput::GetDisplayModeList: Failed to list display modes");
|
if (pDesc != nullptr) {
|
||||||
return DXGI_ERROR_DRIVER_INTERNAL_ERROR;
|
if (dstModeId >= *pNumModes)
|
||||||
}
|
return DXGI_ERROR_MORE_DATA;
|
||||||
|
|
||||||
// We don't want duplicates, so we'll filter out modes
|
|
||||||
// with matching resolution and refresh rate.
|
|
||||||
bool hasMode = false;
|
|
||||||
|
|
||||||
for (int j = 0; j < i && !hasMode; j++) {
|
|
||||||
SDL_DisplayMode testMode;
|
|
||||||
|
|
||||||
if (SDL_GetDisplayMode(m_display, j, &testMode)) {
|
|
||||||
Logger::err("DxgiOutput::GetDisplayModeList: Failed to list display modes");
|
|
||||||
return DXGI_ERROR_DRIVER_INTERNAL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
hasMode = testMode.w == currMode.w
|
|
||||||
&& testMode.h == currMode.h
|
|
||||||
&& testMode.refresh_rate == currMode.refresh_rate;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert the SDL display mode to a DXGI display mode info
|
|
||||||
// structure and filter out any unwanted modes based on the
|
|
||||||
// supplied flags.
|
|
||||||
if (!hasMode) {
|
|
||||||
DXGI_MODE_DESC mode;
|
DXGI_MODE_DESC mode;
|
||||||
mode.Width = currMode.w;
|
mode.Width = devMode.dmPelsWidth;
|
||||||
mode.Height = currMode.h;
|
mode.Height = devMode.dmPelsHeight;
|
||||||
mode.RefreshRate.Numerator = currMode.refresh_rate;
|
mode.RefreshRate = { devMode.dmDisplayFrequency, 1 };
|
||||||
mode.RefreshRate.Denominator = 1;
|
|
||||||
mode.Format = EnumFormat;
|
mode.Format = EnumFormat;
|
||||||
mode.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE;
|
mode.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE;
|
||||||
mode.Scaling = DXGI_MODE_SCALING_CENTERED;
|
mode.Scaling = DXGI_MODE_SCALING_CENTERED;
|
||||||
modes.push_back(mode);
|
pDesc[dstModeId] = mode;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy list of display modes to the application-provided
|
dstModeId += 1;
|
||||||
// destination buffer. The buffer may not be appropriately
|
|
||||||
// sized by the time this is called.
|
|
||||||
if (pDesc != nullptr) {
|
|
||||||
for (uint32_t i = 0; i < modes.size() && i < *pNumModes; i++)
|
|
||||||
pDesc[i] = modes.at(i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the buffer is too small, we shall ask the application
|
*pNumModes = dstModeId;
|
||||||
// to query the display mode list again by returning the
|
|
||||||
// appropriate DXGI error code.
|
|
||||||
if ((pDesc == nullptr) || (modes.size() <= *pNumModes)) {
|
|
||||||
*pNumModes = modes.size();
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
} else {
|
|
||||||
return DXGI_ERROR_MORE_DATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -232,4 +182,10 @@ namespace dxvk {
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t DxgiOutput::GetFormatBpp(DXGI_FORMAT Format) const {
|
||||||
|
DxgiFormatInfo formatInfo = m_adapter->LookupFormat(Format, DxgiFormatMode::Any);
|
||||||
|
return imageFormatInfo(formatInfo.format)->elementSize * 8;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
DxgiOutput(
|
DxgiOutput(
|
||||||
DxgiAdapter* adapter,
|
DxgiAdapter* adapter,
|
||||||
UINT display);
|
HMONITOR monitor);
|
||||||
|
|
||||||
~DxgiOutput();
|
~DxgiOutput();
|
||||||
|
|
||||||
@ -66,8 +66,10 @@ namespace dxvk {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Com<DxgiAdapter> m_adapter;
|
Com<DxgiAdapter> m_adapter = nullptr;
|
||||||
UINT m_display;
|
HMONITOR m_monitor = nullptr;
|
||||||
|
|
||||||
|
uint32_t GetFormatBpp(DXGI_FORMAT Format) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -31,16 +31,6 @@ int WINAPI WinMain(HINSTANCE hInstance,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Com<IDXGIOutput> output;
|
|
||||||
|
|
||||||
for (UINT j = 0; adapter->EnumOutputs(j, &output) == S_OK; j++) {
|
|
||||||
std::vector<DXGI_MODE_DESC> modes;
|
|
||||||
|
|
||||||
HRESULT status = S_OK;
|
|
||||||
UINT displayModeCount = 0;
|
|
||||||
|
|
||||||
std::cout << str::format("Adapter ", i, ":") << std::endl;
|
|
||||||
|
|
||||||
DXGI_ADAPTER_DESC desc;
|
DXGI_ADAPTER_DESC desc;
|
||||||
|
|
||||||
if (adapter->GetDesc(&desc) != S_OK) {
|
if (adapter->GetDesc(&desc) != S_OK) {
|
||||||
@ -51,12 +41,39 @@ int WINAPI WinMain(HINSTANCE hInstance,
|
|||||||
std::array<char, 257> chars;
|
std::array<char, 257> chars;
|
||||||
std::wcstombs(chars.data(), desc.Description, chars.size() - 1);
|
std::wcstombs(chars.data(), desc.Description, chars.size() - 1);
|
||||||
|
|
||||||
|
std::cout << str::format("Adapter ", i, ":") << std::endl;
|
||||||
std::cout << str::format(" ", chars.data()) << std::endl;
|
std::cout << str::format(" ", chars.data()) << std::endl;
|
||||||
std::cout << str::format(" Vendor: ", desc.VendorId) << std::endl;
|
std::cout << str::format(" Vendor: ", desc.VendorId) << std::endl;
|
||||||
std::cout << str::format(" Device: ", desc.DeviceId) << std::endl;
|
std::cout << str::format(" Device: ", desc.DeviceId) << std::endl;
|
||||||
std::cout << str::format(" Dedicated RAM: ", desc.DedicatedVideoMemory) << std::endl;
|
std::cout << str::format(" Dedicated RAM: ", desc.DedicatedVideoMemory) << std::endl;
|
||||||
std::cout << str::format(" Shared RAM: ", desc.SharedSystemMemory) << std::endl;
|
std::cout << str::format(" Shared RAM: ", desc.SharedSystemMemory) << std::endl;
|
||||||
|
|
||||||
|
Com<IDXGIOutput> output;
|
||||||
|
|
||||||
|
for (UINT j = 0; adapter->EnumOutputs(j, &output) == S_OK; j++) {
|
||||||
|
std::vector<DXGI_MODE_DESC> modes;
|
||||||
|
|
||||||
|
DXGI_OUTPUT_DESC desc;
|
||||||
|
|
||||||
|
if (output->GetDesc(&desc) != S_OK) {
|
||||||
|
std::cerr << "Failed to get DXGI output info" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::array<char, 257> chars;
|
||||||
|
std::wcstombs(chars.data(), desc.DeviceName, chars.size() - 1);
|
||||||
|
|
||||||
|
std::cout << str::format(" Output ", j, ":") << std::endl;
|
||||||
|
std::cout << str::format(" ", chars.data()) << std::endl;
|
||||||
|
std::cout << str::format(" Coordinates: ",
|
||||||
|
desc.DesktopCoordinates.left, ",",
|
||||||
|
desc.DesktopCoordinates.top, ":",
|
||||||
|
desc.DesktopCoordinates.right - desc.DesktopCoordinates.left, "x",
|
||||||
|
desc.DesktopCoordinates.bottom - desc.DesktopCoordinates.top) << std::endl;
|
||||||
|
|
||||||
|
HRESULT status = S_OK;
|
||||||
|
UINT displayModeCount = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (output->GetDisplayModeList(
|
if (output->GetDisplayModeList(
|
||||||
DXGI_FORMAT_R8G8B8A8_UNORM,
|
DXGI_FORMAT_R8G8B8A8_UNORM,
|
||||||
@ -79,7 +96,6 @@ int WINAPI WinMain(HINSTANCE hInstance,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << str::format(" Output ", j, ":") << std::endl;
|
|
||||||
for (auto mode : modes) {
|
for (auto mode : modes) {
|
||||||
std::cout << str::format(" ",
|
std::cout << str::format(" ",
|
||||||
mode.Width, "x", mode.Height, " @ ",
|
mode.Width, "x", mode.Height, " @ ",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user