1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-04 16:24:29 +01:00

[dxgi] Add global HDR interop interface for NVAPI/AGS

This commit is contained in:
Joshua Ashton 2023-08-17 23:30:37 +01:00 committed by Joshie
parent 143eb8c710
commit 1130512db5
5 changed files with 100 additions and 2 deletions

View File

@ -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;
}
}

View File

@ -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:

View File

@ -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);

View File

@ -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;
}
}
}

View File

@ -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();
};
}