Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/doitsujin/dxvk.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Ashton <joshua@froggi.es>2023-08-18 01:30:37 +0300
committerJoshua Ashton <joshua@froggi.es>2023-08-19 00:37:57 +0300
commit0d63d81253d2122581ce7b80328442ca50c3688e (patch)
tree52197b205df7660a1fc04420430489ec8803f8c6
parent143eb8c71020a34a6094828f37335fd8d5adf255 (diff)
[dxgi] Add global HDR interop interface for NVAPI/AGSglobal-hdr
-rw-r--r--src/dxgi/dxgi_factory.cpp37
-rw-r--r--src/dxgi/dxgi_factory.h19
-rw-r--r--src/dxgi/dxgi_interfaces.h16
-rw-r--r--src/dxgi/dxgi_swapchain.cpp26
-rw-r--r--src/dxgi/dxgi_swapchain.h4
5 files changed, 100 insertions, 2 deletions
diff --git a/src/dxgi/dxgi_factory.cpp b/src/dxgi/dxgi_factory.cpp
index 877cef19..84b3d404 100644
--- a/src/dxgi/dxgi_factory.cpp
+++ b/src/dxgi/dxgi_factory.cpp
@@ -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;
+ }
+
}
diff --git a/src/dxgi/dxgi_factory.h b/src/dxgi/dxgi_factory.h
index 81b51143..96a4410c 100644
--- a/src/dxgi/dxgi_factory.h
+++ b/src/dxgi/dxgi_factory.h
@@ -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:
diff --git a/src/dxgi/dxgi_interfaces.h b/src/dxgi/dxgi_interfaces.h
index e1fc1250..3735447f 100644
--- a/src/dxgi/dxgi_interfaces.h
+++ b/src/dxgi/dxgi_interfaces.h
@@ -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);
diff --git a/src/dxgi/dxgi_swapchain.cpp b/src/dxgi/dxgi_swapchain.cpp
index fee7cf7b..ba65a86a 100644
--- a/src/dxgi/dxgi_swapchain.cpp
+++ b/src/dxgi/dxgi_swapchain.cpp
@@ -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;
+ }
+ }
+
}
diff --git a/src/dxgi/dxgi_swapchain.h b/src/dxgi/dxgi_swapchain.h
index b87b71e4..7702f879 100644
--- a/src/dxgi/dxgi_swapchain.h
+++ b/src/dxgi/dxgi_swapchain.h
@@ -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();
+
};
}