mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-02 13:29:14 +01:00
[d3d11] Add support for shared ID3D11Texture2D resources.
This commit is contained in:
parent
f9d94c82a5
commit
48046e009c
@ -23,6 +23,8 @@
|
||||
#include "d3d11_texture.h"
|
||||
#include "d3d11_video.h"
|
||||
|
||||
#include "../util/util_shared_res.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
constexpr uint32_t D3D11DXGIDevice::DefaultFrameLatency;
|
||||
@ -207,7 +209,7 @@ namespace dxvk {
|
||||
return S_FALSE;
|
||||
|
||||
try {
|
||||
Com<D3D11Texture2D> texture = new D3D11Texture2D(this, &desc);
|
||||
Com<D3D11Texture2D> texture = new D3D11Texture2D(this, &desc, nullptr);
|
||||
m_initializer->InitTexture(texture->GetCommonTexture(), pInitialData);
|
||||
*ppTexture2D = texture.ref();
|
||||
return S_OK;
|
||||
@ -1388,10 +1390,8 @@ namespace dxvk {
|
||||
HANDLE hResource,
|
||||
REFIID ReturnedInterface,
|
||||
void** ppResource) {
|
||||
InitReturnPtr(ppResource);
|
||||
|
||||
Logger::err("D3D11Device::OpenSharedResource: Not implemented");
|
||||
return E_NOTIMPL;
|
||||
return OpenSharedResourceGeneric<true>(
|
||||
hResource, ReturnedInterface, ppResource);
|
||||
}
|
||||
|
||||
|
||||
@ -1399,10 +1399,8 @@ namespace dxvk {
|
||||
HANDLE hResource,
|
||||
REFIID ReturnedInterface,
|
||||
void** ppResource) {
|
||||
InitReturnPtr(ppResource);
|
||||
|
||||
Logger::err("D3D11Device::OpenSharedResource1: Not implemented");
|
||||
return E_NOTIMPL;
|
||||
return OpenSharedResourceGeneric<false>(
|
||||
hResource, ReturnedInterface, ppResource);
|
||||
}
|
||||
|
||||
|
||||
@ -2260,6 +2258,61 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
template<bool IsKmtHandle>
|
||||
HRESULT D3D11Device::OpenSharedResourceGeneric(
|
||||
HANDLE hResource,
|
||||
REFIID ReturnedInterface,
|
||||
void** ppResource) {
|
||||
InitReturnPtr(ppResource);
|
||||
|
||||
if (ppResource == nullptr)
|
||||
return S_FALSE;
|
||||
|
||||
HANDLE ntHandle = IsKmtHandle ? openKmtHandle(hResource) : hResource;
|
||||
|
||||
if (ntHandle == INVALID_HANDLE_VALUE) {
|
||||
Logger::warn(str::format("D3D11Device::OpenSharedResourceGeneric: Handle not found: ", hResource));
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
DxvkSharedTextureMetadata metadata;
|
||||
bool ret = getSharedMetadata(ntHandle, &metadata, sizeof(metadata), NULL);
|
||||
|
||||
if (IsKmtHandle)
|
||||
::CloseHandle(ntHandle);
|
||||
|
||||
if (!ret) {
|
||||
Logger::warn("D3D11Device::OpenSharedResourceGeneric: Failed to get shared resource info for a texture");
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
D3D11_COMMON_TEXTURE_DESC d3d11Desc;
|
||||
d3d11Desc.Width = metadata.Width;
|
||||
d3d11Desc.Height = metadata.Height;
|
||||
d3d11Desc.Depth = 1,
|
||||
d3d11Desc.MipLevels = metadata.MipLevels;
|
||||
d3d11Desc.ArraySize = metadata.ArraySize;
|
||||
d3d11Desc.Format = metadata.Format;
|
||||
d3d11Desc.SampleDesc = metadata.SampleDesc;
|
||||
d3d11Desc.Usage = metadata.Usage;
|
||||
d3d11Desc.BindFlags = metadata.BindFlags;
|
||||
d3d11Desc.CPUAccessFlags = metadata.CPUAccessFlags;
|
||||
d3d11Desc.MiscFlags = metadata.MiscFlags;
|
||||
d3d11Desc.TextureLayout = metadata.TextureLayout;
|
||||
|
||||
// Only 2D textures may be shared
|
||||
try {
|
||||
const Com<D3D11Texture2D> texture = new D3D11Texture2D(this, &d3d11Desc, hResource);
|
||||
texture->QueryInterface(ReturnedInterface, ppResource);
|
||||
return S_OK;
|
||||
}
|
||||
catch (const DxvkError& e) {
|
||||
Logger::err(e.message());
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<typename Void>
|
||||
void D3D11Device::CopySubresourceData(
|
||||
Void* pData,
|
||||
|
@ -473,6 +473,12 @@ namespace dxvk {
|
||||
VkFormat Format,
|
||||
VkImageType Type) const;
|
||||
|
||||
template<bool IsKmtHandle>
|
||||
HRESULT OpenSharedResourceGeneric(
|
||||
HANDLE hResource,
|
||||
REFIID ReturnedInterface,
|
||||
void** ppResource);
|
||||
|
||||
uint32_t GetViewPlaneIndex(
|
||||
ID3D11Resource* pResource,
|
||||
DXGI_FORMAT ViewFormat);
|
||||
|
@ -81,9 +81,17 @@ namespace dxvk {
|
||||
|
||||
HRESULT STDMETHODCALLTYPE D3D11DXGIResource::GetSharedHandle(
|
||||
HANDLE* pSharedHandle) {
|
||||
InitReturnPtr(pSharedHandle);
|
||||
Logger::err("D3D11DXGIResource::GetSharedHandle: Stub");
|
||||
return E_NOTIMPL;
|
||||
auto texture = GetCommonTexture(m_resource);
|
||||
if (texture == nullptr || pSharedHandle == nullptr)
|
||||
return E_INVALIDARG;
|
||||
|
||||
HANDLE kmtHandle = texture->GetImage()->sharedHandle();
|
||||
|
||||
if (kmtHandle == INVALID_HANDLE_VALUE)
|
||||
return E_INVALIDARG;
|
||||
|
||||
*pSharedHandle = kmtHandle;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -132,9 +140,20 @@ namespace dxvk {
|
||||
DWORD dwAccess,
|
||||
LPCWSTR lpName,
|
||||
HANDLE* pHandle) {
|
||||
InitReturnPtr(pHandle);
|
||||
Logger::err("D3D11DXGIResource::CreateSharedHandle: Stub");
|
||||
return E_NOTIMPL;
|
||||
auto texture = GetCommonTexture(m_resource);
|
||||
if (texture == nullptr || pHandle == nullptr)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (lpName)
|
||||
Logger::warn("Naming shared resources not supported");
|
||||
|
||||
HANDLE handle = texture->GetImage()->sharedHandle();
|
||||
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
return E_INVALIDARG;
|
||||
|
||||
*pHandle = handle;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -235,4 +254,4 @@ namespace dxvk {
|
||||
return ResourceReleasePrivate(pResource, dim);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,8 @@
|
||||
#include "d3d11_gdi.h"
|
||||
#include "d3d11_texture.h"
|
||||
|
||||
#include "../util/util_shared_res.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
D3D11CommonTexture::D3D11CommonTexture(
|
||||
@ -10,7 +12,8 @@ namespace dxvk {
|
||||
const D3D11_COMMON_TEXTURE_DESC* pDesc,
|
||||
D3D11_RESOURCE_DIMENSION Dimension,
|
||||
DXGI_USAGE DxgiUsage,
|
||||
VkImage vkImage)
|
||||
VkImage vkImage,
|
||||
HANDLE hSharedHandle)
|
||||
: m_interface(pInterface), m_device(pDevice), m_dimension(Dimension), m_desc(*pDesc), m_dxgiUsage(DxgiUsage) {
|
||||
DXGI_VK_FORMAT_MODE formatMode = GetFormatMode();
|
||||
DXGI_VK_FORMAT_INFO formatInfo = m_device->LookupFormat(m_desc.Format, formatMode);
|
||||
@ -38,6 +41,22 @@ namespace dxvk {
|
||||
imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
imageInfo.shared = vkImage != VK_NULL_HANDLE;
|
||||
|
||||
// Normalise hSharedhandle to INVALID_HANDLE_VALUE to allow passing in nullptr
|
||||
if (hSharedHandle == nullptr)
|
||||
hSharedHandle = INVALID_HANDLE_VALUE;
|
||||
|
||||
if (m_desc.MiscFlags & (D3D11_RESOURCE_MISC_SHARED|D3D11_RESOURCE_MISC_SHARED_NTHANDLE)) {
|
||||
if (m_desc.MiscFlags & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX)
|
||||
Logger::warn("D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX: not supported.");
|
||||
|
||||
imageInfo.shared = true;
|
||||
imageInfo.sharing.mode = hSharedHandle == INVALID_HANDLE_VALUE ? DxvkSharedHandleMode::Export : DxvkSharedHandleMode::Import;
|
||||
imageInfo.sharing.type = m_desc.MiscFlags & D3D11_RESOURCE_MISC_SHARED_NTHANDLE
|
||||
? VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
|
||||
: VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT;
|
||||
imageInfo.sharing.handle = hSharedHandle;
|
||||
}
|
||||
|
||||
if (!pDevice->GetOptions()->disableMsaa)
|
||||
DecodeSampleCount(m_desc.SampleDesc.Count, &imageInfo.sampleCount);
|
||||
|
||||
@ -175,7 +194,7 @@ namespace dxvk {
|
||||
// We must keep LINEAR images in GENERAL layout, but we
|
||||
// can choose a better layout for the image based on how
|
||||
// it is going to be used by the game.
|
||||
if (imageInfo.tiling == VK_IMAGE_TILING_OPTIMAL && !isMultiPlane)
|
||||
if (imageInfo.tiling == VK_IMAGE_TILING_OPTIMAL && !isMultiPlane && imageInfo.sharing.mode == DxvkSharedHandleMode::None)
|
||||
imageInfo.layout = OptimizeLayout(imageInfo.usage);
|
||||
|
||||
// For some formats, we need to enable sampled and/or
|
||||
@ -210,6 +229,9 @@ namespace dxvk {
|
||||
m_image = m_device->GetDXVKDevice()->createImage(imageInfo, memoryProperties);
|
||||
else
|
||||
m_image = m_device->GetDXVKDevice()->createImageFromVkImage(imageInfo, vkImage);
|
||||
|
||||
if (imageInfo.sharing.mode == DxvkSharedHandleMode::Export)
|
||||
ExportImageInfo();
|
||||
}
|
||||
|
||||
|
||||
@ -410,7 +432,7 @@ namespace dxvk {
|
||||
|
||||
// Use the maximum possible mip level count if the supplied
|
||||
// mip level count is either unspecified (0) or invalid
|
||||
const uint32_t maxMipLevelCount = pDesc->SampleDesc.Count <= 1
|
||||
const uint32_t maxMipLevelCount = (pDesc->SampleDesc.Count <= 1)
|
||||
? util::computeMipLevelCount({ pDesc->Width, pDesc->Height, pDesc->Depth })
|
||||
: 1u;
|
||||
|
||||
@ -591,6 +613,37 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void D3D11CommonTexture::ExportImageInfo() {
|
||||
HANDLE hSharedHandle;
|
||||
|
||||
if (m_desc.MiscFlags & D3D11_RESOURCE_MISC_SHARED)
|
||||
hSharedHandle = openKmtHandle( m_image->sharedHandle() );
|
||||
else
|
||||
hSharedHandle = m_image->sharedHandle();
|
||||
|
||||
DxvkSharedTextureMetadata metadata;
|
||||
|
||||
metadata.Width = m_desc.Width;
|
||||
metadata.Height = m_desc.Height;
|
||||
metadata.MipLevels = m_desc.MipLevels;
|
||||
metadata.ArraySize = m_desc.ArraySize;
|
||||
metadata.Format = m_desc.Format;
|
||||
metadata.SampleDesc = m_desc.SampleDesc;
|
||||
metadata.Usage = m_desc.Usage;
|
||||
metadata.BindFlags = m_desc.BindFlags;
|
||||
metadata.CPUAccessFlags = m_desc.CPUAccessFlags;
|
||||
metadata.MiscFlags = m_desc.MiscFlags;
|
||||
metadata.TextureLayout = m_desc.TextureLayout;
|
||||
|
||||
if (hSharedHandle == INVALID_HANDLE_VALUE || !setSharedMetadata(hSharedHandle, &metadata, sizeof(metadata))) {
|
||||
Logger::warn("D3D11: Failed to write shared resource info for a texture");
|
||||
}
|
||||
|
||||
if (hSharedHandle != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(hSharedHandle);
|
||||
}
|
||||
|
||||
|
||||
D3D11CommonTexture::MappedBuffer D3D11CommonTexture::CreateMappedBuffer(UINT MipLevel) const {
|
||||
const DxvkFormatInfo* formatInfo = imageFormatInfo(
|
||||
m_device->LookupPackedFormat(m_desc.Format, GetFormatMode()).Format);
|
||||
@ -932,7 +985,7 @@ namespace dxvk {
|
||||
D3D11Device* pDevice,
|
||||
const D3D11_COMMON_TEXTURE_DESC* pDesc)
|
||||
: D3D11DeviceChild<ID3D11Texture1D>(pDevice),
|
||||
m_texture (this, pDevice, pDesc, D3D11_RESOURCE_DIMENSION_TEXTURE1D, 0, VK_NULL_HANDLE),
|
||||
m_texture (this, pDevice, pDesc, D3D11_RESOURCE_DIMENSION_TEXTURE1D, 0, VK_NULL_HANDLE, nullptr),
|
||||
m_interop (this, &m_texture),
|
||||
m_surface (this, &m_texture),
|
||||
m_resource(this),
|
||||
@ -1028,9 +1081,10 @@ namespace dxvk {
|
||||
// D 3 D 1 1 T E X T U R E 2 D
|
||||
D3D11Texture2D::D3D11Texture2D(
|
||||
D3D11Device* pDevice,
|
||||
const D3D11_COMMON_TEXTURE_DESC* pDesc)
|
||||
const D3D11_COMMON_TEXTURE_DESC* pDesc,
|
||||
HANDLE hSharedHandle)
|
||||
: D3D11DeviceChild<ID3D11Texture2D1>(pDevice),
|
||||
m_texture (this, pDevice, pDesc, D3D11_RESOURCE_DIMENSION_TEXTURE2D, 0, VK_NULL_HANDLE),
|
||||
m_texture (this, pDevice, pDesc, D3D11_RESOURCE_DIMENSION_TEXTURE2D, 0, VK_NULL_HANDLE, hSharedHandle),
|
||||
m_interop (this, &m_texture),
|
||||
m_surface (this, &m_texture),
|
||||
m_resource(this),
|
||||
@ -1045,7 +1099,7 @@ namespace dxvk {
|
||||
DXGI_USAGE DxgiUsage,
|
||||
VkImage vkImage)
|
||||
: D3D11DeviceChild<ID3D11Texture2D1>(pDevice),
|
||||
m_texture (this, pDevice, pDesc, D3D11_RESOURCE_DIMENSION_TEXTURE2D, DxgiUsage, vkImage),
|
||||
m_texture (this, pDevice, pDesc, D3D11_RESOURCE_DIMENSION_TEXTURE2D, DxgiUsage, vkImage, nullptr),
|
||||
m_interop (this, &m_texture),
|
||||
m_surface (this, &m_texture),
|
||||
m_resource(this),
|
||||
@ -1161,7 +1215,7 @@ namespace dxvk {
|
||||
D3D11Device* pDevice,
|
||||
const D3D11_COMMON_TEXTURE_DESC* pDesc)
|
||||
: D3D11DeviceChild<ID3D11Texture3D1>(pDevice),
|
||||
m_texture (this, pDevice, pDesc, D3D11_RESOURCE_DIMENSION_TEXTURE3D, 0, VK_NULL_HANDLE),
|
||||
m_texture (this, pDevice, pDesc, D3D11_RESOURCE_DIMENSION_TEXTURE3D, 0, VK_NULL_HANDLE, nullptr),
|
||||
m_interop (this, &m_texture),
|
||||
m_resource(this),
|
||||
m_d3d10 (this) {
|
||||
|
@ -78,7 +78,8 @@ namespace dxvk {
|
||||
const D3D11_COMMON_TEXTURE_DESC* pDesc,
|
||||
D3D11_RESOURCE_DIMENSION Dimension,
|
||||
DXGI_USAGE DxgiUsage,
|
||||
VkImage vkImage);
|
||||
VkImage vkImage,
|
||||
HANDLE hSharedHandle);
|
||||
|
||||
~D3D11CommonTexture();
|
||||
|
||||
@ -418,13 +419,14 @@ namespace dxvk {
|
||||
|
||||
D3D11_COMMON_TEXTURE_MAP_MODE DetermineMapMode(
|
||||
const DxvkImageCreateInfo* pImageInfo) const;
|
||||
|
||||
void ExportImageInfo();
|
||||
|
||||
static VkImageType GetImageTypeFromResourceDim(
|
||||
D3D11_RESOURCE_DIMENSION Dimension);
|
||||
|
||||
static VkImageLayout OptimizeLayout(
|
||||
VkImageUsageFlags Usage);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -599,7 +601,8 @@ namespace dxvk {
|
||||
|
||||
D3D11Texture2D(
|
||||
D3D11Device* pDevice,
|
||||
const D3D11_COMMON_TEXTURE_DESC* pDesc);
|
||||
const D3D11_COMMON_TEXTURE_DESC* pDesc,
|
||||
HANDLE hSharedHandle);
|
||||
|
||||
D3D11Texture2D(
|
||||
D3D11Device* pDevice,
|
||||
|
Loading…
x
Reference in New Issue
Block a user