mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-05 01:24:14 +01:00
[d3d11] Implement CreateWrappedResource for D3D12 buffers
This commit is contained in:
parent
fa8cf50263
commit
3c99314332
@ -8,7 +8,8 @@ namespace dxvk {
|
|||||||
|
|
||||||
D3D11Buffer::D3D11Buffer(
|
D3D11Buffer::D3D11Buffer(
|
||||||
D3D11Device* pDevice,
|
D3D11Device* pDevice,
|
||||||
const D3D11_BUFFER_DESC* pDesc)
|
const D3D11_BUFFER_DESC* pDesc,
|
||||||
|
const D3D11_ON_12_RESOURCE_INFO* p11on12Info)
|
||||||
: D3D11DeviceChild<ID3D11Buffer>(pDevice),
|
: D3D11DeviceChild<ID3D11Buffer>(pDevice),
|
||||||
m_desc (*pDesc),
|
m_desc (*pDesc),
|
||||||
m_resource (this),
|
m_resource (this),
|
||||||
@ -83,17 +84,27 @@ namespace dxvk {
|
|||||||
info.access |= VK_ACCESS_HOST_WRITE_BIT;
|
info.access |= VK_ACCESS_HOST_WRITE_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(pDesc->MiscFlags & D3D11_RESOURCE_MISC_TILE_POOL)) {
|
if (p11on12Info) {
|
||||||
|
m_11on12 = *p11on12Info;
|
||||||
|
|
||||||
|
DxvkBufferImportInfo importInfo;
|
||||||
|
importInfo.buffer = VkBuffer(m_11on12.VulkanHandle);
|
||||||
|
importInfo.offset = m_11on12.VulkanOffset;
|
||||||
|
|
||||||
|
if (m_desc.CPUAccessFlags)
|
||||||
|
m_11on12.Resource->Map(0, nullptr, &importInfo.mapPtr);
|
||||||
|
|
||||||
|
m_buffer = m_parent->GetDXVKDevice()->importBuffer(info, importInfo, GetMemoryFlags());
|
||||||
|
m_mapped = m_buffer->getSliceHandle();
|
||||||
|
|
||||||
|
m_mapMode = DetermineMapMode();
|
||||||
|
} else if (!(pDesc->MiscFlags & D3D11_RESOURCE_MISC_TILE_POOL)) {
|
||||||
// Create the buffer and set the entire buffer slice as mapped,
|
// Create the buffer and set the entire buffer slice as mapped,
|
||||||
// so that we only have to update it when invalidating the buffer
|
// so that we only have to update it when invalidating the buffer
|
||||||
m_buffer = m_parent->GetDXVKDevice()->createBuffer(info, GetMemoryFlags());
|
m_buffer = m_parent->GetDXVKDevice()->createBuffer(info, GetMemoryFlags());
|
||||||
m_mapped = m_buffer->getSliceHandle();
|
m_mapped = m_buffer->getSliceHandle();
|
||||||
|
|
||||||
m_mapMode = DetermineMapMode();
|
m_mapMode = DetermineMapMode();
|
||||||
|
|
||||||
// For Stream Output buffers we need a counter
|
|
||||||
if (pDesc->BindFlags & D3D11_BIND_STREAM_OUTPUT)
|
|
||||||
m_soCounter = CreateSoCounterBuffer();
|
|
||||||
} else {
|
} else {
|
||||||
m_sparseAllocator = m_parent->GetDXVKDevice()->createSparsePageAllocator();
|
m_sparseAllocator = m_parent->GetDXVKDevice()->createSparsePageAllocator();
|
||||||
m_sparseAllocator->setCapacity(info.size / SparseMemoryPageSize);
|
m_sparseAllocator->setCapacity(info.size / SparseMemoryPageSize);
|
||||||
@ -101,11 +112,16 @@ namespace dxvk {
|
|||||||
m_mapped = DxvkBufferSliceHandle();
|
m_mapped = DxvkBufferSliceHandle();
|
||||||
m_mapMode = D3D11_COMMON_BUFFER_MAP_MODE_NONE;
|
m_mapMode = D3D11_COMMON_BUFFER_MAP_MODE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For Stream Output buffers we need a counter
|
||||||
|
if (pDesc->BindFlags & D3D11_BIND_STREAM_OUTPUT)
|
||||||
|
m_soCounter = CreateSoCounterBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
D3D11Buffer::~D3D11Buffer() {
|
D3D11Buffer::~D3D11Buffer() {
|
||||||
|
if (m_desc.CPUAccessFlags && m_11on12.Resource != nullptr)
|
||||||
|
m_11on12.Resource->Unmap(0, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -241,6 +257,36 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT D3D11Buffer::GetDescFromD3D12(
|
||||||
|
ID3D12Resource* pResource,
|
||||||
|
const D3D11_RESOURCE_FLAGS* pResourceFlags,
|
||||||
|
D3D11_BUFFER_DESC* pBufferDesc) {
|
||||||
|
D3D12_RESOURCE_DESC desc12 = pResource->GetDesc();
|
||||||
|
|
||||||
|
pBufferDesc->ByteWidth = desc12.Width;
|
||||||
|
pBufferDesc->Usage = D3D11_USAGE_DEFAULT;
|
||||||
|
pBufferDesc->BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||||
|
pBufferDesc->MiscFlags = 0;
|
||||||
|
pBufferDesc->CPUAccessFlags = 0;
|
||||||
|
pBufferDesc->StructureByteStride = 0;
|
||||||
|
|
||||||
|
if (desc12.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET)
|
||||||
|
pBufferDesc->BindFlags |= D3D11_BIND_RENDER_TARGET;
|
||||||
|
|
||||||
|
if (desc12.Flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS)
|
||||||
|
pBufferDesc->BindFlags |= D3D11_BIND_UNORDERED_ACCESS;
|
||||||
|
|
||||||
|
if (pResourceFlags) {
|
||||||
|
pBufferDesc->BindFlags = pResourceFlags->BindFlags;
|
||||||
|
pBufferDesc->MiscFlags |= pResourceFlags->MiscFlags;
|
||||||
|
pBufferDesc->CPUAccessFlags = pResourceFlags->CPUAccessFlags;
|
||||||
|
pBufferDesc->StructureByteStride = pResourceFlags->StructureByteStride;
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOL D3D11Buffer::CheckFormatFeatureSupport(
|
BOOL D3D11Buffer::CheckFormatFeatureSupport(
|
||||||
VkFormat Format,
|
VkFormat Format,
|
||||||
VkFormatFeatureFlags2 Features) const {
|
VkFormatFeatureFlags2 Features) const {
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include "d3d11_device_child.h"
|
#include "d3d11_device_child.h"
|
||||||
#include "d3d11_interfaces.h"
|
#include "d3d11_interfaces.h"
|
||||||
|
#include "d3d11_on_12.h"
|
||||||
#include "d3d11_resource.h"
|
#include "d3d11_resource.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
@ -41,7 +42,9 @@ namespace dxvk {
|
|||||||
|
|
||||||
D3D11Buffer(
|
D3D11Buffer(
|
||||||
D3D11Device* pDevice,
|
D3D11Device* pDevice,
|
||||||
const D3D11_BUFFER_DESC* pDesc);
|
const D3D11_BUFFER_DESC* pDesc,
|
||||||
|
const D3D11_ON_12_RESOURCE_INFO* p11on12Info);
|
||||||
|
|
||||||
~D3D11Buffer();
|
~D3D11Buffer();
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE QueryInterface(
|
HRESULT STDMETHODCALLTYPE QueryInterface(
|
||||||
@ -142,6 +145,14 @@ namespace dxvk {
|
|||||||
: DxvkCsThread::SynchronizeAll;
|
: DxvkCsThread::SynchronizeAll;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieves D3D11on12 resource info
|
||||||
|
* \returns 11on12 resource info
|
||||||
|
*/
|
||||||
|
D3D11_ON_12_RESOURCE_INFO Get11on12Info() const {
|
||||||
|
return m_11on12;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Normalizes buffer description
|
* \brief Normalizes buffer description
|
||||||
*
|
*
|
||||||
@ -151,9 +162,23 @@ namespace dxvk {
|
|||||||
static HRESULT NormalizeBufferProperties(
|
static HRESULT NormalizeBufferProperties(
|
||||||
D3D11_BUFFER_DESC* pDesc);
|
D3D11_BUFFER_DESC* pDesc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Initializes D3D11 buffer description from D3D12
|
||||||
|
*
|
||||||
|
* \param [in] pResource D3D12 resource
|
||||||
|
* \param [in] pResourceFlags D3D11 flag overrides
|
||||||
|
* \param [out] pBufferDesc D3D11 buffer description
|
||||||
|
* \returns \c S_OK if the parameters are valid
|
||||||
|
*/
|
||||||
|
static HRESULT GetDescFromD3D12(
|
||||||
|
ID3D12Resource* pResource,
|
||||||
|
const D3D11_RESOURCE_FLAGS* pResourceFlags,
|
||||||
|
D3D11_BUFFER_DESC* pBufferDesc);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
D3D11_BUFFER_DESC m_desc;
|
D3D11_BUFFER_DESC m_desc;
|
||||||
|
D3D11_ON_12_RESOURCE_INFO m_11on12;
|
||||||
D3D11_COMMON_BUFFER_MAP_MODE m_mapMode;
|
D3D11_COMMON_BUFFER_MAP_MODE m_mapMode;
|
||||||
|
|
||||||
Rc<DxvkBuffer> m_buffer;
|
Rc<DxvkBuffer> m_buffer;
|
||||||
|
@ -100,7 +100,7 @@ namespace dxvk {
|
|||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const Com<D3D11Buffer> buffer = new D3D11Buffer(this, &desc);
|
const Com<D3D11Buffer> buffer = new D3D11Buffer(this, &desc, nullptr);
|
||||||
|
|
||||||
if (!(desc.MiscFlags & D3D11_RESOURCE_MISC_TILE_POOL))
|
if (!(desc.MiscFlags & D3D11_RESOURCE_MISC_TILE_POOL))
|
||||||
m_initializer->InitBuffer(buffer.ptr(), pInitialData);
|
m_initializer->InitBuffer(buffer.ptr(), pInitialData);
|
||||||
|
@ -45,8 +45,43 @@ namespace dxvk {
|
|||||||
D3D12_RESOURCE_STATES OutputState,
|
D3D12_RESOURCE_STATES OutputState,
|
||||||
REFIID riid,
|
REFIID riid,
|
||||||
void** ppResource11) {
|
void** ppResource11) {
|
||||||
Logger::err("D3D11on12Device::CreateWrappedResource: Stub");
|
Com<ID3D12DXVKInteropDevice> interopDevice;
|
||||||
return E_NOTIMPL;
|
m_d3d12Device->QueryInterface(__uuidof(ID3D12DXVKInteropDevice), reinterpret_cast<void**>(&interopDevice));
|
||||||
|
|
||||||
|
D3D11_ON_12_RESOURCE_INFO info = { };
|
||||||
|
info.InputState = InputState;
|
||||||
|
info.OutputState = OutputState;
|
||||||
|
info.IsWrappedResource = TRUE;
|
||||||
|
|
||||||
|
// 11on12 technically allows importing D3D12 heaps as tile pools,
|
||||||
|
// but we don't support importing sparse resources at this time.
|
||||||
|
if (FAILED(pResource12->QueryInterface(__uuidof(ID3D12Resource), reinterpret_cast<void**>(&info.Resource)))) {
|
||||||
|
Logger::err("D3D11on12Device::CreateWrappedResource: Resource not a valid D3D12 resource");
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query Vulkan resource handle and buffer offset
|
||||||
|
if (FAILED(interopDevice->GetVulkanResourceInfo(info.Resource.ptr(), &info.VulkanHandle, &info.VulkanOffset))) {
|
||||||
|
Logger::err("D3D11on12Device::CreateWrappedResource: Failed to retrieve Vulkan resource info");
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
Com<ID3D11Resource> resource;
|
||||||
|
D3D12_RESOURCE_DESC desc = info.Resource->GetDesc();
|
||||||
|
|
||||||
|
if (desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) {
|
||||||
|
D3D11_BUFFER_DESC bufferDesc;
|
||||||
|
|
||||||
|
if (FAILED(D3D11Buffer::GetDescFromD3D12(info.Resource.ptr(), pResourceFlags, &bufferDesc)))
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
resource = new D3D11Buffer(m_device, &bufferDesc, &info);
|
||||||
|
} else {
|
||||||
|
Logger::err("D3D11on12Device::CreateWrappedResource: Resource type not supported");
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return resource->QueryInterface(riid, ppResource11);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,6 +9,19 @@ namespace dxvk {
|
|||||||
class D3D11Device;
|
class D3D11Device;
|
||||||
class D3D11DXGIDevice;
|
class D3D11DXGIDevice;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Resource info for 11on12 resources
|
||||||
|
*/
|
||||||
|
struct D3D11_ON_12_RESOURCE_INFO {
|
||||||
|
Com<ID3D12Resource> Resource;
|
||||||
|
UINT64 VulkanHandle = 0;
|
||||||
|
UINT64 VulkanOffset = 0;
|
||||||
|
BOOL IsWrappedResource = FALSE;
|
||||||
|
D3D12_RESOURCE_STATES InputState = D3D12_RESOURCE_STATE_COMMON;
|
||||||
|
D3D12_RESOURCE_STATES OutputState = D3D12_RESOURCE_STATE_COMMON;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class D3D11on12Device : public ID3D11On12Device {
|
class D3D11on12Device : public ID3D11On12Device {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -220,6 +220,14 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Rc<DxvkBuffer> DxvkDevice::importBuffer(
|
||||||
|
const DxvkBufferCreateInfo& createInfo,
|
||||||
|
const DxvkBufferImportInfo& importInfo,
|
||||||
|
VkMemoryPropertyFlags memoryType) {
|
||||||
|
return new DxvkBuffer(this, createInfo, importInfo, memoryType);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DxvkMemoryStats DxvkDevice::getMemoryStats(uint32_t heap) {
|
DxvkMemoryStats DxvkDevice::getMemoryStats(uint32_t heap) {
|
||||||
return m_objects.memoryManager().getMemoryStats(heap);
|
return m_objects.memoryManager().getMemoryStats(heap);
|
||||||
}
|
}
|
||||||
|
@ -372,6 +372,19 @@ namespace dxvk {
|
|||||||
*/
|
*/
|
||||||
Rc<DxvkSparsePageAllocator> createSparsePageAllocator();
|
Rc<DxvkSparsePageAllocator> createSparsePageAllocator();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Imports a buffer
|
||||||
|
*
|
||||||
|
* \param [in] createInfo Buffer create info
|
||||||
|
* \param [in] importInfo Buffer import info
|
||||||
|
* \param [in] memoryType Memory type flags
|
||||||
|
* \returns The buffer object
|
||||||
|
*/
|
||||||
|
Rc<DxvkBuffer> importBuffer(
|
||||||
|
const DxvkBufferCreateInfo& createInfo,
|
||||||
|
const DxvkBufferImportInfo& importInfo,
|
||||||
|
VkMemoryPropertyFlags memoryType);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Retrieves stat counters
|
* \brief Retrieves stat counters
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user