dxvk/src/dxgi/dxgi_output.cpp

192 lines
5.4 KiB
C++
Raw Normal View History

2017-10-11 02:09:04 +01:00
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <string>
#include "dxgi_adapter.h"
#include "dxgi_output.h"
#include "../dxvk/dxvk_format.h"
2017-10-11 02:09:04 +01:00
namespace dxvk {
DxgiOutput::DxgiOutput(
DxgiAdapter* adapter,
HMONITOR monitor)
: m_adapter(adapter),
m_monitor(monitor) {
2017-11-26 13:01:41 +00:00
2017-10-11 02:09:04 +01:00
}
DxgiOutput::~DxgiOutput() {
2017-11-26 13:01:41 +00:00
2017-10-11 02:09:04 +01:00
}
2017-12-12 11:50:52 +00:00
HRESULT STDMETHODCALLTYPE DxgiOutput::QueryInterface(REFIID riid, void** ppvObject) {
2017-10-15 20:50:45 +01:00
COM_QUERY_IFACE(riid, ppvObject, IUnknown);
COM_QUERY_IFACE(riid, ppvObject, IDXGIObject);
2017-10-11 02:09:04 +01:00
COM_QUERY_IFACE(riid, ppvObject, IDXGIOutput);
Logger::warn("DxgiOutput::QueryInterface: Unknown interface query");
return E_NOINTERFACE;
}
2017-12-12 11:50:52 +00:00
HRESULT STDMETHODCALLTYPE DxgiOutput::GetParent(
2017-10-11 02:09:04 +01:00
REFIID riid,
void **ppParent) {
return m_adapter->QueryInterface(riid, ppParent);
}
2017-12-12 11:50:52 +00:00
HRESULT STDMETHODCALLTYPE DxgiOutput::FindClosestMatchingMode(
2017-10-11 02:09:04 +01:00
const DXGI_MODE_DESC *pModeToMatch,
DXGI_MODE_DESC *pClosestMatch,
IUnknown *pConcernedDevice) {
Logger::err("DxgiOutput::FindClosestMatchingMode: Not implemented");
return E_NOTIMPL;
}
2017-12-12 11:50:52 +00:00
HRESULT STDMETHODCALLTYPE DxgiOutput::GetDesc(DXGI_OUTPUT_DESC *pDesc) {
2017-10-11 02:09:04 +01:00
if (pDesc == nullptr)
return DXGI_ERROR_INVALID_CALL;
::MONITORINFOEX monInfo = { sizeof(monInfo) };
2017-10-11 02:09:04 +01:00
if (!::GetMonitorInfo(m_monitor, &monInfo)) {
Logger::err("DxgiOutput: Failed to query monitor info");
return E_FAIL;
2017-10-11 02:09:04 +01:00
}
std::memset(pDesc->DeviceName, 0, sizeof(pDesc->DeviceName));
std::mbstowcs(pDesc->DeviceName, monInfo.szDevice, _countof(pDesc->DeviceName) - 1);
2017-10-11 02:09:04 +01:00
pDesc->DesktopCoordinates = monInfo.rcMonitor;
2017-10-11 02:09:04 +01:00
pDesc->AttachedToDesktop = 1;
pDesc->Rotation = DXGI_MODE_ROTATION_UNSPECIFIED;
pDesc->Monitor = m_monitor;
2017-10-11 02:09:04 +01:00
return S_OK;
}
2017-12-12 11:50:52 +00:00
HRESULT STDMETHODCALLTYPE DxgiOutput::GetDisplayModeList(
2017-10-11 02:09:04 +01:00
DXGI_FORMAT EnumFormat,
UINT Flags,
UINT *pNumModes,
DXGI_MODE_DESC *pDesc) {
if (pNumModes == nullptr)
return DXGI_ERROR_INVALID_CALL;
// Query monitor info to get the device name
::MONITORINFOEX monInfo = { sizeof(monInfo) };
2017-10-11 02:09:04 +01:00
if (!::GetMonitorInfo(m_monitor, &monInfo)) {
Logger::err("DxgiOutput: Failed to query monitor info");
return E_FAIL;
}
2017-10-11 02:09:04 +01:00
// Walk over all modes that the display supports and
// return those that match the requested format etc.
DEVMODE devMode;
2017-10-11 02:09:04 +01:00
uint32_t srcModeId = 0;
uint32_t dstModeId = 0;
2017-10-11 02:09:04 +01:00
while (::EnumDisplaySettings(monInfo.szDevice, srcModeId++, &devMode)) {
// Skip interlaced modes altogether
if (devMode.dmDisplayFlags & DM_INTERLACED)
continue;
2017-10-11 02:09:04 +01:00
// Skip modes with incompatible formats
if (devMode.dmBitsPerPel != GetFormatBpp(EnumFormat))
continue;
2017-10-11 02:09:04 +01:00
// Write back display mode
if (pDesc != nullptr) {
if (dstModeId >= *pNumModes)
return DXGI_ERROR_MORE_DATA;
2017-10-11 02:09:04 +01:00
DXGI_MODE_DESC mode;
mode.Width = devMode.dmPelsWidth;
mode.Height = devMode.dmPelsHeight;
mode.RefreshRate = { devMode.dmDisplayFrequency, 1 };
mode.Format = EnumFormat;
mode.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE;
mode.Scaling = DXGI_MODE_SCALING_CENTERED;
pDesc[dstModeId] = mode;
2017-10-11 02:09:04 +01:00
}
dstModeId += 1;
2017-10-11 02:09:04 +01:00
}
*pNumModes = dstModeId;
return S_OK;
2017-10-11 02:09:04 +01:00
}
2017-12-12 11:50:52 +00:00
HRESULT STDMETHODCALLTYPE DxgiOutput::GetDisplaySurfaceData(IDXGISurface *pDestination) {
2017-10-11 02:09:04 +01:00
Logger::err("DxgiOutput::GetDisplaySurfaceData: Not implemented");
return E_NOTIMPL;
}
2017-12-12 11:50:52 +00:00
HRESULT STDMETHODCALLTYPE DxgiOutput::GetFrameStatistics(DXGI_FRAME_STATISTICS *pStats) {
2017-10-11 02:09:04 +01:00
Logger::err("DxgiOutput::GetFrameStatistics: Not implemented");
return E_NOTIMPL;
}
2017-12-12 11:50:52 +00:00
HRESULT STDMETHODCALLTYPE DxgiOutput::GetGammaControl(DXGI_GAMMA_CONTROL *pArray) {
2017-10-11 02:09:04 +01:00
Logger::err("DxgiOutput::GetGammaControl: Not implemented");
return E_NOTIMPL;
}
2017-12-12 11:50:52 +00:00
HRESULT STDMETHODCALLTYPE DxgiOutput::GetGammaControlCapabilities(DXGI_GAMMA_CONTROL_CAPABILITIES *pGammaCaps) {
2017-10-11 02:09:04 +01:00
Logger::err("DxgiOutput::GetGammaControlCapabilities: Not implemented");
return E_NOTIMPL;
}
2017-12-12 11:50:52 +00:00
void STDMETHODCALLTYPE DxgiOutput::ReleaseOwnership() {
2017-10-11 02:09:04 +01:00
Logger::warn("DxgiOutput::ReleaseOwnership: Stub");
}
2017-12-12 11:50:52 +00:00
HRESULT STDMETHODCALLTYPE DxgiOutput::SetDisplaySurface(IDXGISurface *pScanoutSurface) {
2017-10-11 02:09:04 +01:00
Logger::err("DxgiOutput::SetDisplaySurface: Not implemented");
return E_NOTIMPL;
}
2017-12-12 11:50:52 +00:00
HRESULT STDMETHODCALLTYPE DxgiOutput::SetGammaControl(const DXGI_GAMMA_CONTROL *pArray) {
2017-10-11 02:09:04 +01:00
Logger::err("DxgiOutput::SetGammaControl: Not implemented");
return E_NOTIMPL;
}
2017-12-12 11:50:52 +00:00
HRESULT STDMETHODCALLTYPE DxgiOutput::TakeOwnership(
2017-10-11 02:09:04 +01:00
IUnknown *pDevice,
BOOL Exclusive) {
Logger::warn("DxgiOutput::TakeOwnership: Stub");
return S_OK;
}
2017-12-12 11:50:52 +00:00
HRESULT STDMETHODCALLTYPE DxgiOutput::WaitForVBlank() {
2017-10-11 02:09:04 +01:00
Logger::warn("DxgiOutput::WaitForVBlank: Stub");
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;
}
2017-10-11 02:09:04 +01:00
}