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(
|
||||
D3D11Device* pDevice,
|
||||
const D3D11_BUFFER_DESC* pDesc)
|
||||
const D3D11_BUFFER_DESC* pDesc,
|
||||
const D3D11_ON_12_RESOURCE_INFO* p11on12Info)
|
||||
: D3D11DeviceChild<ID3D11Buffer>(pDevice),
|
||||
m_desc (*pDesc),
|
||||
m_resource (this),
|
||||
@ -83,17 +84,27 @@ namespace dxvk {
|
||||
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,
|
||||
// so that we only have to update it when invalidating the buffer
|
||||
m_buffer = m_parent->GetDXVKDevice()->createBuffer(info, GetMemoryFlags());
|
||||
m_mapped = m_buffer->getSliceHandle();
|
||||
|
||||
m_mapMode = DetermineMapMode();
|
||||
|
||||
// For Stream Output buffers we need a counter
|
||||
if (pDesc->BindFlags & D3D11_BIND_STREAM_OUTPUT)
|
||||
m_soCounter = CreateSoCounterBuffer();
|
||||
} else {
|
||||
m_sparseAllocator = m_parent->GetDXVKDevice()->createSparsePageAllocator();
|
||||
m_sparseAllocator->setCapacity(info.size / SparseMemoryPageSize);
|
||||
@ -101,11 +112,16 @@ namespace dxvk {
|
||||
m_mapped = DxvkBufferSliceHandle();
|
||||
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() {
|
||||
|
||||
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(
|
||||
VkFormat Format,
|
||||
VkFormatFeatureFlags2 Features) const {
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "d3d11_device_child.h"
|
||||
#include "d3d11_interfaces.h"
|
||||
#include "d3d11_on_12.h"
|
||||
#include "d3d11_resource.h"
|
||||
|
||||
namespace dxvk {
|
||||
@ -41,7 +42,9 @@ namespace dxvk {
|
||||
|
||||
D3D11Buffer(
|
||||
D3D11Device* pDevice,
|
||||
const D3D11_BUFFER_DESC* pDesc);
|
||||
const D3D11_BUFFER_DESC* pDesc,
|
||||
const D3D11_ON_12_RESOURCE_INFO* p11on12Info);
|
||||
|
||||
~D3D11Buffer();
|
||||
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(
|
||||
@ -142,6 +145,14 @@ namespace dxvk {
|
||||
: 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
|
||||
*
|
||||
@ -151,9 +162,23 @@ namespace dxvk {
|
||||
static HRESULT NormalizeBufferProperties(
|
||||
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:
|
||||
|
||||
D3D11_BUFFER_DESC m_desc;
|
||||
D3D11_ON_12_RESOURCE_INFO m_11on12;
|
||||
D3D11_COMMON_BUFFER_MAP_MODE m_mapMode;
|
||||
|
||||
Rc<DxvkBuffer> m_buffer;
|
||||
|
@ -100,7 +100,7 @@ namespace dxvk {
|
||||
return S_FALSE;
|
||||
|
||||
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))
|
||||
m_initializer->InitBuffer(buffer.ptr(), pInitialData);
|
||||
|
@ -45,8 +45,43 @@ namespace dxvk {
|
||||
D3D12_RESOURCE_STATES OutputState,
|
||||
REFIID riid,
|
||||
void** ppResource11) {
|
||||
Logger::err("D3D11on12Device::CreateWrappedResource: Stub");
|
||||
return E_NOTIMPL;
|
||||
Com<ID3D12DXVKInteropDevice> interopDevice;
|
||||
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 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 {
|
||||
|
||||
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) {
|
||||
return m_objects.memoryManager().getMemoryStats(heap);
|
||||
}
|
||||
|
@ -372,6 +372,19 @@ namespace dxvk {
|
||||
*/
|
||||
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
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user