mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-30 07:54:15 +01:00
Implement descriptor update batching and push descriptors
Batching helps to avoid the need to attach so many objects to the fence cycle, which ends up taking a fair bit of time due to the allocation required.
This commit is contained in:
parent
62a165b51e
commit
9ce848d4e0
@ -26,15 +26,23 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
|||||||
textures{manager, registerBundle.texturePoolRegisters},
|
textures{manager, registerBundle.texturePoolRegisters},
|
||||||
directState{activeState.directState} {
|
directState{activeState.directState} {
|
||||||
executor.AddFlushCallback([this] {
|
executor.AddFlushCallback([this] {
|
||||||
|
if (attachedDescriptorSets) {
|
||||||
|
ctx.executor.AttachDependency(attachedDescriptorSets);
|
||||||
|
attachedDescriptorSets = nullptr;
|
||||||
|
activeDescriptorSet = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
activeState.MarkAllDirty();
|
activeState.MarkAllDirty();
|
||||||
constantBuffers.MarkAllDirty();
|
constantBuffers.MarkAllDirty();
|
||||||
samplers.MarkAllDirty();
|
samplers.MarkAllDirty();
|
||||||
textures.MarkAllDirty();
|
textures.MarkAllDirty();
|
||||||
quadConversionBufferAttached = false;
|
quadConversionBufferAttached = false;
|
||||||
|
constantBuffers.DisableQuickBind();
|
||||||
});
|
});
|
||||||
|
|
||||||
executor.AddPipelineChangeCallback([this] {
|
executor.AddPipelineChangeCallback([this] {
|
||||||
activeState.MarkAllDirty();
|
activeState.MarkAllDirty();
|
||||||
|
activeDescriptorSet = nullptr;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,14 +240,23 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
|||||||
builder.SetPipeline(pipeline->compiledPipeline.pipeline);
|
builder.SetPipeline(pipeline->compiledPipeline.pipeline);
|
||||||
|
|
||||||
if (descUpdateInfo) {
|
if (descUpdateInfo) {
|
||||||
auto newSet{std::make_shared<DescriptorAllocator::ActiveDescriptorSet>(ctx.gpu.descriptor.AllocateSet(descUpdateInfo->descriptorSetLayout))};
|
if (ctx.gpu.traits.supportsPushDescriptors) {
|
||||||
ctx.executor.cycle->AttachObject(newSet);
|
builder.SetDescriptorSetWithPush(descUpdateInfo);
|
||||||
|
} else {
|
||||||
|
if (!attachedDescriptorSets)
|
||||||
|
attachedDescriptorSets = std::make_shared<boost::container::static_vector<DescriptorAllocator::ActiveDescriptorSet, DescriptorBatchSize>>();
|
||||||
|
|
||||||
// Descriptor set lifetime is bound to the current cycle so we can safely use a raw pointer from now on
|
auto newSet{&attachedDescriptorSets->emplace_back(ctx.gpu.descriptor.AllocateSet(descUpdateInfo->descriptorSetLayout))};
|
||||||
auto *oldSet{activeDescriptorSet};
|
auto *oldSet{activeDescriptorSet};
|
||||||
activeDescriptorSet = newSet.get();
|
activeDescriptorSet = newSet;
|
||||||
|
|
||||||
builder.SetDescriptorSetWithUpdate(descUpdateInfo, activeDescriptorSet, oldSet);
|
builder.SetDescriptorSetWithUpdate(descUpdateInfo, activeDescriptorSet, oldSet);
|
||||||
|
|
||||||
|
if (attachedDescriptorSets->size() == DescriptorBatchSize) {
|
||||||
|
ctx.executor.AttachDependency(attachedDescriptorSets);
|
||||||
|
attachedDescriptorSets.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto stateUpdater{builder.Build()};
|
auto stateUpdater{builder.Build()};
|
||||||
|
@ -48,6 +48,8 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
|||||||
std::shared_ptr<memory::Buffer> quadConversionBuffer{};
|
std::shared_ptr<memory::Buffer> quadConversionBuffer{};
|
||||||
bool quadConversionBufferAttached{};
|
bool quadConversionBufferAttached{};
|
||||||
|
|
||||||
|
static constexpr size_t DescriptorBatchSize{0x100};
|
||||||
|
std::shared_ptr<boost::container::static_vector<DescriptorAllocator::ActiveDescriptorSet, DescriptorBatchSize>> attachedDescriptorSets;
|
||||||
DescriptorAllocator::ActiveDescriptorSet *activeDescriptorSet{};
|
DescriptorAllocator::ActiveDescriptorSet *activeDescriptorSet{};
|
||||||
|
|
||||||
size_t UpdateQuadConversionBuffer(u32 count, u32 firstVertex);
|
size_t UpdateQuadConversionBuffer(u32 count, u32 firstVertex);
|
||||||
|
@ -205,31 +205,36 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the destination/(source) descriptor set(s) for all writes/(copies)
|
if constexpr (PushDescriptor) {
|
||||||
for (auto &write : updateInfo->writes)
|
commandBuffer.pushDescriptorSetKHR(updateInfo->bindPoint, updateInfo->pipelineLayout, updateInfo->descriptorSetIndex, updateInfo->writes);
|
||||||
write.dstSet = **dstSet;
|
} else {
|
||||||
|
// Set the destination/(source) descriptor set(s) for all writes/(copies)
|
||||||
|
for (auto &write : updateInfo->writes)
|
||||||
|
write.dstSet = **dstSet;
|
||||||
|
|
||||||
for (auto © : updateInfo->copies) {
|
for (auto © : updateInfo->copies) {
|
||||||
copy.dstSet = **dstSet;
|
copy.dstSet = **dstSet;
|
||||||
copy.srcSet = **srcSet;
|
copy.srcSet = **srcSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform the updates, doing copies first to avoid overwriting
|
||||||
|
if (!updateInfo->copies.empty())
|
||||||
|
gpu.vkDevice.updateDescriptorSets({}, updateInfo->copies);
|
||||||
|
|
||||||
|
if (!updateInfo->writes.empty())
|
||||||
|
gpu.vkDevice.updateDescriptorSets(updateInfo->writes, {});
|
||||||
|
|
||||||
|
// Bind the updated descriptor set and we're done!
|
||||||
|
commandBuffer.bindDescriptorSets(updateInfo->bindPoint, updateInfo->pipelineLayout, updateInfo->descriptorSetIndex, **dstSet, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform the updates, doing copies first to avoid overwriting
|
|
||||||
if (!updateInfo->copies.empty())
|
|
||||||
gpu.vkDevice.updateDescriptorSets({}, updateInfo->copies);
|
|
||||||
|
|
||||||
if (!updateInfo->writes.empty())
|
|
||||||
gpu.vkDevice.updateDescriptorSets(updateInfo->writes, {});
|
|
||||||
|
|
||||||
// Bind the updated descriptor set and we're done!
|
|
||||||
commandBuffer.bindDescriptorSets(updateInfo->bindPoint, updateInfo->pipelineLayout, updateInfo->descriptorSetIndex, **dstSet, {});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DescriptorUpdateInfo *updateInfo;
|
DescriptorUpdateInfo *updateInfo;
|
||||||
DescriptorAllocator::ActiveDescriptorSet *srcSet;
|
DescriptorAllocator::ActiveDescriptorSet *srcSet;
|
||||||
DescriptorAllocator::ActiveDescriptorSet *dstSet;
|
DescriptorAllocator::ActiveDescriptorSet *dstSet;
|
||||||
};
|
};
|
||||||
using SetDescriptorSetWithUpdateCmd = CmdHolder<SetDescriptorSetWithUpdateCmdImpl>;
|
using SetDescriptorSetWithUpdateCmd = CmdHolder<SetDescriptorSetCmdImpl<false>>;
|
||||||
|
using SetDescriptorSetWithPushCmd = CmdHolder<SetDescriptorSetCmdImpl<true>>;
|
||||||
|
|
||||||
struct SetPipelineCmdImpl {
|
struct SetPipelineCmdImpl {
|
||||||
void Record(GPU &gpu, vk::raii::CommandBuffer &commandBuffer) {
|
void Record(GPU &gpu, vk::raii::CommandBuffer &commandBuffer) {
|
||||||
|
Loading…
Reference in New Issue
Block a user