1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-01-31 23:52:20 +01:00

[dxvk] Remove direct resource allocation tracking

Track the containing virtual resources instead and only explicitly
keep allocations alive through invalidations.
This commit is contained in:
Philip Rebohle 2024-10-17 14:41:27 +02:00 committed by Philip Rebohle
parent 863ce5f117
commit 56e8d55830
9 changed files with 39 additions and 75 deletions

View File

@ -255,14 +255,12 @@ namespace dxvk {
* the device can guarantee that the submission has
* completed.
*/
template<DxvkAccess Access>
void trackResource(Rc<DxvkResourceAllocation>&& rc) {
m_resources.trackResource(DxvkLifetime<DxvkResourceAllocation>(std::move(rc), Access));
m_resources.trackResource(std::move(rc));
}
template<DxvkAccess Access>
void trackResource(const Rc<DxvkResourceAllocation>& rc) {
m_resources.trackResource(DxvkLifetime<DxvkResourceAllocation>(rc.ptr(), Access));
m_resources.trackResource(Rc<DxvkResourceAllocation>(rc));
}
template<DxvkAccess Access, typename T>

View File

@ -1381,7 +1381,7 @@ namespace dxvk {
const Rc<DxvkBuffer>& buffer,
Rc<DxvkResourceAllocation>&& slice) {
Rc<DxvkResourceAllocation> prevAllocation = buffer->assignStorage(std::move(slice));
m_cmd->trackResource<DxvkAccess::None>(std::move(prevAllocation));
m_cmd->trackResource(std::move(prevAllocation));
// We also need to update all bindings that the buffer
// may be bound to either directly or through views.
@ -1437,7 +1437,7 @@ namespace dxvk {
Rc<DxvkResourceAllocation>&& slice,
const DxvkImageUsageInfo& usageInfo) {
Rc<DxvkResourceAllocation> prevAllocation = image->assignStorageWithUsage(std::move(slice), usageInfo);
m_cmd->trackResource<DxvkAccess::None>(std::move(prevAllocation));
m_cmd->trackResource(std::move(prevAllocation));
VkImageUsageFlags usage = image->info().usage;

View File

@ -28,14 +28,14 @@ namespace dxvk {
DxvkLifetime(
Rc<Tx>&& resource,
DxvkAccess access)
: m_ptr(reinterpret_cast<uintptr_t>(resource.ptr()) | uintptr_t(access)) {
: m_ptr(reinterpret_cast<uintptr_t>(static_cast<DxvkResource*>(resource.ptr())) | uintptr_t(access)) {
resource.unsafeExtract()->convertRef(DxvkAccess::None, access);
}
DxvkLifetime(
const T* resource,
DxvkAccess access)
: m_ptr(reinterpret_cast<uintptr_t>(resource) | uintptr_t(access)) {
: m_ptr(reinterpret_cast<uintptr_t>(static_cast<const DxvkResource*>(resource)) | uintptr_t(access)) {
acquire();
}
@ -145,7 +145,7 @@ namespace dxvk {
* \brief Adds a resource allocation to track
* \param [in] res The allocation to track
*/
void trackResource(DxvkLifetime<DxvkResourceAllocation>&& res) {
void trackResource(Rc<DxvkResourceAllocation>&& res) {
m_allocations.push_back(std::move(res));
}
@ -164,7 +164,7 @@ namespace dxvk {
std::vector<Rc<DxvkGpuQuery>> m_queries;
std::vector<DxvkLifetime<DxvkResource>> m_resources;
std::vector<DxvkLifetime<DxvkResourceAllocation>> m_allocations;
std::vector<Rc<DxvkResourceAllocation>> m_allocations;
};

View File

@ -476,60 +476,22 @@ namespace dxvk {
~DxvkResourceAllocation();
force_inline void incRef() { acquire(DxvkAccess::None); }
force_inline void decRef() { release(DxvkAccess::None); }
/**
* \brief Releases allocation
*
* Increments the use counter of the allocation.
* \param [in] access Resource access
* \brief Increments reference count
*/
force_inline void acquire(DxvkAccess access) {
m_useCount.fetch_add(getIncrement(access), std::memory_order_acquire);
force_inline void incRef() {
m_useCount.fetch_add(1u, std::memory_order_acquire);
}
/**
* \brief Releases allocation
*
* Decrements the use counter and frees the allocation if necessary.
* \param [in] access Resource access
* \brief Decrements reference count
* Frees allocation if necessary
*/
force_inline void release(DxvkAccess access) {
uint64_t increment = getIncrement(access);
uint64_t remaining = m_useCount.fetch_sub(increment, std::memory_order_release) - increment;
if (unlikely(!remaining))
force_inline void decRef() {
if (unlikely(m_useCount.fetch_sub(1u, std::memory_order_acquire) == 1u))
free();
}
/**
* \brief Converts reference
*
* Decrements and increments the use counter according
* to the given access types in a single operation.
* \param [in] from Previous access type
* \param [in] to New access type
*/
force_inline void convertRef(DxvkAccess from, DxvkAccess to) {
uint64_t increment = getIncrement(to) - getIncrement(from);
if (increment)
m_useCount.fetch_add(increment, std::memory_order_acq_rel);
}
/**
* \brief Checks whether the resource is in use
*
* Note that when checking for read access, this will also
* return \c true if the resource is being written to.
* \param [in] access Access to check
*/
force_inline bool isInUse(DxvkAccess access) const {
uint64_t cur = m_useCount.load(std::memory_order_acquire);
return cur >= getIncrement(access);
}
/**
* \brief Queries allocation flags
* \returns Allocation flags
@ -623,11 +585,11 @@ namespace dxvk {
private:
std::atomic<uint64_t> m_useCount = { 0u };
uint32_t m_resourceCookie = 0u;
std::atomic<uint32_t> m_useCount = { 0u };
DxvkAllocationFlags m_flags = 0u;
uint64_t m_resourceCookie = 0u;
VkDeviceMemory m_memory = VK_NULL_HANDLE;
VkDeviceSize m_address = 0u;
VkDeviceSize m_size = 0u;

View File

@ -395,7 +395,7 @@ namespace dxvk {
DxvkSparseMapping&& mapping) {
if (m_mappings[page] != mapping) {
if (m_mappings[page])
cmd->trackResource<DxvkAccess::None>(m_mappings[page].m_page);
cmd->trackResource(m_mappings[page].m_page);
m_mappings[page] = std::move(mapping);
}

View File

@ -344,7 +344,7 @@ namespace dxvk {
ctx.cmd->trackResource<DxvkAccess::Write>(dstView->image());
if (m_gammaImage)
ctx.cmd->trackResource<DxvkAccess::Read>(m_gammaImage->storage());
ctx.cmd->trackResource<DxvkAccess::Read>(m_gammaImage);
ctx.cmd->trackSampler(m_samplerGamma);
ctx.cmd->trackSampler(m_samplerPresent);
@ -444,8 +444,8 @@ namespace dxvk {
ctx.cmd->cmdPipelineBarrier(DxvkCmdBuffer::ExecBuffer, &depInfo);
ctx.cmd->trackResource<DxvkAccess::Read>(buffer->storage());
ctx.cmd->trackResource<DxvkAccess::Write>(image->storage());
ctx.cmd->trackResource<DxvkAccess::Read>(buffer);
ctx.cmd->trackResource<DxvkAccess::Write>(image);
}

View File

@ -373,7 +373,7 @@ namespace dxvk::hud {
drawInfoBuffer, textBufferView, 2u);
// Make sure GPU resources are being kept alive as necessary
ctx.cmd->trackResource<DxvkAccess::Write>(m_gpuBuffer->storage());
ctx.cmd->trackResource<DxvkAccess::Write>(m_gpuBuffer);
ctx.cmd->trackQuery(Rc<DxvkGpuQuery>(m_query));
}
@ -419,7 +419,7 @@ namespace dxvk::hud {
ctx.cmd->cmdDraw(4, 1, 0, 0);
ctx.cmd->trackResource<DxvkAccess::Read>(m_gpuBuffer->storage());
ctx.cmd->trackResource<DxvkAccess::Read>(m_gpuBuffer);
}
@ -473,7 +473,7 @@ namespace dxvk::hud {
depInfo.pMemoryBarriers = &barrier;
ctx.cmd->cmdPipelineBarrier(DxvkCmdBuffer::InitBuffer, &depInfo);
ctx.cmd->trackResource<DxvkAccess::Write>(m_gpuBuffer->storage());
ctx.cmd->trackResource<DxvkAccess::Write>(m_gpuBuffer);
m_query = m_device->createRawQuery(VK_QUERY_TYPE_TIMESTAMP);
}
@ -1146,7 +1146,7 @@ namespace dxvk::hud {
VkDescriptorBufferInfo drawDescriptor = { };
VkDescriptorBufferInfo dataDescriptor = { };
updateDataBuffer(drawDescriptor, dataDescriptor);
updateDataBuffer(ctx, drawDescriptor, dataDescriptor);
std::array<VkWriteDescriptorSet, 2> descriptorWrites = {{
{ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, nullptr,
@ -1176,13 +1176,14 @@ namespace dxvk::hud {
ctx.cmd->cmdDraw(4, m_drawInfos.size(), 0, 0);
// Track data buffer lifetime
ctx.cmd->trackResource<DxvkAccess::Read>(m_dataBuffer->storage());
ctx.cmd->trackResource<DxvkAccess::Read>(m_dataBuffer);
m_drawInfos.clear();
}
void HudMemoryDetailsItem::updateDataBuffer(
const DxvkContextObjects& ctx,
VkDescriptorBufferInfo& drawDescriptor,
VkDescriptorBufferInfo& dataDescriptor) {
size_t drawInfoSize = m_drawInfos.size() * sizeof(DrawInfo);
@ -1206,7 +1207,8 @@ namespace dxvk::hud {
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
} else {
// Ensure we can update the buffer without overriding live data
m_dataBuffer->assignStorage(m_dataBuffer->allocateStorage());
auto allocation = m_dataBuffer->assignStorage(m_dataBuffer->allocateStorage());
ctx.cmd->trackResource(std::move(allocation));
}
// Update draw infos and pad unused area with zeroes

View File

@ -585,6 +585,7 @@ namespace dxvk::hud {
HudRenderer& renderer);
void updateDataBuffer(
const DxvkContextObjects& ctx,
VkDescriptorBufferInfo& drawDescriptor,
VkDescriptorBufferInfo& dataDescriptor);

View File

@ -155,7 +155,8 @@ namespace dxvk::hud {
m_textBufferView = m_textBuffer->createView(textViewInfo);
} else {
// Discard and invalidate buffer so we can safely update it
m_textBuffer->assignStorage(Rc<DxvkResourceAllocation>(m_textBuffer->allocateStorage()));
auto storage = m_textBuffer->assignStorage(Rc<DxvkResourceAllocation>(m_textBuffer->allocateStorage()));
ctx.cmd->trackResource(std::move(storage));
}
// Upload aligned text data in such a way that we write full cache lines
@ -190,9 +191,9 @@ namespace dxvk::hud {
m_textBufferView->handle(), m_textDraws.size());
// Ensure all used resources are kept alive
ctx.cmd->trackResource<DxvkAccess::None>(m_textBuffer->storage());
ctx.cmd->trackResource<DxvkAccess::Read>(m_fontBuffer->storage());
ctx.cmd->trackResource<DxvkAccess::Read>(m_fontTexture->storage());
ctx.cmd->trackResource<DxvkAccess::Read>(m_textBuffer);
ctx.cmd->trackResource<DxvkAccess::Read>(m_fontBuffer);
ctx.cmd->trackResource<DxvkAccess::Read>(m_fontTexture);
ctx.cmd->trackSampler(m_fontSampler);
// Reset internal text buffers
@ -481,9 +482,9 @@ namespace dxvk::hud {
ctx.cmd->cmdPipelineBarrier(DxvkCmdBuffer::InitBuffer, &depInfo);
ctx.cmd->trackResource<DxvkAccess::Read>(uploadBuffer->storage());
ctx.cmd->trackResource<DxvkAccess::Write>(m_fontBuffer->storage());
ctx.cmd->trackResource<DxvkAccess::Write>(m_fontTexture->storage());
ctx.cmd->trackResource<DxvkAccess::Read>(uploadBuffer);
ctx.cmd->trackResource<DxvkAccess::Write>(m_fontBuffer);
ctx.cmd->trackResource<DxvkAccess::Write>(m_fontTexture);
}