diff --git a/src/dxgi/dxgi_factory.cpp b/src/dxgi/dxgi_factory.cpp index 43c0b043..695d22ab 100644 --- a/src/dxgi/dxgi_factory.cpp +++ b/src/dxgi/dxgi_factory.cpp @@ -4,9 +4,10 @@ namespace dxvk { DxgiFactory::DxgiFactory(UINT Flags) - : m_instance(new DxvkInstance()), - m_options (m_instance->config()), - m_flags (Flags) { + : m_instance (new DxvkInstance()), + m_monitorInfo (this), + m_options (m_instance->config()), + m_flags (Flags) { for (uint32_t i = 0; m_instance->enumAdapters(i) != nullptr; i++) m_instance->enumAdapters(i)->logAdapterInfo(); } @@ -33,6 +34,11 @@ namespace dxvk { *ppvObject = ref(this); return S_OK; } + + if (riid == __uuidof(IDXGIVkMonitorInfo)) { + *ppvObject = ref(&m_monitorInfo); + return S_OK; + } Logger::warn("DxgiFactory::QueryInterface: Unknown interface query"); Logger::warn(str::format(riid)); diff --git a/src/dxgi/dxgi_factory.h b/src/dxgi/dxgi_factory.h index bb245230..2044e6a3 100644 --- a/src/dxgi/dxgi_factory.h +++ b/src/dxgi/dxgi_factory.h @@ -3,6 +3,7 @@ #include #include "dxgi_adapter.h" +#include "dxgi_monitor.h" #include "dxgi_options.h" #include "../dxvk/dxvk_instance.h" @@ -119,6 +120,7 @@ namespace dxvk { private: Rc m_instance; + DxgiMonitorInfo m_monitorInfo; DxgiOptions m_options; UINT m_flags; diff --git a/src/dxgi/dxgi_monitor.cpp b/src/dxgi/dxgi_monitor.cpp index 9227b1a7..5491b0cc 100644 --- a/src/dxgi/dxgi_monitor.cpp +++ b/src/dxgi/dxgi_monitor.cpp @@ -6,6 +6,73 @@ namespace dxvk { std::unordered_map g_monitorData; + DxgiMonitorInfo::DxgiMonitorInfo(IUnknown* pParent) + : m_parent(pParent) { + + } + + + DxgiMonitorInfo::~DxgiMonitorInfo() { + + } + + + ULONG STDMETHODCALLTYPE DxgiMonitorInfo::AddRef() { + return m_parent->AddRef(); + } + + + ULONG STDMETHODCALLTYPE DxgiMonitorInfo::Release() { + return m_parent->Release(); + } + + + HRESULT STDMETHODCALLTYPE DxgiMonitorInfo::QueryInterface( + REFIID riid, + void** ppvObject) { + return m_parent->QueryInterface(riid, ppvObject); + } + + + HRESULT STDMETHODCALLTYPE DxgiMonitorInfo::InitMonitorData( + HMONITOR hMonitor, + const DXGI_VK_MONITOR_DATA* pData) { + if (!hMonitor || !pData) + return E_INVALIDARG; + + std::lock_guard lock(m_monitorMutex); + auto result = m_monitorData.insert({ hMonitor, *pData }); + + return result.second ? S_OK : E_INVALIDARG; + } + + + HRESULT STDMETHODCALLTYPE DxgiMonitorInfo::AcquireMonitorData( + HMONITOR hMonitor, + DXGI_VK_MONITOR_DATA** ppData) { + InitReturnPtr(ppData); + + if (!hMonitor || !ppData) + return E_INVALIDARG; + + m_monitorMutex.lock(); + + auto entry = m_monitorData.find(hMonitor); + if (entry == m_monitorData.end()) { + m_monitorMutex.unlock(); + return DXGI_ERROR_NOT_FOUND; + } + + *ppData = &entry->second; + return S_OK; + } + + + void STDMETHODCALLTYPE DxgiMonitorInfo::ReleaseMonitorData() { + m_monitorMutex.unlock(); + } + + uint32_t GetMonitorFormatBpp(DXGI_FORMAT Format) { switch (Format) { case DXGI_FORMAT_R8G8B8A8_UNORM: diff --git a/src/dxgi/dxgi_monitor.h b/src/dxgi/dxgi_monitor.h index 083dc35e..4f5b1fd5 100644 --- a/src/dxgi/dxgi_monitor.h +++ b/src/dxgi/dxgi_monitor.h @@ -9,6 +9,42 @@ namespace dxvk { class DxgiSwapChain; + class DxgiMonitorInfo : public IDXGIVkMonitorInfo { + + public: + + DxgiMonitorInfo(IUnknown* pParent); + + ~DxgiMonitorInfo(); + + ULONG STDMETHODCALLTYPE AddRef(); + + ULONG STDMETHODCALLTYPE Release(); + + HRESULT STDMETHODCALLTYPE QueryInterface( + REFIID riid, + void** ppvObject); + + HRESULT STDMETHODCALLTYPE InitMonitorData( + HMONITOR hMonitor, + const DXGI_VK_MONITOR_DATA* pData); + + HRESULT STDMETHODCALLTYPE AcquireMonitorData( + HMONITOR hMonitor, + DXGI_VK_MONITOR_DATA** ppData); + + void STDMETHODCALLTYPE ReleaseMonitorData(); + + private: + + IUnknown* m_parent; + + std::mutex m_monitorMutex; + std::unordered_map m_monitorData; + + }; + + /** * \brief Queries bits per pixel for a format *