mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-04 07:24:15 +01:00
[dxgi] Add global HDR interop interface for NVAPI/AGS
This commit is contained in:
parent
143eb8c710
commit
1130512db5
@ -11,6 +11,9 @@ namespace dxvk {
|
||||
|
||||
Singleton<DxvkInstance> g_dxvkInstance;
|
||||
|
||||
std::mutex s_globalHDRStateMutex;
|
||||
DXVK_VK_GLOBAL_HDR_STATE s_globalHDRState{};
|
||||
|
||||
DxgiVkFactory::DxgiVkFactory(DxgiFactory* pFactory)
|
||||
: m_factory(pFactory) {
|
||||
|
||||
@ -47,6 +50,32 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
HRESULT STDMETHODCALLTYPE DxgiVkFactory::GetGlobalHDRState(
|
||||
DXGI_COLOR_SPACE_TYPE *pOutColorSpace,
|
||||
DXGI_HDR_METADATA_HDR10 *pOutMetadata) {
|
||||
std::unique_lock lock(s_globalHDRStateMutex);
|
||||
if (!s_globalHDRState.Serial)
|
||||
return S_FALSE;
|
||||
|
||||
*pOutColorSpace = s_globalHDRState.ColorSpace;
|
||||
*pOutMetadata = s_globalHDRState.Metadata.HDR10;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
HRESULT STDMETHODCALLTYPE DxgiVkFactory::SetGlobalHDRState(
|
||||
DXGI_COLOR_SPACE_TYPE ColorSpace,
|
||||
const DXGI_HDR_METADATA_HDR10 *pMetadata) {
|
||||
std::unique_lock lock(s_globalHDRStateMutex);
|
||||
static uint32_t s_GlobalHDRStateSerial = 0;
|
||||
|
||||
s_globalHDRState.Serial = ++s_GlobalHDRStateSerial;
|
||||
s_globalHDRState.ColorSpace = ColorSpace;
|
||||
s_globalHDRState.Metadata.Type = DXGI_HDR_METADATA_TYPE_HDR10;
|
||||
s_globalHDRState.Metadata.HDR10 = *pMetadata;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
DxgiFactory::DxgiFactory(UINT Flags)
|
||||
@ -127,7 +156,8 @@ namespace dxvk {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (riid == __uuidof(IDXGIVkInteropFactory)) {
|
||||
if (riid == __uuidof(IDXGIVkInteropFactory)
|
||||
|| riid == __uuidof(IDXGIVkInteropFactory1)) {
|
||||
*ppvObject = ref(&m_interop);
|
||||
return S_OK;
|
||||
}
|
||||
@ -519,4 +549,9 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
DXVK_VK_GLOBAL_HDR_STATE DxgiFactory::GlobalHDRState() {
|
||||
std::unique_lock lock(s_globalHDRStateMutex);
|
||||
return s_globalHDRState;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
|
||||
#include "dxgi_adapter.h"
|
||||
#include "dxgi_monitor.h"
|
||||
@ -12,7 +13,13 @@ namespace dxvk {
|
||||
|
||||
class DxgiFactory;
|
||||
|
||||
class DxgiVkFactory : public IDXGIVkInteropFactory {
|
||||
struct DXVK_VK_GLOBAL_HDR_STATE {
|
||||
uint32_t Serial;
|
||||
DXGI_COLOR_SPACE_TYPE ColorSpace;
|
||||
DXGI_VK_HDR_METADATA Metadata;
|
||||
};
|
||||
|
||||
class DxgiVkFactory : public IDXGIVkInteropFactory1 {
|
||||
|
||||
public:
|
||||
|
||||
@ -30,6 +37,14 @@ namespace dxvk {
|
||||
VkInstance* pInstance,
|
||||
PFN_vkGetInstanceProcAddr* ppfnVkGetInstanceProcAddr);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE GetGlobalHDRState(
|
||||
DXGI_COLOR_SPACE_TYPE *pOutColorSpace,
|
||||
DXGI_HDR_METADATA_HDR10 *pOutMetadata);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE SetGlobalHDRState(
|
||||
DXGI_COLOR_SPACE_TYPE ColorSpace,
|
||||
const DXGI_HDR_METADATA_HDR10 *pMetadata);
|
||||
|
||||
private:
|
||||
|
||||
DxgiFactory* m_factory;
|
||||
@ -173,6 +188,8 @@ namespace dxvk {
|
||||
DxgiMonitorInfo* GetMonitorInfo() {
|
||||
return &m_monitorInfo;
|
||||
}
|
||||
|
||||
DXVK_VK_GLOBAL_HDR_STATE GlobalHDRState();
|
||||
|
||||
private:
|
||||
|
||||
|
@ -443,12 +443,27 @@ IDXGIVkInteropFactory : public IUnknown {
|
||||
PFN_vkGetInstanceProcAddr* ppfnVkGetInstanceProcAddr) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief DXGI factory interface for Vulkan interop
|
||||
*/
|
||||
MIDL_INTERFACE("2a289dbd-2d0a-4a51-89f7-f2adce465cd6")
|
||||
IDXGIVkInteropFactory1 : public IDXGIVkInteropFactory {
|
||||
virtual HRESULT STDMETHODCALLTYPE GetGlobalHDRState(
|
||||
DXGI_COLOR_SPACE_TYPE *pOutColorSpace,
|
||||
DXGI_HDR_METADATA_HDR10 *ppOutMetadata) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE SetGlobalHDRState(
|
||||
DXGI_COLOR_SPACE_TYPE ColorSpace,
|
||||
const DXGI_HDR_METADATA_HDR10 *pMetadata) = 0;
|
||||
};
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
struct __declspec(uuid("907bf281-ea3c-43b4-a8e4-9f231107b4ff")) IDXGIDXVKAdapter;
|
||||
struct __declspec(uuid("92a5d77b-b6e1-420a-b260-fdd701272827")) IDXGIDXVKDevice;
|
||||
struct __declspec(uuid("c06a236f-5be3-448a-8943-89c611c0c2c1")) IDXGIVkMonitorInfo;
|
||||
struct __declspec(uuid("4c5e1b0d-b0c8-4131-bfd8-9b2476f7f408")) IDXGIVkInteropFactory;
|
||||
struct __declspec(uuid("2a289dbd-2d0a-4a51-89f7-f2adce465cd6")) IDXGIVkInteropFactory1;
|
||||
struct __declspec(uuid("3a6d8f2c-b0e8-4ab4-b4dc-4fd24891bfa5")) IDXGIVkInteropAdapter;
|
||||
struct __declspec(uuid("e2ef5fa5-dc21-4af7-90c4-f67ef6a09323")) IDXGIVkInteropDevice;
|
||||
struct __declspec(uuid("e2ef5fa5-dc21-4af7-90c4-f67ef6a09324")) IDXGIVkInteropDevice1;
|
||||
@ -462,6 +477,7 @@ __CRT_UUID_DECL(IDXGIDXVKAdapter, 0x907bf281,0xea3c,0x43b4,0xa8,0xe4,0x
|
||||
__CRT_UUID_DECL(IDXGIDXVKDevice, 0x92a5d77b,0xb6e1,0x420a,0xb2,0x60,0xfd,0xf7,0x01,0x27,0x28,0x27);
|
||||
__CRT_UUID_DECL(IDXGIVkMonitorInfo, 0xc06a236f,0x5be3,0x448a,0x89,0x43,0x89,0xc6,0x11,0xc0,0xc2,0xc1);
|
||||
__CRT_UUID_DECL(IDXGIVkInteropFactory, 0x4c5e1b0d,0xb0c8,0x4131,0xbf,0xd8,0x9b,0x24,0x76,0xf7,0xf4,0x08);
|
||||
__CRT_UUID_DECL(IDXGIVkInteropFactory1, 0x2a289dbd,0x2d0a,0x4a51,0x89,0xf7,0xf2,0xad,0xce,0x46,0x5c,0xd6);
|
||||
__CRT_UUID_DECL(IDXGIVkInteropAdapter, 0x3a6d8f2c,0xb0e8,0x4ab4,0xb4,0xdc,0x4f,0xd2,0x48,0x91,0xbf,0xa5);
|
||||
__CRT_UUID_DECL(IDXGIVkInteropDevice, 0xe2ef5fa5,0xdc21,0x4af7,0x90,0xc4,0xf6,0x7e,0xf6,0xa0,0x93,0x23);
|
||||
__CRT_UUID_DECL(IDXGIVkInteropDevice1, 0xe2ef5fa5,0xdc21,0x4af7,0x90,0xc4,0xf6,0x7e,0xf6,0xa0,0x93,0x24);
|
||||
|
@ -312,6 +312,8 @@ namespace dxvk {
|
||||
if (SyncInterval > 4)
|
||||
return DXGI_ERROR_INVALID_CALL;
|
||||
|
||||
UpdateGlobalHDRState();
|
||||
|
||||
std::lock_guard<dxvk::recursive_mutex> lockWin(m_lockWindow);
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
@ -862,4 +864,28 @@ namespace dxvk {
|
||||
m_monitorInfo->ReleaseMonitorData();
|
||||
}
|
||||
|
||||
void DxgiSwapChain::UpdateGlobalHDRState() {
|
||||
// Update the global HDR state if called from the legacy NVAPI
|
||||
// interfaces, etc.
|
||||
|
||||
auto state = m_factory->GlobalHDRState();
|
||||
if (m_globalHDRStateSerial != state.Serial) {
|
||||
SetColorSpace1(state.ColorSpace);
|
||||
|
||||
switch (state.Metadata.Type) {
|
||||
case DXGI_HDR_METADATA_TYPE_NONE:
|
||||
SetHDRMetaData(DXGI_HDR_METADATA_TYPE_NONE, 0, nullptr);
|
||||
break;
|
||||
case DXGI_HDR_METADATA_TYPE_HDR10:
|
||||
SetHDRMetaData(DXGI_HDR_METADATA_TYPE_HDR10, sizeof(state.Metadata.HDR10), reinterpret_cast<void*>(&state.Metadata.HDR10));
|
||||
break;
|
||||
default:
|
||||
Logger::err(str::format("DXGI: Unsupported HDR metadata type (global): ", state.Metadata.Type));
|
||||
break;
|
||||
}
|
||||
|
||||
m_globalHDRStateSerial = state.Serial;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -192,6 +192,8 @@ namespace dxvk {
|
||||
bool m_monitorHasOutput = true;
|
||||
bool m_frameStatisticsDisjoint = true;
|
||||
wsi::DxvkWindowState m_windowState;
|
||||
|
||||
uint32_t m_globalHDRStateSerial = 0;
|
||||
|
||||
HRESULT EnterFullscreenMode(
|
||||
IDXGIOutput1 *pTarget);
|
||||
@ -219,6 +221,8 @@ namespace dxvk {
|
||||
|
||||
void ReleaseMonitorData();
|
||||
|
||||
void UpdateGlobalHDRState();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user