From a3065fca8e636ab61a76597f3f7aaa507f7680b8 Mon Sep 17 00:00:00 2001 From: Andrew Eikum Date: Tue, 29 Dec 2020 15:39:04 -0600 Subject: [PATCH] [d3d11] Extend interop interfaces for OpenXR support --- src/d3d11/d3d11_device.cpp | 3 +- src/d3d11/d3d11_interop.cpp | 59 +++++++++++++++++++++++++++++++++++++ src/d3d11/d3d11_interop.h | 12 +++++++- src/d3d11/d3d11_texture.cpp | 27 +++++++++++++---- src/d3d11/d3d11_texture.h | 8 ++++- src/dxgi/dxgi_interfaces.h | 27 +++++++++++++++++ src/dxvk/dxvk_device.cpp | 6 ++++ src/dxvk/dxvk_device.h | 11 +++++++ 8 files changed, 145 insertions(+), 8 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 75b0632e..b7433873 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -2531,7 +2531,8 @@ namespace dxvk { return S_OK; } - if (riid == __uuidof(IDXGIVkInteropDevice)) { + if (riid == __uuidof(IDXGIVkInteropDevice) + || riid == __uuidof(IDXGIVkInteropDevice1)) { *ppvObject = ref(&m_d3d11Interop); return S_OK; } diff --git a/src/d3d11/d3d11_interop.cpp b/src/d3d11/d3d11_interop.cpp index 8bb39dd3..42dacfd1 100644 --- a/src/d3d11/d3d11_interop.cpp +++ b/src/d3d11/d3d11_interop.cpp @@ -104,4 +104,63 @@ namespace dxvk { m_device->GetDXVKDevice()->unlockSubmission(); } + + void STDMETHODCALLTYPE D3D11VkInterop::GetSubmissionQueue1( + VkQueue* pQueue, + uint32_t* pQueueIndex, + uint32_t* pQueueFamilyIndex) { + auto device = static_cast(m_device)->GetDXVKDevice(); + DxvkDeviceQueue queue = device->queues().graphics; + + if (pQueue != nullptr) + *pQueue = queue.queueHandle; + + if (pQueueIndex != nullptr) + *pQueueIndex = queue.queueIndex; + + if (pQueueFamilyIndex != nullptr) + *pQueueFamilyIndex = queue.queueFamily; + } + + HRESULT STDMETHODCALLTYPE D3D11VkInterop::CreateTexture2DFromVkImage( + const D3D11_TEXTURE2D_DESC1 *pDesc, + VkImage vkImage, + ID3D11Texture2D **ppTexture2D) { + + InitReturnPtr(ppTexture2D); + + if (!pDesc) + return E_INVALIDARG; + + D3D11_COMMON_TEXTURE_DESC desc; + desc.Width = pDesc->Width; + desc.Height = pDesc->Height; + desc.Depth = 1; + desc.MipLevels = pDesc->MipLevels; + desc.ArraySize = pDesc->ArraySize; + desc.Format = pDesc->Format; + desc.SampleDesc = pDesc->SampleDesc; + desc.Usage = pDesc->Usage; + desc.BindFlags = pDesc->BindFlags; + desc.CPUAccessFlags = pDesc->CPUAccessFlags; + desc.MiscFlags = pDesc->MiscFlags; + desc.TextureLayout = pDesc->TextureLayout; + + HRESULT hr = D3D11CommonTexture::NormalizeTextureProperties(&desc); + + if (FAILED(hr)) + return hr; + + if (!ppTexture2D) + return S_FALSE; + + try { + Com texture = new D3D11Texture2D(m_device, &desc, vkImage); + *ppTexture2D = texture.ref(); + return S_OK; + } catch (const DxvkError& e) { + Logger::err(e.message()); + return E_INVALIDARG; + } + } } \ No newline at end of file diff --git a/src/d3d11/d3d11_interop.h b/src/d3d11/d3d11_interop.h index a8facd53..48ee4c3b 100644 --- a/src/d3d11/d3d11_interop.h +++ b/src/d3d11/d3d11_interop.h @@ -8,7 +8,7 @@ namespace dxvk { class D3D11Device; - class D3D11VkInterop : public ComObject { + class D3D11VkInterop : public ComObject { public: @@ -47,6 +47,16 @@ namespace dxvk { void STDMETHODCALLTYPE ReleaseSubmissionQueue(); + void STDMETHODCALLTYPE GetSubmissionQueue1( + VkQueue* pQueue, + uint32_t* pQueueIndex, + uint32_t* pQueueFamilyIndex); + + HRESULT STDMETHODCALLTYPE CreateTexture2DFromVkImage( + const D3D11_TEXTURE2D_DESC1* pDesc, + VkImage vkImage, + ID3D11Texture2D** ppTexture2D); + private: IDXGIObject* m_container; diff --git a/src/d3d11/d3d11_texture.cpp b/src/d3d11/d3d11_texture.cpp index 08b0e68c..8cce0035 100644 --- a/src/d3d11/d3d11_texture.cpp +++ b/src/d3d11/d3d11_texture.cpp @@ -7,7 +7,8 @@ namespace dxvk { D3D11CommonTexture::D3D11CommonTexture( D3D11Device* pDevice, const D3D11_COMMON_TEXTURE_DESC* pDesc, - D3D11_RESOURCE_DIMENSION Dimension) + D3D11_RESOURCE_DIMENSION Dimension, + VkImage vkImage) : m_device(pDevice), m_desc(*pDesc) { DXGI_VK_FORMAT_MODE formatMode = GetFormatMode(); DXGI_VK_FORMAT_INFO formatInfo = m_device->LookupFormat(m_desc.Format, formatMode); @@ -179,7 +180,10 @@ namespace dxvk { | VK_MEMORY_PROPERTY_HOST_CACHED_BIT; } - m_image = m_device->GetDXVKDevice()->createImage(imageInfo, memoryProperties); + if (vkImage == VK_NULL_HANDLE) + m_image = m_device->GetDXVKDevice()->createImage(imageInfo, memoryProperties); + else + m_image = m_device->GetDXVKDevice()->createImageFromVkImage(imageInfo, vkImage); } @@ -775,7 +779,7 @@ namespace dxvk { D3D11Texture1D::D3D11Texture1D( D3D11Device* pDevice, const D3D11_COMMON_TEXTURE_DESC* pDesc) - : m_texture (pDevice, pDesc, D3D11_RESOURCE_DIMENSION_TEXTURE1D), + : m_texture (pDevice, pDesc, D3D11_RESOURCE_DIMENSION_TEXTURE1D, VK_NULL_HANDLE), m_interop (this, &m_texture), m_surface (this, &m_texture), m_resource(this), @@ -877,7 +881,20 @@ namespace dxvk { D3D11Texture2D::D3D11Texture2D( D3D11Device* pDevice, const D3D11_COMMON_TEXTURE_DESC* pDesc) - : m_texture (pDevice, pDesc, D3D11_RESOURCE_DIMENSION_TEXTURE2D), + : m_texture (pDevice, pDesc, D3D11_RESOURCE_DIMENSION_TEXTURE2D, VK_NULL_HANDLE), + m_interop (this, &m_texture), + m_surface (this, &m_texture), + m_resource(this), + m_d3d10 (this) { + + } + + + D3D11Texture2D::D3D11Texture2D( + D3D11Device* pDevice, + const D3D11_COMMON_TEXTURE_DESC* pDesc, + VkImage vkImage) + : m_texture (pDevice, pDesc, D3D11_RESOURCE_DIMENSION_TEXTURE2D, vkImage), m_interop (this, &m_texture), m_surface (this, &m_texture), m_resource(this), @@ -997,7 +1014,7 @@ namespace dxvk { D3D11Texture3D::D3D11Texture3D( D3D11Device* pDevice, const D3D11_COMMON_TEXTURE_DESC* pDesc) - : m_texture (pDevice, pDesc, D3D11_RESOURCE_DIMENSION_TEXTURE3D), + : m_texture (pDevice, pDesc, D3D11_RESOURCE_DIMENSION_TEXTURE3D, VK_NULL_HANDLE), m_interop (this, &m_texture), m_resource(this), m_d3d10 (this) { diff --git a/src/d3d11/d3d11_texture.h b/src/d3d11/d3d11_texture.h index ca41da40..635b3c40 100644 --- a/src/d3d11/d3d11_texture.h +++ b/src/d3d11/d3d11_texture.h @@ -62,7 +62,8 @@ namespace dxvk { D3D11CommonTexture( D3D11Device* pDevice, const D3D11_COMMON_TEXTURE_DESC* pDesc, - D3D11_RESOURCE_DIMENSION Dimension); + D3D11_RESOURCE_DIMENSION Dimension, + VkImage vkImage); ~D3D11CommonTexture(); @@ -421,6 +422,11 @@ namespace dxvk { D3D11Texture2D( D3D11Device* pDevice, const D3D11_COMMON_TEXTURE_DESC* pDesc); + + D3D11Texture2D( + D3D11Device* pDevice, + const D3D11_COMMON_TEXTURE_DESC* pDesc, + VkImage vkImage); ~D3D11Texture2D(); diff --git a/src/dxgi/dxgi_interfaces.h b/src/dxgi/dxgi_interfaces.h index 15fc0d04..cd7f992a 100644 --- a/src/dxgi/dxgi_interfaces.h +++ b/src/dxgi/dxgi_interfaces.h @@ -287,6 +287,31 @@ IDXGIVkInteropDevice : public IUnknown { virtual void STDMETHODCALLTYPE ReleaseSubmissionQueue() = 0; }; +struct D3D11_TEXTURE2D_DESC1; +class ID3D11Texture2D; + +/** + * \brief See IDXGIVkInteropDevice. + */ +MIDL_INTERFACE("e2ef5fa5-dc21-4af7-90c4-f67ef6a09324") +IDXGIVkInteropDevice1 : public IDXGIVkInteropDevice { + /** + * \brief Queries the rendering queue used by DXVK + * + * \param [out] pQueue The Vulkan queue handle + * \param [out] pQueueIndex Queue index + * \param [out] pQueueFamilyIndex Queue family index + */ + virtual void STDMETHODCALLTYPE GetSubmissionQueue1( + VkQueue* pQueue, + uint32_t* pQueueIndex, + uint32_t* pQueueFamilyIndex) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateTexture2DFromVkImage( + const D3D11_TEXTURE2D_DESC1 *pDesc, + VkImage vkImage, + ID3D11Texture2D **ppTexture2D) = 0; +}; /** * \brief DXGI adapter interface for Vulkan interop @@ -332,6 +357,7 @@ struct __declspec(uuid("92a5d77b-b6e1-420a-b260-fdd701272827")) IDXGIDXVKDevice; struct __declspec(uuid("c06a236f-5be3-448a-8943-89c611c0c2c1")) IDXGIVkMonitorInfo; 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; struct __declspec(uuid("5546cf8c-77e7-4341-b05d-8d4d5000e77d")) IDXGIVkInteropSurface; struct __declspec(uuid("104001a6-7f36-4957-b932-86ade9567d91")) IDXGIVkSwapChain; struct __declspec(uuid("53cb4ff0-c25a-4164-a891-0e83db0a7aac")) IWineDXGISwapChainFactory; @@ -341,6 +367,7 @@ __CRT_UUID_DECL(IDXGIDXVKDevice, 0x92a5d77b,0xb6e1,0x420a,0xb2,0x60,0x __CRT_UUID_DECL(IDXGIVkMonitorInfo, 0xc06a236f,0x5be3,0x448a,0x89,0x43,0x89,0xc6,0x11,0xc0,0xc2,0xc1); __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); __CRT_UUID_DECL(IDXGIVkInteropSurface, 0x5546cf8c,0x77e7,0x4341,0xb0,0x5d,0x8d,0x4d,0x50,0x00,0xe7,0x7d); __CRT_UUID_DECL(IDXGIVkSwapChain, 0x104001a6,0x7f36,0x4957,0xb9,0x32,0x86,0xad,0xe9,0x56,0x7d,0x91); __CRT_UUID_DECL(IWineDXGISwapChainFactory, 0x53cb4ff0,0xc25a,0x4164,0xa8,0x91,0x0e,0x83,0xdb,0x0a,0x7a,0xac); diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index c3610618..7678c5c0 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -142,6 +142,12 @@ namespace dxvk { } + Rc DxvkDevice::createImageFromVkImage( + const DxvkImageCreateInfo& createInfo, + VkImage image) { + return new DxvkImage(m_vkd, createInfo, image); + } + Rc DxvkDevice::createImageView( const Rc& image, const DxvkImageViewCreateInfo& createInfo) { diff --git a/src/dxvk/dxvk_device.h b/src/dxvk/dxvk_device.h index e2960b10..7ff07b43 100644 --- a/src/dxvk/dxvk_device.h +++ b/src/dxvk/dxvk_device.h @@ -304,6 +304,17 @@ namespace dxvk { Rc createImage( const DxvkImageCreateInfo& createInfo, VkMemoryPropertyFlags memoryType); + + /** + * \brief Creates an image object for an existing VkImage + * + * \param [in] createInfo Image create info + * \param [in] image Vulkan image to wrap + * \returns The image object + */ + Rc createImageFromVkImage( + const DxvkImageCreateInfo& createInfo, + VkImage image); /** * \brief Creates an image view