mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-14 22:29:15 +01:00
[dxvk] Introduce updatePageTable
This commit is contained in:
parent
12d2f8a9d4
commit
d5348a0cf0
@ -2460,6 +2460,97 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxvkContext::updatePageTable(
|
||||||
|
const DxvkSparseBindInfo& bindInfo,
|
||||||
|
DxvkSparseBindFlags flags) {
|
||||||
|
// Split command buffers here so that we execute
|
||||||
|
// the sparse binding operation at the right time
|
||||||
|
if (!flags.test(DxvkSparseBindFlag::SkipSynchronization))
|
||||||
|
this->splitCommands();
|
||||||
|
|
||||||
|
DxvkSparsePageAllocator* srcAllocator = bindInfo.srcAllocator.ptr();
|
||||||
|
DxvkSparsePageTable* dstPageTable = bindInfo.dstResource->getSparsePageTable();
|
||||||
|
DxvkSparsePageTable* srcPageTable = nullptr;
|
||||||
|
|
||||||
|
if (bindInfo.srcResource != nullptr)
|
||||||
|
srcPageTable = bindInfo.srcResource->getSparsePageTable();
|
||||||
|
|
||||||
|
// In order to support copies properly, we need to buffer the new
|
||||||
|
// mappings first before we apply them to the destination resource.
|
||||||
|
size_t bindCount = bindInfo.binds.size();
|
||||||
|
std::vector<DxvkSparseMapping> mappings(bindCount);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < bindCount; i++) {
|
||||||
|
DxvkSparseBind bind = bindInfo.binds[i];
|
||||||
|
|
||||||
|
switch (bind.mode) {
|
||||||
|
case DxvkSparseBindMode::Null:
|
||||||
|
// The mapping array is already default-initialized
|
||||||
|
// so we don't actually need to do anything here
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DxvkSparseBindMode::Bind:
|
||||||
|
mappings[i] = srcAllocator->acquirePage(bind.srcPage);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DxvkSparseBindMode::Copy:
|
||||||
|
mappings[i] = srcPageTable->getMapping(bind.srcPage);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process the actual page table updates here and resolve
|
||||||
|
// our internal structures to Vulkan resource and memory
|
||||||
|
// handles. The rest will be done at submission time.
|
||||||
|
for (size_t i = 0; i < bindCount; i++) {
|
||||||
|
DxvkSparseBind bind = bindInfo.binds[i];
|
||||||
|
DxvkSparseMapping mapping = std::move(mappings[i]);
|
||||||
|
|
||||||
|
DxvkSparsePageInfo pageInfo = dstPageTable->getPageInfo(bind.dstPage);
|
||||||
|
|
||||||
|
switch (pageInfo.type) {
|
||||||
|
case DxvkSparsePageType::None:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DxvkSparsePageType::Buffer: {
|
||||||
|
DxvkSparseBufferBindKey key;
|
||||||
|
key.buffer = dstPageTable->getBufferHandle();
|
||||||
|
key.offset = pageInfo.buffer.offset;
|
||||||
|
key.size = pageInfo.buffer.length;
|
||||||
|
|
||||||
|
m_cmd->bindBufferMemory(key, mapping.getHandle());
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case DxvkSparsePageType::Image: {
|
||||||
|
DxvkSparseImageBindKey key;
|
||||||
|
key.image = dstPageTable->getImageHandle();
|
||||||
|
key.subresource = pageInfo.image.subresource;
|
||||||
|
key.offset = pageInfo.image.offset;
|
||||||
|
key.extent = pageInfo.image.extent;
|
||||||
|
|
||||||
|
m_cmd->bindImageMemory(key, mapping.getHandle());
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case DxvkSparsePageType::ImageMipTail: {
|
||||||
|
DxvkSparseImageOpaqueBindKey key;
|
||||||
|
key.image = dstPageTable->getImageHandle();
|
||||||
|
key.offset = pageInfo.mipTail.resourceOffset;
|
||||||
|
key.size = pageInfo.mipTail.resourceLength;
|
||||||
|
key.flags = 0;
|
||||||
|
|
||||||
|
m_cmd->bindImageOpaqueMemory(key, mapping.getHandle());
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the page table mapping for tracking purposes
|
||||||
|
if (pageInfo.type != DxvkSparsePageType::None)
|
||||||
|
dstPageTable->updateMapping(m_cmd.ptr(), bind.dstPage, std::move(mapping));
|
||||||
|
}
|
||||||
|
|
||||||
|
m_cmd->trackResource<DxvkAccess::Write>(bindInfo.dstResource);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxvkContext::signalGpuEvent(const Rc<DxvkGpuEvent>& event) {
|
void DxvkContext::signalGpuEvent(const Rc<DxvkGpuEvent>& event) {
|
||||||
this->spillRenderPass(true);
|
this->spillRenderPass(true);
|
||||||
|
|
||||||
|
@ -1170,7 +1170,18 @@ namespace dxvk {
|
|||||||
*/
|
*/
|
||||||
void setBarrierControl(
|
void setBarrierControl(
|
||||||
DxvkBarrierControlFlags control);
|
DxvkBarrierControlFlags control);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Updates page table for a given sparse resource
|
||||||
|
*
|
||||||
|
* Note that this is a very high overhead operation.
|
||||||
|
* \param [in] bindInfo Sparse bind info
|
||||||
|
* \param [in] flags Sparse bind flags
|
||||||
|
*/
|
||||||
|
void updatePageTable(
|
||||||
|
const DxvkSparseBindInfo& bindInfo,
|
||||||
|
DxvkSparseBindFlags flags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Launches a Cuda kernel
|
* \brief Launches a Cuda kernel
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user