1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-12 13:08:50 +01:00

[d3d11] Implement CreateWrappedResource for D3D12 textures

This commit is contained in:
Philip Rebohle 2023-03-16 16:02:04 +01:00
parent 3c99314332
commit 9bdad71dc6
10 changed files with 156 additions and 43 deletions

View File

@ -149,7 +149,7 @@ namespace dxvk {
return S_FALSE;
try {
const Com<D3D11Texture1D> texture = new D3D11Texture1D(this, &desc);
const Com<D3D11Texture1D> texture = new D3D11Texture1D(this, &desc, nullptr);
m_initializer->InitTexture(texture->GetCommonTexture(), pInitialData);
*ppTexture1D = texture.ref();
return S_OK;
@ -229,7 +229,7 @@ namespace dxvk {
return S_FALSE;
try {
Com<D3D11Texture2D> texture = new D3D11Texture2D(this, &desc, nullptr);
Com<D3D11Texture2D> texture = new D3D11Texture2D(this, &desc, nullptr, nullptr);
m_initializer->InitTexture(texture->GetCommonTexture(), pInitialData);
*ppTexture2D = texture.ref();
return S_OK;
@ -308,7 +308,7 @@ namespace dxvk {
return S_FALSE;
try {
Com<D3D11Texture3D> texture = new D3D11Texture3D(this, &desc);
Com<D3D11Texture3D> texture = new D3D11Texture3D(this, &desc, nullptr);
m_initializer->InitTexture(texture->GetCommonTexture(), pInitialData);
*ppTexture3D = texture.ref();
return S_OK;
@ -2307,7 +2307,7 @@ namespace dxvk {
// Only 2D textures may be shared
try {
const Com<D3D11Texture2D> texture = new D3D11Texture2D(this, &d3d11Desc, hResource);
const Com<D3D11Texture2D> texture = new D3D11Texture2D(this, &d3d11Desc, nullptr, hResource);
texture->QueryInterface(ReturnedInterface, ppResource);
return S_OK;
}

View File

@ -60,7 +60,7 @@ namespace dxvk {
return E_INVALIDARG;
}
// Query Vulkan resource handle and buffer offset
// Query Vulkan resource handle and buffer offset as necessary
if (FAILED(interopDevice->GetVulkanResourceInfo(info.Resource.ptr(), &info.VulkanHandle, &info.VulkanOffset))) {
Logger::err("D3D11on12Device::CreateWrappedResource: Failed to retrieve Vulkan resource info");
return E_INVALIDARG;
@ -77,8 +77,28 @@ namespace dxvk {
resource = new D3D11Buffer(m_device, &bufferDesc, &info);
} else {
Logger::err("D3D11on12Device::CreateWrappedResource: Resource type not supported");
return E_NOTIMPL;
D3D11_COMMON_TEXTURE_DESC textureDesc;
if (FAILED(D3D11CommonTexture::GetDescFromD3D12(info.Resource.ptr(), pResourceFlags, &textureDesc)))
return E_INVALIDARG;
switch (desc.Dimension) {
case D3D12_RESOURCE_DIMENSION_TEXTURE1D:
resource = new D3D11Texture1D(m_device, &textureDesc, &info);
break;
case D3D12_RESOURCE_DIMENSION_TEXTURE2D:
resource = new D3D11Texture2D(m_device, &textureDesc, &info, nullptr);
break;
case D3D12_RESOURCE_DIMENSION_TEXTURE3D:
resource = new D3D11Texture3D(m_device, &textureDesc, &info);
break;
default:
Logger::err("D3D11on12Device::CreateWrappedResource: Unhandled resource dimension");
return E_INVALIDARG;
}
}
return resource->QueryInterface(riid, ppResource11);

View File

@ -550,7 +550,8 @@ namespace dxvk {
VkImage imageHandle = m_presenter->getImage(i).image;
Rc<DxvkImage> image = new DxvkImage(
m_device.ptr(), imageInfo, imageHandle);
m_device.ptr(), imageInfo, imageHandle,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
m_imageViews[i] = new DxvkImageView(
m_device->vkd(), image, viewInfo);

View File

@ -11,11 +11,13 @@ namespace dxvk {
ID3D11Resource* pInterface,
D3D11Device* pDevice,
const D3D11_COMMON_TEXTURE_DESC* pDesc,
const D3D11_ON_12_RESOURCE_INFO* p11on12Info,
D3D11_RESOURCE_DIMENSION Dimension,
DXGI_USAGE DxgiUsage,
VkImage vkImage,
HANDLE hSharedHandle)
: m_interface(pInterface), m_device(pDevice), m_dimension(Dimension), m_desc(*pDesc), m_dxgiUsage(DxgiUsage) {
: m_interface(pInterface), m_device(pDevice), m_dimension(Dimension), m_desc(*pDesc),
m_11on12(p11on12Info ? *p11on12Info : D3D11_ON_12_RESOURCE_INFO()), m_dxgiUsage(DxgiUsage) {
DXGI_VK_FORMAT_MODE formatMode = GetFormatMode();
DXGI_VK_FORMAT_INFO formatInfo = m_device->LookupFormat(m_desc.Format, formatMode);
DXGI_VK_FORMAT_FAMILY formatFamily = m_device->LookupFamily(m_desc.Format, formatMode);
@ -228,10 +230,13 @@ namespace dxvk {
if (m_mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT)
memoryProperties = GetMemoryFlags();
if (vkImage == VK_NULL_HANDLE)
if (m_11on12.Resource != nullptr)
vkImage = VkImage(m_11on12.VulkanHandle);
if (!vkImage)
m_image = m_device->GetDXVKDevice()->createImage(imageInfo, memoryProperties);
else
m_image = m_device->GetDXVKDevice()->createImageFromVkImage(imageInfo, vkImage);
m_image = m_device->GetDXVKDevice()->importImage(imageInfo, vkImage, memoryProperties);
if (imageInfo.sharing.mode == DxvkSharedHandleMode::Export)
ExportImageInfo();
@ -469,9 +474,60 @@ namespace dxvk {
}
HRESULT D3D11CommonTexture::GetDescFromD3D12(
ID3D12Resource* pResource,
const D3D11_RESOURCE_FLAGS* pResourceFlags,
D3D11_COMMON_TEXTURE_DESC* pTextureDesc) {
D3D12_RESOURCE_DESC desc12 = pResource->GetDesc();
pTextureDesc->Width = desc12.Width;
pTextureDesc->Height = desc12.Height;
if (desc12.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D) {
pTextureDesc->Depth = desc12.DepthOrArraySize;
pTextureDesc->ArraySize = 1;
} else {
pTextureDesc->Depth = 1;
pTextureDesc->ArraySize = desc12.DepthOrArraySize;
}
pTextureDesc->MipLevels = desc12.MipLevels;
pTextureDesc->Format = desc12.Format;
pTextureDesc->SampleDesc = desc12.SampleDesc;
pTextureDesc->Usage = D3D11_USAGE_DEFAULT;
pTextureDesc->BindFlags = 0;
pTextureDesc->CPUAccessFlags = 0;
pTextureDesc->MiscFlags = 0;
if (!(desc12.Flags & D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE))
pTextureDesc->BindFlags |= D3D11_BIND_SHADER_RESOURCE;
if (desc12.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET)
pTextureDesc->BindFlags |= D3D11_BIND_RENDER_TARGET;
if (desc12.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL)
pTextureDesc->BindFlags |= D3D11_BIND_DEPTH_STENCIL;
if (desc12.Flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS)
pTextureDesc->BindFlags |= D3D11_BIND_UNORDERED_ACCESS;
if (pResourceFlags) {
pTextureDesc->BindFlags = pResourceFlags->BindFlags;
pTextureDesc->MiscFlags |= pResourceFlags->MiscFlags;
pTextureDesc->CPUAccessFlags = pResourceFlags->CPUAccessFlags;
}
return S_OK;
}
BOOL D3D11CommonTexture::CheckImageSupport(
const DxvkImageCreateInfo* pImageInfo,
VkImageTiling Tiling) const {
// D3D12 images always use optimal tiling
if (m_11on12.Resource != nullptr && Tiling != VK_IMAGE_TILING_OPTIMAL)
return FALSE;
DxvkFormatQuery formatQuery = { };
formatQuery.format = pImageInfo->format;
formatQuery.type = pImageInfo->type;
@ -486,7 +542,7 @@ namespace dxvk {
if (!properties)
return FALSE;
return (pImageInfo->extent.width <= properties->maxExtent.width)
&& (pImageInfo->extent.height <= properties->maxExtent.height)
&& (pImageInfo->extent.depth <= properties->maxExtent.depth)
@ -1028,9 +1084,10 @@ namespace dxvk {
// D 3 D 1 1 T E X T U R E 1 D
D3D11Texture1D::D3D11Texture1D(
D3D11Device* pDevice,
const D3D11_COMMON_TEXTURE_DESC* pDesc)
const D3D11_COMMON_TEXTURE_DESC* pDesc,
const D3D11_ON_12_RESOURCE_INFO* p11on12Info)
: D3D11DeviceChild<ID3D11Texture1D>(pDevice),
m_texture (this, pDevice, pDesc, D3D11_RESOURCE_DIMENSION_TEXTURE1D, 0, VK_NULL_HANDLE, nullptr),
m_texture (this, pDevice, pDesc, p11on12Info, D3D11_RESOURCE_DIMENSION_TEXTURE1D, 0, VK_NULL_HANDLE, nullptr),
m_interop (this, &m_texture),
m_surface (this, &m_texture),
m_resource(this),
@ -1130,9 +1187,10 @@ namespace dxvk {
D3D11Texture2D::D3D11Texture2D(
D3D11Device* pDevice,
const D3D11_COMMON_TEXTURE_DESC* pDesc,
const D3D11_ON_12_RESOURCE_INFO* p11on12Info,
HANDLE hSharedHandle)
: D3D11DeviceChild<ID3D11Texture2D1>(pDevice),
m_texture (this, pDevice, pDesc, D3D11_RESOURCE_DIMENSION_TEXTURE2D, 0, VK_NULL_HANDLE, hSharedHandle),
m_texture (this, pDevice, pDesc, p11on12Info, D3D11_RESOURCE_DIMENSION_TEXTURE2D, 0, VK_NULL_HANDLE, hSharedHandle),
m_interop (this, &m_texture),
m_surface (this, &m_texture),
m_resource (this),
@ -1147,7 +1205,7 @@ namespace dxvk {
DXGI_USAGE DxgiUsage,
VkImage vkImage)
: D3D11DeviceChild<ID3D11Texture2D1>(pDevice),
m_texture (this, pDevice, pDesc, D3D11_RESOURCE_DIMENSION_TEXTURE2D, DxgiUsage, vkImage, nullptr),
m_texture (this, pDevice, pDesc, nullptr, D3D11_RESOURCE_DIMENSION_TEXTURE2D, DxgiUsage, vkImage, nullptr),
m_interop (this, &m_texture),
m_surface (this, &m_texture),
m_resource (this),
@ -1163,7 +1221,7 @@ namespace dxvk {
const D3D11_COMMON_TEXTURE_DESC* pDesc,
DXGI_USAGE DxgiUsage)
: D3D11DeviceChild<ID3D11Texture2D1>(pDevice),
m_texture (this, pDevice, pDesc, D3D11_RESOURCE_DIMENSION_TEXTURE2D, DxgiUsage, VK_NULL_HANDLE, nullptr),
m_texture (this, pDevice, pDesc, nullptr, D3D11_RESOURCE_DIMENSION_TEXTURE2D, DxgiUsage, VK_NULL_HANDLE, nullptr),
m_interop (this, &m_texture),
m_surface (this, &m_texture),
m_resource (this),
@ -1306,9 +1364,10 @@ namespace dxvk {
// D 3 D 1 1 T E X T U R E 3 D
D3D11Texture3D::D3D11Texture3D(
D3D11Device* pDevice,
const D3D11_COMMON_TEXTURE_DESC* pDesc)
const D3D11_COMMON_TEXTURE_DESC* pDesc,
const D3D11_ON_12_RESOURCE_INFO* p11on12Info)
: D3D11DeviceChild<ID3D11Texture3D1>(pDevice),
m_texture (this, pDevice, pDesc, D3D11_RESOURCE_DIMENSION_TEXTURE3D, 0, VK_NULL_HANDLE, nullptr),
m_texture (this, pDevice, pDesc, p11on12Info, D3D11_RESOURCE_DIMENSION_TEXTURE3D, 0, VK_NULL_HANDLE, nullptr),
m_interop (this, &m_texture),
m_resource(this),
m_d3d10 (this) {

View File

@ -7,6 +7,7 @@
#include "d3d11_device_child.h"
#include "d3d11_interfaces.h"
#include "d3d11_on_12.h"
#include "d3d11_resource.h"
namespace dxvk {
@ -85,6 +86,7 @@ namespace dxvk {
ID3D11Resource* pInterface,
D3D11Device* pDevice,
const D3D11_COMMON_TEXTURE_DESC* pDesc,
const D3D11_ON_12_RESOURCE_INFO* p11on12Info,
D3D11_RESOURCE_DIMENSION Dimension,
DXGI_USAGE DxgiUsage,
VkImage vkImage,
@ -435,6 +437,14 @@ namespace dxvk {
DXGI_FORMAT Format,
UINT Plane) const;
/**
* \brief Retrieves D3D11on12 resource info
* \returns 11on12 resource info
*/
D3D11_ON_12_RESOURCE_INFO Get11on12Info() const {
return m_11on12;
}
/**
* \brief Normalizes and validates texture description
*
@ -447,6 +457,19 @@ namespace dxvk {
static HRESULT NormalizeTextureProperties(
D3D11_COMMON_TEXTURE_DESC* pDesc);
/**
* \brief Initializes D3D11 texture description from D3D12
*
* \param [in] pResource D3D12 resource
* \param [in] pResourceFlags D3D11 flag overrides
* \param [out] pTextureDesc D3D11 buffer description
* \returns \c S_OK if the parameters are valid
*/
static HRESULT GetDescFromD3D12(
ID3D12Resource* pResource,
const D3D11_RESOURCE_FLAGS* pResourceFlags,
D3D11_COMMON_TEXTURE_DESC* pTextureDesc);
private:
struct MappedBuffer {
@ -465,6 +488,7 @@ namespace dxvk {
D3D11Device* m_device;
D3D11_RESOURCE_DIMENSION m_dimension;
D3D11_COMMON_TEXTURE_DESC m_desc;
D3D11_ON_12_RESOURCE_INFO m_11on12;
D3D11_COMMON_TEXTURE_MAP_MODE m_mapMode;
DXGI_USAGE m_dxgiUsage;
VkFormat m_packedFormat;
@ -636,7 +660,8 @@ namespace dxvk {
D3D11Texture1D(
D3D11Device* pDevice,
const D3D11_COMMON_TEXTURE_DESC* pDesc);
const D3D11_COMMON_TEXTURE_DESC* pDesc,
const D3D11_ON_12_RESOURCE_INFO* p11on12Info);
~D3D11Texture1D();
@ -682,6 +707,7 @@ namespace dxvk {
D3D11Texture2D(
D3D11Device* pDevice,
const D3D11_COMMON_TEXTURE_DESC* pDesc,
const D3D11_ON_12_RESOURCE_INFO* p11on12Info,
HANDLE hSharedHandle);
D3D11Texture2D(
@ -747,7 +773,8 @@ namespace dxvk {
D3D11Texture3D(
D3D11Device* pDevice,
const D3D11_COMMON_TEXTURE_DESC* pDesc);
const D3D11_COMMON_TEXTURE_DESC* pDesc,
const D3D11_ON_12_RESOURCE_INFO* p11on12Info);
~D3D11Texture3D();

View File

@ -861,7 +861,8 @@ namespace dxvk {
VkImage imageHandle = m_presenter->getImage(i).image;
Rc<DxvkImage> image = new DxvkImage(
m_device.ptr(), imageInfo, imageHandle);
m_device.ptr(), imageInfo, imageHandle,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
m_imageViews[i] = new DxvkImageView(
m_device->vkd(), image, viewInfo);

View File

@ -178,12 +178,6 @@ namespace dxvk {
}
Rc<DxvkImage> DxvkDevice::createImageFromVkImage(
const DxvkImageCreateInfo& createInfo,
VkImage image) {
return new DxvkImage(this, createInfo, image);
}
Rc<DxvkImageView> DxvkDevice::createImageView(
const Rc<DxvkImage>& image,
const DxvkImageViewCreateInfo& createInfo) {
@ -228,6 +222,14 @@ namespace dxvk {
}
Rc<DxvkImage> DxvkDevice::importImage(
const DxvkImageCreateInfo& createInfo,
VkImage image,
VkMemoryPropertyFlags memoryType) {
return new DxvkImage(this, createInfo, image, memoryType);
}
DxvkMemoryStats DxvkDevice::getMemoryStats(uint32_t heap) {
return m_objects.memoryManager().getMemoryStats(heap);
}

View File

@ -335,17 +335,6 @@ namespace dxvk {
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<DxvkImage> createImageFromVkImage(
const DxvkImageCreateInfo& createInfo,
VkImage image);
/**
* \brief Creates an image view
*
@ -385,6 +374,19 @@ namespace dxvk {
const DxvkBufferImportInfo& importInfo,
VkMemoryPropertyFlags memoryType);
/**
* \brief Imports an image
*
* \param [in] createInfo Image create info
* \param [in] image Vulkan image to wrap
* \param [in] memoryType Memory type flags
* \returns The image object
*/
Rc<DxvkImage> importImage(
const DxvkImageCreateInfo& createInfo,
VkImage image,
VkMemoryPropertyFlags memoryType);
/**
* \brief Retrieves stat counters
*

View File

@ -150,9 +150,9 @@ namespace dxvk {
DxvkImage::DxvkImage(
DxvkDevice* device,
const DxvkImageCreateInfo& info,
VkImage image)
: m_vkd(device->vkd()), m_device(device), m_info(info), m_image({ image }) {
VkImage image,
VkMemoryPropertyFlags memFlags)
: m_vkd(device->vkd()), m_device(device), m_info(info), m_memFlags(memFlags), m_image({ image }) {
m_viewFormats.resize(info.viewFormatCount);
for (uint32_t i = 0; i < info.viewFormatCount; i++)
m_viewFormats[i] = info.viewFormats[i];

View File

@ -144,7 +144,8 @@ namespace dxvk {
DxvkImage(
DxvkDevice* device,
const DxvkImageCreateInfo& info,
VkImage image);
VkImage image,
VkMemoryPropertyFlags memFlags);
/**
* \brief Destroys image