diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index ffcb25d64..2db6f9e4f 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -149,7 +149,7 @@ namespace dxvk { return S_FALSE; try { - const Com texture = new D3D11Texture1D(this, &desc); + const Com 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 texture = new D3D11Texture2D(this, &desc, nullptr); + Com 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 texture = new D3D11Texture3D(this, &desc); + Com 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 texture = new D3D11Texture2D(this, &d3d11Desc, hResource); + const Com texture = new D3D11Texture2D(this, &d3d11Desc, nullptr, hResource); texture->QueryInterface(ReturnedInterface, ppResource); return S_OK; } diff --git a/src/d3d11/d3d11_on_12.cpp b/src/d3d11/d3d11_on_12.cpp index 4f92b87c8..55b2057ca 100644 --- a/src/d3d11/d3d11_on_12.cpp +++ b/src/d3d11/d3d11_on_12.cpp @@ -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); diff --git a/src/d3d11/d3d11_swapchain.cpp b/src/d3d11/d3d11_swapchain.cpp index a28978cdf..eeb847062 100644 --- a/src/d3d11/d3d11_swapchain.cpp +++ b/src/d3d11/d3d11_swapchain.cpp @@ -550,7 +550,8 @@ namespace dxvk { VkImage imageHandle = m_presenter->getImage(i).image; Rc 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); diff --git a/src/d3d11/d3d11_texture.cpp b/src/d3d11/d3d11_texture.cpp index 15579edde..b6f7d92a9 100644 --- a/src/d3d11/d3d11_texture.cpp +++ b/src/d3d11/d3d11_texture.cpp @@ -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(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(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(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(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(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) { diff --git a/src/d3d11/d3d11_texture.h b/src/d3d11/d3d11_texture.h index bd778d71f..3708d14f7 100644 --- a/src/d3d11/d3d11_texture.h +++ b/src/d3d11/d3d11_texture.h @@ -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(); diff --git a/src/d3d9/d3d9_swapchain.cpp b/src/d3d9/d3d9_swapchain.cpp index b65f3ee79..a3af18a37 100644 --- a/src/d3d9/d3d9_swapchain.cpp +++ b/src/d3d9/d3d9_swapchain.cpp @@ -861,7 +861,8 @@ namespace dxvk { VkImage imageHandle = m_presenter->getImage(i).image; Rc 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); diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index 2591da5a7..87022f857 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -178,12 +178,6 @@ namespace dxvk { } - Rc DxvkDevice::createImageFromVkImage( - const DxvkImageCreateInfo& createInfo, - VkImage image) { - return new DxvkImage(this, createInfo, image); - } - Rc DxvkDevice::createImageView( const Rc& image, const DxvkImageViewCreateInfo& createInfo) { @@ -228,6 +222,14 @@ namespace dxvk { } + Rc 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); } diff --git a/src/dxvk/dxvk_device.h b/src/dxvk/dxvk_device.h index 85d2e557b..7c222907c 100644 --- a/src/dxvk/dxvk_device.h +++ b/src/dxvk/dxvk_device.h @@ -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 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 importImage( + const DxvkImageCreateInfo& createInfo, + VkImage image, + VkMemoryPropertyFlags memoryType); + /** * \brief Retrieves stat counters * diff --git a/src/dxvk/dxvk_image.cpp b/src/dxvk/dxvk_image.cpp index 5d84386ff..8ddbd477a 100644 --- a/src/dxvk/dxvk_image.cpp +++ b/src/dxvk/dxvk_image.cpp @@ -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]; diff --git a/src/dxvk/dxvk_image.h b/src/dxvk/dxvk_image.h index a29d916cf..3a09302bf 100644 --- a/src/dxvk/dxvk_image.h +++ b/src/dxvk/dxvk_image.h @@ -144,7 +144,8 @@ namespace dxvk { DxvkImage( DxvkDevice* device, const DxvkImageCreateInfo& info, - VkImage image); + VkImage image, + VkMemoryPropertyFlags memFlags); /** * \brief Destroys image