1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-01-31 14:52:11 +01:00

[d3d9] Add ID3D9VkInteropTexture

Provides access to the backing resource of a D3D9 texture.
This commit is contained in:
Joshua Ashton 2022-09-21 20:28:09 +00:00 committed by Joshie
parent ae2465079e
commit ac13112619
9 changed files with 172 additions and 4 deletions

View File

@ -12,10 +12,11 @@ namespace dxvk {
D3D9CommonTexture::D3D9CommonTexture( D3D9CommonTexture::D3D9CommonTexture(
D3D9DeviceEx* pDevice, D3D9DeviceEx* pDevice,
IUnknown* pInterface,
const D3D9_COMMON_TEXTURE_DESC* pDesc, const D3D9_COMMON_TEXTURE_DESC* pDesc,
D3DRESOURCETYPE ResourceType, D3DRESOURCETYPE ResourceType,
HANDLE* pSharedHandle) HANDLE* pSharedHandle)
: m_device(pDevice), m_desc(*pDesc), m_type(ResourceType) { : m_device(pDevice), m_desc(*pDesc), m_type(ResourceType), m_d3d9Interop(pInterface, this) {
if (m_desc.Format == D3D9Format::Unknown) if (m_desc.Format == D3D9Format::Unknown)
m_desc.Format = (m_desc.Usage & D3DUSAGE_DEPTHSTENCIL) m_desc.Format = (m_desc.Usage & D3DUSAGE_DEPTHSTENCIL)
? D3D9Format::D32 ? D3D9Format::D32

View File

@ -4,6 +4,7 @@
#include "d3d9_util.h" #include "d3d9_util.h"
#include "d3d9_caps.h" #include "d3d9_caps.h"
#include "d3d9_mem.h" #include "d3d9_mem.h"
#include "d3d9_interop.h"
#include "../dxvk/dxvk_device.h" #include "../dxvk/dxvk_device.h"
@ -72,6 +73,7 @@ namespace dxvk {
D3D9CommonTexture( D3D9CommonTexture(
D3D9DeviceEx* pDevice, D3D9DeviceEx* pDevice,
IUnknown* pInterface,
const D3D9_COMMON_TEXTURE_DESC* pDesc, const D3D9_COMMON_TEXTURE_DESC* pDesc,
D3DRESOURCETYPE ResourceType, D3DRESOURCETYPE ResourceType,
HANDLE* pSharedHandle); HANDLE* pSharedHandle);
@ -474,6 +476,8 @@ namespace dxvk {
*/ */
void CreateBufferSubresource(UINT Subresource, bool Initialize); void CreateBufferSubresource(UINT Subresource, bool Initialize);
ID3D9VkInteropTexture* GetVkInterop() { return &m_d3d9Interop; }
private: private:
D3D9DeviceEx* m_device; D3D9DeviceEx* m_device;
@ -523,6 +527,8 @@ namespace dxvk {
std::array<D3DBOX, 6> m_dirtyBoxes; std::array<D3DBOX, 6> m_dirtyBoxes;
D3D9VkInteropTexture m_d3d9Interop;
Rc<DxvkImage> CreatePrimaryImage(D3DRESOURCETYPE ResourceType, bool TryOffscreenRT, HANDLE* pSharedHandle) const; Rc<DxvkImage> CreatePrimaryImage(D3DRESOURCETYPE ResourceType, bool TryOffscreenRT, HANDLE* pSharedHandle) const;
Rc<DxvkImage> CreateResolveImage() const; Rc<DxvkImage> CreateResolveImage() const;

View File

@ -30,8 +30,54 @@ ID3D9VkInteropInterface : public IUnknown {
VkPhysicalDevice* pPhysicalDevice) = 0; VkPhysicalDevice* pPhysicalDevice) = 0;
}; };
/**
* \brief D3D9 texture interface for Vulkan interop
*
* Provides access to the backing resource of a
* D3D9 texture.
*/
MIDL_INTERFACE("d56344f5-8d35-46fd-806d-94c351b472c1")
ID3D9VkInteropTexture : public IUnknown {
/**
* \brief Retrieves Vulkan image info
*
* Retrieves both the image handle as well as the image's
* properties. Any of the given pointers may be \c nullptr.
*
* If \c pInfo is not \c nullptr, the following rules apply:
* - \c pInfo->sType \e must be \c VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO
* - \c pInfo->pNext \e must be \c nullptr or point to a supported
* extension-specific structure (currently none)
* - \c pInfo->queueFamilyIndexCount must be the length of the
* \c pInfo->pQueueFamilyIndices array, in \c uint32_t units.
* - \c pInfo->pQueueFamilyIndices must point to a pre-allocated
* array of \c uint32_t of size \c pInfo->pQueueFamilyIndices.
*
* \note As of now, the sharing mode will always be
* \c VK_SHARING_MODE_EXCLUSIVE and no queue
* family indices will be written to the array.
*
* After the call, the structure pointed to by \c pInfo can
* be used to create an image with identical properties.
*
* If \c pLayout is not \c nullptr, it will receive the
* layout that the image will be in after flushing any
* outstanding commands on the device.
* \param [out] pHandle The image handle
* \param [out] pLayout Image layout
* \param [out] pInfo Image properties
* \returns \c S_OK on success, or \c D3DERR_INVALIDCALL
*/
virtual HRESULT STDMETHODCALLTYPE GetVulkanImageInfo(
VkImage* pHandle,
VkImageLayout* pLayout,
VkImageCreateInfo* pInfo) = 0;
};
#ifdef _MSC_VER #ifdef _MSC_VER
struct __declspec(uuid("3461a81b-ce41-485b-b6b5-fcf08ba6a6bd")) ID3D9VkInteropInterface; struct __declspec(uuid("3461a81b-ce41-485b-b6b5-fcf08ba6a6bd")) ID3D9VkInteropInterface;
struct __declspec(uuid("d56344f5-8d35-46fd-806d-94c351b472c1")) ID3D9VkInteropTexture;
#else #else
__CRT_UUID_DECL(ID3D9VkInteropInterface, 0x3461a81b,0xce41,0x485b,0xb6,0xb5,0xfc,0xf0,0x8b,0xa6,0xa6,0xbd); __CRT_UUID_DECL(ID3D9VkInteropInterface, 0x3461a81b,0xce41,0x485b,0xb6,0xb5,0xfc,0xf0,0x8b,0xa6,0xa6,0xbd);
__CRT_UUID_DECL(ID3D9VkInteropTexture, 0xd56344f5,0x8d35,0x46fd,0x80,0x6d,0x94,0xc3,0x51,0xb4,0x72,0xc1);
#endif #endif

View File

@ -1,5 +1,6 @@
#include "d3d9_interop.h" #include "d3d9_interop.h"
#include "d3d9_interface.h" #include "d3d9_interface.h"
#include "d3d9_common_texture.h"
namespace dxvk { namespace dxvk {
@ -46,4 +47,70 @@ namespace dxvk {
} }
} }
////////////////////////////////
// Texture Interop
///////////////////////////////
D3D9VkInteropTexture::D3D9VkInteropTexture(
IUnknown* pInterface,
D3D9CommonTexture* pTexture)
: m_interface(pInterface)
, m_texture (pTexture) {
}
D3D9VkInteropTexture::~D3D9VkInteropTexture() {
}
ULONG STDMETHODCALLTYPE D3D9VkInteropTexture::AddRef() {
return m_interface->AddRef();
}
ULONG STDMETHODCALLTYPE D3D9VkInteropTexture::Release() {
return m_interface->Release();
}
HRESULT STDMETHODCALLTYPE D3D9VkInteropTexture::QueryInterface(
REFIID riid,
void** ppvObject) {
return m_interface->QueryInterface(riid, ppvObject);
}
HRESULT STDMETHODCALLTYPE D3D9VkInteropTexture::GetVulkanImageInfo(
VkImage* pHandle,
VkImageLayout* pLayout,
VkImageCreateInfo* pInfo) {
const Rc<DxvkImage> image = m_texture->GetImage();
const DxvkImageCreateInfo& info = image->info();
if (pHandle != nullptr)
*pHandle = image->handle();
if (pLayout != nullptr)
*pLayout = info.layout;
if (pInfo != nullptr) {
// We currently don't support any extended structures
if (pInfo->sType != VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO
|| pInfo->pNext != nullptr)
return D3DERR_INVALIDCALL;
pInfo->flags = 0;
pInfo->imageType = info.type;
pInfo->format = info.format;
pInfo->extent = info.extent;
pInfo->mipLevels = info.mipLevels;
pInfo->arrayLayers = info.numLayers;
pInfo->samples = info.sampleCount;
pInfo->tiling = info.tiling;
pInfo->usage = info.usage;
pInfo->sharingMode = VK_SHARING_MODE_EXCLUSIVE;
pInfo->queueFamilyIndexCount = 0;
pInfo->initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
}
return S_OK;
}
} }

View File

@ -5,6 +5,7 @@
namespace dxvk { namespace dxvk {
class D3D9InterfaceEx; class D3D9InterfaceEx;
class D3D9CommonTexture;
class D3D9VkInteropInterface final : public ID3D9VkInteropInterface { class D3D9VkInteropInterface final : public ID3D9VkInteropInterface {
@ -36,4 +37,36 @@ namespace dxvk {
}; };
class D3D9VkInteropTexture final : public ID3D9VkInteropTexture {
public:
D3D9VkInteropTexture(
IUnknown* pInterface,
D3D9CommonTexture* pTexture);
~D3D9VkInteropTexture();
ULONG STDMETHODCALLTYPE AddRef();
ULONG STDMETHODCALLTYPE Release();
HRESULT STDMETHODCALLTYPE QueryInterface(
REFIID riid,
void** ppvObject);
HRESULT STDMETHODCALLTYPE GetVulkanImageInfo(
VkImage* pHandle,
VkImageLayout* pLayout,
VkImageCreateInfo* pInfo);
D3D9CommonTexture* GetCommonTexture() { return m_texture; }
private:
IUnknown* m_interface;
D3D9CommonTexture* m_texture;
};
} }

View File

@ -15,7 +15,7 @@ namespace dxvk {
HANDLE* pSharedHandle) HANDLE* pSharedHandle)
: D3D9SurfaceBase( : D3D9SurfaceBase(
pDevice, pDevice,
new D3D9CommonTexture( pDevice, pDesc, D3DRTYPE_SURFACE, pSharedHandle), new D3D9CommonTexture( pDevice, this, pDesc, D3DRTYPE_SURFACE, pSharedHandle),
0, 0, 0, 0,
nullptr, nullptr,
pContainer) { } pContainer) { }

View File

@ -27,6 +27,11 @@ namespace dxvk {
return S_OK; return S_OK;
} }
if (riid == __uuidof(ID3D9VkInteropTexture)) {
*ppvObject = ref(m_texture.GetVkInterop());
return S_OK;
}
Logger::warn("D3D9Texture2D::QueryInterface: Unknown interface query"); Logger::warn("D3D9Texture2D::QueryInterface: Unknown interface query");
Logger::warn(str::format(riid)); Logger::warn(str::format(riid));
return E_NOINTERFACE; return E_NOINTERFACE;
@ -118,6 +123,11 @@ namespace dxvk {
return S_OK; return S_OK;
} }
if (riid == __uuidof(ID3D9VkInteropTexture)) {
*ppvObject = ref(m_texture.GetVkInterop());
return S_OK;
}
Logger::warn("D3D9Texture3D::QueryInterface: Unknown interface query"); Logger::warn("D3D9Texture3D::QueryInterface: Unknown interface query");
Logger::warn(str::format(riid)); Logger::warn(str::format(riid));
return E_NOINTERFACE; return E_NOINTERFACE;
@ -203,6 +213,11 @@ namespace dxvk {
return S_OK; return S_OK;
} }
if (riid == __uuidof(ID3D9VkInteropTexture)) {
*ppvObject = ref(m_texture.GetVkInterop());
return S_OK;
}
Logger::warn("D3D9TextureCube::QueryInterface: Unknown interface query"); Logger::warn("D3D9TextureCube::QueryInterface: Unknown interface query");
Logger::warn(str::format(riid)); Logger::warn(str::format(riid));
return E_NOINTERFACE; return E_NOINTERFACE;

View File

@ -26,7 +26,7 @@ namespace dxvk {
D3DRESOURCETYPE ResourceType, D3DRESOURCETYPE ResourceType,
HANDLE* pSharedHandle) HANDLE* pSharedHandle)
: D3D9Resource<Base...> ( pDevice ) : D3D9Resource<Base...> ( pDevice )
, m_texture ( pDevice, pDesc, ResourceType, pSharedHandle ) , m_texture ( pDevice, this, pDesc, ResourceType, pSharedHandle )
, m_lod ( 0 ) { , m_lod ( 0 ) {
const uint32_t arraySlices = m_texture.Desc()->ArraySize; const uint32_t arraySlices = m_texture.Desc()->ArraySize;
const uint32_t mipLevels = m_texture.Desc()->MipLevels; const uint32_t mipLevels = m_texture.Desc()->MipLevels;

View File

@ -10,7 +10,7 @@ namespace dxvk {
const D3D9_COMMON_TEXTURE_DESC* pDesc) const D3D9_COMMON_TEXTURE_DESC* pDesc)
: D3D9VolumeBase( : D3D9VolumeBase(
pDevice, pDevice,
new D3D9CommonTexture( pDevice, pDesc, D3DRTYPE_VOLUMETEXTURE, nullptr ), new D3D9CommonTexture( pDevice, this, pDesc, D3DRTYPE_VOLUMETEXTURE, nullptr ),
0, 0, 0, 0,
nullptr, nullptr,
nullptr) { } nullptr) { }