1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-05 01:24:14 +01:00

[dxvk] Implement functionality to import foreign buffers

This commit is contained in:
Philip Rebohle 2023-03-16 13:36:47 +01:00
parent 3f9d2269f6
commit fa8cf50263
3 changed files with 63 additions and 2 deletions

View File

@ -62,9 +62,35 @@ namespace dxvk {
}
DxvkBuffer::DxvkBuffer(
DxvkDevice* device,
const DxvkBufferCreateInfo& createInfo,
const DxvkBufferImportInfo& importInfo,
VkMemoryPropertyFlags memFlags)
: m_vkd (device->vkd()),
m_info (createInfo),
m_import (importInfo),
m_memAlloc (nullptr),
m_memFlags (memFlags),
m_shaderStages (util::shaderStages(createInfo.stages)) {
m_physSliceLength = createInfo.size;
m_physSliceStride = createInfo.size;
m_physSliceCount = 1;
m_physSliceMaxCount = 1;
m_physSlice.handle = importInfo.buffer;
m_physSlice.offset = importInfo.offset;
m_physSlice.length = createInfo.size;
m_physSlice.mapPtr = importInfo.mapPtr;
m_lazyAlloc = false;
}
DxvkBuffer::~DxvkBuffer() {
for (const auto& buffer : m_buffers)
m_vkd->vkDestroyBuffer(m_vkd->device(), buffer.buffer, nullptr);
m_vkd->vkDestroyBuffer(m_vkd->device(), m_buffer.buffer, nullptr);
}

View File

@ -55,6 +55,22 @@ namespace dxvk {
};
/**
* \brief Buffer import info
*
* Used to import an existing Vulkan buffer. Note
* that imported buffers must not be renamed.
*/
struct DxvkBufferImportInfo {
/// Buffer handle
VkBuffer buffer = VK_NULL_HANDLE;
/// Buffer offset
VkDeviceSize offset = 0;
/// Pointer to mapped memory region
void* mapPtr = nullptr;
};
/**
* \brief Buffer info
*
@ -113,6 +129,12 @@ namespace dxvk {
DxvkMemoryAllocator& memAlloc,
VkMemoryPropertyFlags memFlags);
DxvkBuffer(
DxvkDevice* device,
const DxvkBufferCreateInfo& createInfo,
const DxvkBufferImportInfo& importInfo,
VkMemoryPropertyFlags memFlags);
~DxvkBuffer();
/**
@ -294,10 +316,19 @@ namespace dxvk {
m_nextSlices.push_back(slice);
}
/**
* \brief Checks whether the buffer is imported
* \returns \c true if the buffer is imported
*/
bool isForeign() const {
return m_import.buffer != VK_NULL_HANDLE;
}
private:
Rc<vk::DeviceFn> m_vkd;
DxvkBufferCreateInfo m_info;
DxvkBufferImportInfo m_import;
DxvkMemoryAllocator* m_memAlloc;
VkMemoryPropertyFlags m_memFlags;
VkShaderStageFlags m_shaderStages;

View File

@ -6155,6 +6155,10 @@ namespace dxvk {
if (buffer->info().flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT)
return false;
// Don't discard imported buffers
if (buffer->isForeign())
return false;
// Suspend the current render pass if transform feedback is active prior to
// invalidating the buffer, since otherwise we may invalidate a bound buffer.
if ((buffer->info().usage & VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT)