mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-12 04:08:52 +01:00
[dxvk] Refactor descriptor set allocation
With this new approach, descriptor pools are decoupled from the command list they are used with. Instead, the DXVK context takes ownership of a single descriptor pool until it runs out of memory. This reduces the amount of memory wasted for under-utilized pools and should this reduce an application's memory footprint.
This commit is contained in:
parent
eb7a5da975
commit
4057937d2d
@ -8,7 +8,7 @@ namespace dxvk {
|
|||||||
uint32_t queueFamily)
|
uint32_t queueFamily)
|
||||||
: m_vkd (device->vkd()),
|
: m_vkd (device->vkd()),
|
||||||
m_cmdBuffersUsed(0),
|
m_cmdBuffersUsed(0),
|
||||||
m_descAlloc (device->vkd()),
|
m_descriptorPoolTracker(device),
|
||||||
m_stagingAlloc (device) {
|
m_stagingAlloc (device) {
|
||||||
VkFenceCreateInfo fenceInfo;
|
VkFenceCreateInfo fenceInfo;
|
||||||
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||||
@ -127,7 +127,7 @@ namespace dxvk {
|
|||||||
m_eventTracker.reset();
|
m_eventTracker.reset();
|
||||||
m_queryTracker.reset();
|
m_queryTracker.reset();
|
||||||
m_stagingAlloc.reset();
|
m_stagingAlloc.reset();
|
||||||
m_descAlloc.reset();
|
m_descriptorPoolTracker.reset();
|
||||||
m_resources.reset();
|
m_resources.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,6 +157,14 @@ namespace dxvk {
|
|||||||
m_eventTracker.trackEvent(event);
|
m_eventTracker.trackEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Tracks a descriptor pool
|
||||||
|
* \param [in] pool The descriptor pool
|
||||||
|
*/
|
||||||
|
void trackDescriptorPool(Rc<DxvkDescriptorPool> pool) {
|
||||||
|
m_descriptorPoolTracker.trackDescriptorPool(pool);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Signals tracked events
|
* \brief Signals tracked events
|
||||||
*
|
*
|
||||||
@ -188,12 +196,6 @@ namespace dxvk {
|
|||||||
*/
|
*/
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
VkDescriptorSet allocateDescriptorSet(
|
|
||||||
VkDescriptorSetLayout descriptorLayout) {
|
|
||||||
return m_descAlloc.alloc(descriptorLayout);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void updateDescriptorSets(
|
void updateDescriptorSets(
|
||||||
uint32_t descriptorWriteCount,
|
uint32_t descriptorWriteCount,
|
||||||
const VkWriteDescriptorSet* pDescriptorWrites) {
|
const VkWriteDescriptorSet* pDescriptorWrites) {
|
||||||
@ -656,7 +658,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
DxvkCmdBufferFlags m_cmdBuffersUsed;
|
DxvkCmdBufferFlags m_cmdBuffersUsed;
|
||||||
DxvkLifetimeTracker m_resources;
|
DxvkLifetimeTracker m_resources;
|
||||||
DxvkDescriptorAlloc m_descAlloc;
|
DxvkDescriptorPoolTracker m_descriptorPoolTracker;
|
||||||
DxvkStagingAlloc m_stagingAlloc;
|
DxvkStagingAlloc m_stagingAlloc;
|
||||||
DxvkQueryTracker m_queryTracker;
|
DxvkQueryTracker m_queryTracker;
|
||||||
DxvkEventTracker m_eventTracker;
|
DxvkEventTracker m_eventTracker;
|
||||||
|
@ -296,8 +296,7 @@ namespace dxvk {
|
|||||||
// Create a descriptor set pointing to the view
|
// Create a descriptor set pointing to the view
|
||||||
VkBufferView viewObject = bufferView->handle();
|
VkBufferView viewObject = bufferView->handle();
|
||||||
|
|
||||||
VkDescriptorSet descriptorSet =
|
VkDescriptorSet descriptorSet = allocateDescriptorSet(pipeInfo.dsetLayout);
|
||||||
m_cmd->allocateDescriptorSet(pipeInfo.dsetLayout);
|
|
||||||
|
|
||||||
VkWriteDescriptorSet descriptorWrite;
|
VkWriteDescriptorSet descriptorWrite;
|
||||||
descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||||
@ -963,7 +962,7 @@ namespace dxvk {
|
|||||||
descriptors.srcDepth = dView->getDescriptor(VK_IMAGE_VIEW_TYPE_2D_ARRAY, layout).image;
|
descriptors.srcDepth = dView->getDescriptor(VK_IMAGE_VIEW_TYPE_2D_ARRAY, layout).image;
|
||||||
descriptors.srcStencil = sView->getDescriptor(VK_IMAGE_VIEW_TYPE_2D_ARRAY, layout).image;
|
descriptors.srcStencil = sView->getDescriptor(VK_IMAGE_VIEW_TYPE_2D_ARRAY, layout).image;
|
||||||
|
|
||||||
VkDescriptorSet dset = m_cmd->allocateDescriptorSet(pipeInfo.dsetLayout);
|
VkDescriptorSet dset = allocateDescriptorSet(pipeInfo.dsetLayout);
|
||||||
m_cmd->updateDescriptorSetWithTemplate(dset, pipeInfo.dsetTemplate, &descriptors);
|
m_cmd->updateDescriptorSetWithTemplate(dset, pipeInfo.dsetTemplate, &descriptors);
|
||||||
|
|
||||||
// Since this is a meta operation, the image may be
|
// Since this is a meta operation, the image may be
|
||||||
@ -1290,7 +1289,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
// Create descriptor set with the current source view
|
// Create descriptor set with the current source view
|
||||||
descriptorImage.imageView = pass.srcView;
|
descriptorImage.imageView = pass.srcView;
|
||||||
descriptorWrite.dstSet = m_cmd->allocateDescriptorSet(pipeInfo.dsetLayout);
|
descriptorWrite.dstSet = allocateDescriptorSet(pipeInfo.dsetLayout);
|
||||||
m_cmd->updateDescriptorSets(1, &descriptorWrite);
|
m_cmd->updateDescriptorSets(1, &descriptorWrite);
|
||||||
|
|
||||||
// Set up viewport and scissor rect
|
// Set up viewport and scissor rect
|
||||||
@ -1802,8 +1801,7 @@ namespace dxvk {
|
|||||||
imageView->type(), imageFormatInfo(imageView->info().format)->flags);
|
imageView->type(), imageFormatInfo(imageView->info().format)->flags);
|
||||||
|
|
||||||
// Create a descriptor set pointing to the view
|
// Create a descriptor set pointing to the view
|
||||||
VkDescriptorSet descriptorSet =
|
VkDescriptorSet descriptorSet = allocateDescriptorSet(pipeInfo.dsetLayout);
|
||||||
m_cmd->allocateDescriptorSet(pipeInfo.dsetLayout);
|
|
||||||
|
|
||||||
VkDescriptorImageInfo viewInfo;
|
VkDescriptorImageInfo viewInfo;
|
||||||
viewInfo.sampler = VK_NULL_HANDLE;
|
viewInfo.sampler = VK_NULL_HANDLE;
|
||||||
@ -2077,7 +2075,7 @@ namespace dxvk {
|
|||||||
descriptorWrite.pBufferInfo = nullptr;
|
descriptorWrite.pBufferInfo = nullptr;
|
||||||
descriptorWrite.pTexelBufferView = nullptr;
|
descriptorWrite.pTexelBufferView = nullptr;
|
||||||
|
|
||||||
descriptorWrite.dstSet = m_cmd->allocateDescriptorSet(pipeInfo.dsetLayout);
|
descriptorWrite.dstSet = allocateDescriptorSet(pipeInfo.dsetLayout);
|
||||||
m_cmd->updateDescriptorSets(1, &descriptorWrite);
|
m_cmd->updateDescriptorSets(1, &descriptorWrite);
|
||||||
|
|
||||||
VkViewport viewport;
|
VkViewport viewport;
|
||||||
@ -2272,7 +2270,7 @@ namespace dxvk {
|
|||||||
descriptorWrite.pBufferInfo = nullptr;
|
descriptorWrite.pBufferInfo = nullptr;
|
||||||
descriptorWrite.pTexelBufferView = nullptr;
|
descriptorWrite.pTexelBufferView = nullptr;
|
||||||
|
|
||||||
descriptorWrite.dstSet = m_cmd->allocateDescriptorSet(pipeInfo.dsetLayout);
|
descriptorWrite.dstSet = allocateDescriptorSet(pipeInfo.dsetLayout);
|
||||||
m_cmd->updateDescriptorSets(1, &descriptorWrite);
|
m_cmd->updateDescriptorSets(1, &descriptorWrite);
|
||||||
|
|
||||||
// Set up viewport and scissor rect
|
// Set up viewport and scissor rect
|
||||||
@ -2814,7 +2812,7 @@ namespace dxvk {
|
|||||||
VkDescriptorSet descriptorSet = VK_NULL_HANDLE;
|
VkDescriptorSet descriptorSet = VK_NULL_HANDLE;
|
||||||
|
|
||||||
if (layout->bindingCount() != 0) {
|
if (layout->bindingCount() != 0) {
|
||||||
descriptorSet = m_cmd->allocateDescriptorSet(
|
descriptorSet = allocateDescriptorSet(
|
||||||
layout->descriptorSetLayout());
|
layout->descriptorSetLayout());
|
||||||
|
|
||||||
m_cmd->updateDescriptorSetWithTemplate(
|
m_cmd->updateDescriptorSetWithTemplate(
|
||||||
@ -3259,6 +3257,24 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VkDescriptorSet DxvkContext::allocateDescriptorSet(
|
||||||
|
VkDescriptorSetLayout layout) {
|
||||||
|
if (m_descPool == nullptr)
|
||||||
|
m_descPool = m_device->createDescriptorPool();
|
||||||
|
|
||||||
|
VkDescriptorSet set = m_descPool->alloc(layout);
|
||||||
|
|
||||||
|
if (set == VK_NULL_HANDLE) {
|
||||||
|
m_cmd->trackDescriptorPool(std::move(m_descPool));
|
||||||
|
|
||||||
|
m_descPool = m_device->createDescriptorPool();
|
||||||
|
set = m_descPool->alloc(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxvkContext::trackDrawBuffer() {
|
void DxvkContext::trackDrawBuffer() {
|
||||||
if (m_flags.test(DxvkContextFlag::DirtyDrawBuffer)) {
|
if (m_flags.test(DxvkContextFlag::DirtyDrawBuffer)) {
|
||||||
m_flags.clr(DxvkContextFlag::DirtyDrawBuffer);
|
m_flags.clr(DxvkContextFlag::DirtyDrawBuffer);
|
||||||
|
@ -769,6 +769,8 @@ namespace dxvk {
|
|||||||
const Rc<DxvkMetaResolveObjects> m_metaResolve;
|
const Rc<DxvkMetaResolveObjects> m_metaResolve;
|
||||||
|
|
||||||
Rc<DxvkCommandList> m_cmd;
|
Rc<DxvkCommandList> m_cmd;
|
||||||
|
Rc<DxvkDescriptorPool> m_descPool;
|
||||||
|
|
||||||
DxvkContextFlags m_flags;
|
DxvkContextFlags m_flags;
|
||||||
DxvkContextState m_state;
|
DxvkContextState m_state;
|
||||||
|
|
||||||
@ -903,6 +905,9 @@ namespace dxvk {
|
|||||||
VkPipelineStageFlags dstStages,
|
VkPipelineStageFlags dstStages,
|
||||||
VkAccessFlags dstAccess);
|
VkAccessFlags dstAccess);
|
||||||
|
|
||||||
|
VkDescriptorSet allocateDescriptorSet(
|
||||||
|
VkDescriptorSetLayout layout);
|
||||||
|
|
||||||
void trackDrawBuffer();
|
void trackDrawBuffer();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -1,50 +1,10 @@
|
|||||||
#include "dxvk_descriptor.h"
|
#include "dxvk_descriptor.h"
|
||||||
|
#include "dxvk_device.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
DxvkDescriptorAlloc::DxvkDescriptorAlloc(
|
DxvkDescriptorPool::DxvkDescriptorPool(const Rc<vk::DeviceFn>& vkd)
|
||||||
const Rc<vk::DeviceFn>& vkd)
|
|
||||||
: m_vkd(vkd) {
|
: m_vkd(vkd) {
|
||||||
// Allocate one pool right away so that there
|
|
||||||
// is always at least one pool available when
|
|
||||||
// allocating a descriptor set
|
|
||||||
m_pools.push_back(createDescriptorPool());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DxvkDescriptorAlloc::~DxvkDescriptorAlloc() {
|
|
||||||
for (auto p : m_pools) {
|
|
||||||
m_vkd->vkDestroyDescriptorPool(
|
|
||||||
m_vkd->device(), p, nullptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
VkDescriptorSet DxvkDescriptorAlloc::alloc(VkDescriptorSetLayout layout) {
|
|
||||||
VkDescriptorSet set = allocFrom(m_pools[m_poolId], layout);
|
|
||||||
|
|
||||||
if (set == VK_NULL_HANDLE) {
|
|
||||||
if (++m_poolId >= m_pools.size())
|
|
||||||
m_pools.push_back(createDescriptorPool());
|
|
||||||
|
|
||||||
set = allocFrom(m_pools[m_poolId], layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
return set;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DxvkDescriptorAlloc::reset() {
|
|
||||||
for (auto p : m_pools) {
|
|
||||||
m_vkd->vkResetDescriptorPool(
|
|
||||||
m_vkd->device(), p, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_poolId = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
VkDescriptorPool DxvkDescriptorAlloc::createDescriptorPool() {
|
|
||||||
constexpr uint32_t MaxSets = 2048;
|
constexpr uint32_t MaxSets = 2048;
|
||||||
|
|
||||||
std::array<VkDescriptorPoolSize, 10> pools = {{
|
std::array<VkDescriptorPoolSize, 10> pools = {{
|
||||||
@ -67,21 +27,22 @@ namespace dxvk {
|
|||||||
info.poolSizeCount = pools.size();
|
info.poolSizeCount = pools.size();
|
||||||
info.pPoolSizes = pools.data();
|
info.pPoolSizes = pools.data();
|
||||||
|
|
||||||
VkDescriptorPool pool = VK_NULL_HANDLE;
|
if (m_vkd->vkCreateDescriptorPool(m_vkd->device(), &info, nullptr, &m_pool) != VK_SUCCESS)
|
||||||
if (m_vkd->vkCreateDescriptorPool(m_vkd->device(),
|
throw DxvkError("DxvkDescriptorPool: Failed to create descriptor pool");
|
||||||
&info, nullptr, &pool) != VK_SUCCESS)
|
|
||||||
throw DxvkError("DxvkDescriptorAlloc: Failed to create descriptor pool");
|
|
||||||
return pool;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VkDescriptorSet DxvkDescriptorAlloc::allocFrom(
|
DxvkDescriptorPool::~DxvkDescriptorPool() {
|
||||||
VkDescriptorPool pool,
|
m_vkd->vkDestroyDescriptorPool(
|
||||||
VkDescriptorSetLayout layout) const {
|
m_vkd->device(), m_pool, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VkDescriptorSet DxvkDescriptorPool::alloc(VkDescriptorSetLayout layout) {
|
||||||
VkDescriptorSetAllocateInfo info;
|
VkDescriptorSetAllocateInfo info;
|
||||||
info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
||||||
info.pNext = nullptr;
|
info.pNext = nullptr;
|
||||||
info.descriptorPool = pool;
|
info.descriptorPool = m_pool;
|
||||||
info.descriptorSetCount = 1;
|
info.descriptorSetCount = 1;
|
||||||
info.pSetLayouts = &layout;
|
info.pSetLayouts = &layout;
|
||||||
|
|
||||||
@ -91,4 +52,38 @@ namespace dxvk {
|
|||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxvkDescriptorPool::reset() {
|
||||||
|
m_vkd->vkResetDescriptorPool(
|
||||||
|
m_vkd->device(), m_pool, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
DxvkDescriptorPoolTracker::DxvkDescriptorPoolTracker(DxvkDevice* device)
|
||||||
|
: m_device(device) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DxvkDescriptorPoolTracker::~DxvkDescriptorPoolTracker() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxvkDescriptorPoolTracker::trackDescriptorPool(Rc<DxvkDescriptorPool> pool) {
|
||||||
|
m_pools.push_back(std::move(pool));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxvkDescriptorPoolTracker::reset() {
|
||||||
|
for (const auto& pool : m_pools) {
|
||||||
|
pool->reset();
|
||||||
|
m_device->recycleDescriptorPool(pool);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pools.clear();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
|
class DxvkDevice;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Descriptor info
|
* \brief Descriptor info
|
||||||
*
|
*
|
||||||
@ -20,21 +22,18 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Descriptor set allocator
|
* \brief Descriptor pool
|
||||||
*
|
*
|
||||||
* Creates descriptor pools on demand and
|
* Wrapper around a Vulkan descriptor pool that
|
||||||
* allocates descriptor sets from those pools.
|
* descriptor sets can be allocated from.
|
||||||
*/
|
*/
|
||||||
class DxvkDescriptorAlloc {
|
class DxvkDescriptorPool : public RcObject {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
DxvkDescriptorAlloc(
|
DxvkDescriptorPool(
|
||||||
const Rc<vk::DeviceFn>& vkd);
|
const Rc<vk::DeviceFn>& vkd);
|
||||||
~DxvkDescriptorAlloc();
|
~DxvkDescriptorPool();
|
||||||
|
|
||||||
DxvkDescriptorAlloc (const DxvkDescriptorAlloc&) = delete;
|
|
||||||
DxvkDescriptorAlloc& operator = (const DxvkDescriptorAlloc&) = delete;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Allocates a descriptor set
|
* \brief Allocates a descriptor set
|
||||||
@ -56,15 +55,45 @@ namespace dxvk {
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
Rc<vk::DeviceFn> m_vkd;
|
Rc<vk::DeviceFn> m_vkd;
|
||||||
|
VkDescriptorPool m_pool;
|
||||||
|
|
||||||
std::vector<VkDescriptorPool> m_pools;
|
};
|
||||||
size_t m_poolId = 0;
|
|
||||||
|
|
||||||
VkDescriptorPool createDescriptorPool();
|
|
||||||
|
|
||||||
VkDescriptorSet allocFrom(
|
/**
|
||||||
VkDescriptorPool pool,
|
* \brief Descriptor pool tracker
|
||||||
VkDescriptorSetLayout layout) const;
|
*
|
||||||
|
* Tracks descriptor pools that are either full
|
||||||
|
* or no longer needed by the DXVK context. The
|
||||||
|
* command list will reset and recycle all pools
|
||||||
|
* once it has completed execution on the GPU.
|
||||||
|
*/
|
||||||
|
class DxvkDescriptorPoolTracker {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
DxvkDescriptorPoolTracker(DxvkDevice* device);
|
||||||
|
~DxvkDescriptorPoolTracker();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Adds a descriptor pool to track
|
||||||
|
* \param [in] pool The descriptor pool
|
||||||
|
*/
|
||||||
|
void trackDescriptorPool(Rc<DxvkDescriptorPool> pool);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Resets event tracker
|
||||||
|
*
|
||||||
|
* Resets all tracked descriptor pools
|
||||||
|
* and returns them to the device.
|
||||||
|
*/
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
DxvkDevice* m_device;
|
||||||
|
|
||||||
|
std::vector<Rc<DxvkDescriptorPool>> m_pools;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -116,6 +116,16 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Rc<DxvkDescriptorPool> DxvkDevice::createDescriptorPool() {
|
||||||
|
Rc<DxvkDescriptorPool> pool = m_recycledDescriptorPools.retrieveObject();
|
||||||
|
|
||||||
|
if (pool == nullptr)
|
||||||
|
pool = new DxvkDescriptorPool(m_vkd);
|
||||||
|
|
||||||
|
return pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Rc<DxvkContext> DxvkDevice::createContext() {
|
Rc<DxvkContext> DxvkDevice::createContext() {
|
||||||
return new DxvkContext(this,
|
return new DxvkContext(this,
|
||||||
m_pipelineManager,
|
m_pipelineManager,
|
||||||
@ -296,4 +306,9 @@ namespace dxvk {
|
|||||||
m_recycledCommandLists.returnObject(cmdList);
|
m_recycledCommandLists.returnObject(cmdList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxvkDevice::recycleDescriptorPool(const Rc<DxvkDescriptorPool>& pool) {
|
||||||
|
m_recycledDescriptorPools.returnObject(pool);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,7 @@ namespace dxvk {
|
|||||||
class DxvkDevice : public RcObject {
|
class DxvkDevice : public RcObject {
|
||||||
friend class DxvkContext;
|
friend class DxvkContext;
|
||||||
friend class DxvkSubmissionQueue;
|
friend class DxvkSubmissionQueue;
|
||||||
|
friend class DxvkDescriptorPoolTracker;
|
||||||
|
|
||||||
constexpr static VkDeviceSize DefaultStagingBufferSize = 4 * 1024 * 1024;
|
constexpr static VkDeviceSize DefaultStagingBufferSize = 4 * 1024 * 1024;
|
||||||
public:
|
public:
|
||||||
@ -178,6 +179,16 @@ namespace dxvk {
|
|||||||
*/
|
*/
|
||||||
Rc<DxvkCommandList> createCommandList();
|
Rc<DxvkCommandList> createCommandList();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Creates a descriptor pool
|
||||||
|
*
|
||||||
|
* Returns a previously recycled pool, or creates
|
||||||
|
* a new one if necessary. The context should take
|
||||||
|
* ownership of the returned pool.
|
||||||
|
* \returns Descriptor pool
|
||||||
|
*/
|
||||||
|
Rc<DxvkDescriptorPool> createDescriptorPool();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Creates a context
|
* \brief Creates a context
|
||||||
*
|
*
|
||||||
@ -414,6 +425,7 @@ namespace dxvk {
|
|||||||
DxvkDeviceQueue m_presentQueue;
|
DxvkDeviceQueue m_presentQueue;
|
||||||
|
|
||||||
DxvkRecycler<DxvkCommandList, 16> m_recycledCommandLists;
|
DxvkRecycler<DxvkCommandList, 16> m_recycledCommandLists;
|
||||||
|
DxvkRecycler<DxvkDescriptorPool, 16> m_recycledDescriptorPools;
|
||||||
DxvkRecycler<DxvkStagingBuffer, 4> m_recycledStagingBuffers;
|
DxvkRecycler<DxvkStagingBuffer, 4> m_recycledStagingBuffers;
|
||||||
|
|
||||||
DxvkSubmissionQueue m_submissionQueue;
|
DxvkSubmissionQueue m_submissionQueue;
|
||||||
@ -421,6 +433,9 @@ namespace dxvk {
|
|||||||
void recycleCommandList(
|
void recycleCommandList(
|
||||||
const Rc<DxvkCommandList>& cmdList);
|
const Rc<DxvkCommandList>& cmdList);
|
||||||
|
|
||||||
|
void recycleDescriptorPool(
|
||||||
|
const Rc<DxvkDescriptorPool>& pool);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Dummy buffer handle
|
* \brief Dummy buffer handle
|
||||||
* \returns Use for unbound vertex buffers.
|
* \returns Use for unbound vertex buffers.
|
||||||
|
Loading…
Reference in New Issue
Block a user