Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proton Shared Texture Resources Implementation #2516

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
70 changes: 61 additions & 9 deletions src/d3d11/d3d11_device.cpp
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -1388,21 +1390,15 @@ 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);
}


HRESULT STDMETHODCALLTYPE D3D11Device::OpenSharedResource1(
HANDLE hResource,
REFIID ReturnedInterface,
void** ppResource) {
InitReturnPtr(ppResource);

Logger::err("D3D11Device::OpenSharedResource1: Not implemented");
return E_NOTIMPL;
return OpenSharedResourceGeneric(false, hResource, ReturnedInterface, ppResource);
}


Expand Down Expand Up @@ -2260,6 +2256,62 @@ namespace dxvk {
}


HRESULT D3D11Device::OpenSharedResourceGeneric(
BOOL isKmtResource,
HANDLE hResource,
REFIID ReturnedInterface,
void** ppResource) {
InitReturnPtr(ppResource);

if (ppResource == nullptr)
return S_FALSE;

HANDLE ntHandle = isKmtResource ? 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 (isKmtResource)
::CloseHandle(ntHandle);
Guy1524 marked this conversation as resolved.
Show resolved Hide resolved

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,
Expand Down
6 changes: 6 additions & 0 deletions src/d3d11/d3d11_device.h
Expand Up @@ -473,6 +473,12 @@ namespace dxvk {
VkFormat Format,
VkImageType Type) const;

HRESULT OpenSharedResourceGeneric(
BOOL NTHandle,
HANDLE hResource,
REFIID ReturnedInterface,
void** ppResource);

uint32_t GetViewPlaneIndex(
ID3D11Resource* pResource,
DXGI_FORMAT ViewFormat);
Expand Down
33 changes: 26 additions & 7 deletions src/d3d11/d3d11_resource.cpp
Expand Up @@ -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;
}


Expand Down Expand Up @@ -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;
}


Expand Down Expand Up @@ -235,4 +254,4 @@ namespace dxvk {
return ResourceReleasePrivate(pResource, dim);
}

}
}
4 changes: 2 additions & 2 deletions src/d3d11/d3d11_swapchain.cpp
Expand Up @@ -445,7 +445,7 @@ namespace dxvk {
VkImage imageHandle = m_presenter->getImage(i).image;

Rc<DxvkImage> image = new DxvkImage(
m_device->vkd(), imageInfo, imageHandle);
m_device.ptr(), imageInfo, imageHandle);

m_imageViews[i] = new DxvkImageView(
m_device->vkd(), image, viewInfo);
Expand Down Expand Up @@ -661,4 +661,4 @@ namespace dxvk {
return str::format("D3D", apiVersion, " FL", flHi, "_", flLo);
}

}
}
71 changes: 63 additions & 8 deletions src/d3d11/d3d11_texture.cpp
Expand Up @@ -2,6 +2,8 @@
#include "d3d11_gdi.h"
#include "d3d11_texture.h"

#include "../util/util_shared_res.h"

namespace dxvk {

D3D11CommonTexture::D3D11CommonTexture(
Expand All @@ -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);
Expand Down Expand Up @@ -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)) {
Guy1524 marked this conversation as resolved.
Show resolved Hide resolved
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);

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


Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -588,6 +610,38 @@ 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);
Expand Down Expand Up @@ -927,7 +981,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),
Expand Down Expand Up @@ -1023,9 +1077,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),
Expand All @@ -1040,7 +1095,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),
Expand Down Expand Up @@ -1156,7 +1211,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) {
Expand Down
9 changes: 6 additions & 3 deletions src/d3d11/d3d11_texture.h
Expand Up @@ -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();

Expand Down Expand Up @@ -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);

};


Expand Down Expand Up @@ -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,
Expand Down