mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-05 16:25:10 +01:00
Implement descriptor set updating through StateUpdater
Will automatically resolve buffer views at record-time into descriptor write/copy structures then apply the write and bind the set.
This commit is contained in:
parent
d174ca950b
commit
04cea9239f
@ -69,4 +69,15 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
using DirtyManager = dirty::Manager<soc::gm20b::engine::EngineMethodsEnd * sizeof(u32), sizeof(u32)>;
|
||||
|
||||
class StateUpdateBuilder;
|
||||
|
||||
struct DescriptorUpdateInfo {
|
||||
span<vk::CopyDescriptorSet> copies; //!< These will be performed before writes
|
||||
span<vk::WriteDescriptorSet> writes;
|
||||
span<vk::DescriptorBufferInfo> bufferDescs;
|
||||
span<DynamicBufferBinding> bufferDescDynamicBindings;
|
||||
vk::PipelineLayout pipelineLayout;
|
||||
vk::DescriptorSetLayout descriptorSetLayout;
|
||||
vk::PipelineBindPoint bindPoint;
|
||||
u32 descriptorSetIndex;
|
||||
};
|
||||
}
|
||||
|
@ -169,14 +169,29 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
activeState.Update(ctx, builder, indexed, topology, count);
|
||||
Pipeline *pipeline{activeState.GetPipeline()};
|
||||
|
||||
auto *descUpdateInfo{[&]() -> DescriptorUpdateInfo * {
|
||||
if (((oldPipeline == pipeline) || (oldPipeline && oldPipeline->CheckBindingMatch(pipeline))) && constantBuffers.quickBindEnabled) {
|
||||
// If bindings between the old and new pipelines are the same we can reuse the descriptor sets given that quick bind is enabled (meaning that no buffer updates or calls to non-graphics engines have occurred that could invalidate them)
|
||||
if (constantBuffers.quickBind)
|
||||
// If only a single constant buffer has been rebound between draws we can perform a partial descriptor update
|
||||
pipeline->SyncDescriptorsQuickBind(ctx, constantBuffers.boundConstantBuffers, *constantBuffers.quickBind);
|
||||
return pipeline->SyncDescriptorsQuickBind(ctx, constantBuffers.boundConstantBuffers, *constantBuffers.quickBind);
|
||||
else
|
||||
return nullptr;
|
||||
} else {
|
||||
// If bindings have changed or quick bind is disabled, perform a full descriptor update
|
||||
pipeline->SyncDescriptors(ctx, constantBuffers.boundConstantBuffers);
|
||||
return pipeline->SyncDescriptors(ctx, constantBuffers.boundConstantBuffers);
|
||||
}
|
||||
}()};
|
||||
|
||||
if (descUpdateInfo) {
|
||||
auto newSet{std::make_shared<DescriptorAllocator::ActiveDescriptorSet>(ctx.gpu.descriptor.AllocateSet(descUpdateInfo->descriptorSetLayout))};
|
||||
ctx.executor.cycle->AttachObject(newSet);
|
||||
|
||||
// Descriptor set lifetime is bound to the current cycle so we can safely use a raw pointer from now on
|
||||
auto *oldSet{activeDescriptorSet};
|
||||
activeDescriptorSet = newSet.get();
|
||||
|
||||
builder.SetDescriptorSetWithUpdate(descUpdateInfo, activeDescriptorSet, oldSet);
|
||||
}
|
||||
|
||||
const auto &surfaceClip{clearEngineRegisters.surfaceClip};
|
||||
@ -186,8 +201,8 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
};
|
||||
|
||||
auto stateUpdater{builder.Build()};
|
||||
ctx.executor.AddSubpass([stateUpdater](vk::raii::CommandBuffer &commandBuffer, const std::shared_ptr<FenceCycle> &, GPU &, vk::RenderPass, u32) {
|
||||
stateUpdater.RecordAll(commandBuffer);
|
||||
ctx.executor.AddSubpass([stateUpdater](vk::raii::CommandBuffer &commandBuffer, const std::shared_ptr<FenceCycle> &, GPU &gpu, vk::RenderPass, u32) {
|
||||
stateUpdater.RecordAll(gpu, commandBuffer);
|
||||
}, scissor, {}, activeState.GetColorAttachments(), activeState.GetDepthAttachment());
|
||||
|
||||
constantBuffers.ResetQuickBind();
|
||||
|
@ -39,6 +39,8 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
ClearEngineRegisters clearEngineRegisters;
|
||||
ConstantBuffers constantBuffers;
|
||||
|
||||
DescriptorAllocator::ActiveDescriptorSet *activeDescriptorSet{};
|
||||
|
||||
vk::Rect2D GetClearScissor();
|
||||
|
||||
public:
|
||||
|
@ -609,7 +609,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
}
|
||||
|
||||
// TODO: EXEC ID FOR STORAGE BUFS PURGE REMAP
|
||||
void Pipeline::SyncDescriptors(InterconnectContext &ctx, ConstantBufferSet &constantBuffers) {
|
||||
DescriptorUpdateInfo *Pipeline::SyncDescriptors(InterconnectContext &ctx, ConstantBufferSet &constantBuffers) {
|
||||
u32 bindingIdx{};
|
||||
u32 writeIdx{};
|
||||
u32 bufferIdx{};
|
||||
@ -617,7 +617,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
|
||||
auto writes{ctx.executor.allocator->AllocateUntracked<vk::WriteDescriptorSet>(descriptorInfo.writeDescCount)};
|
||||
auto bufferDescs{ctx.executor.allocator->AllocateUntracked<vk::DescriptorBufferInfo>(descriptorInfo.totalBufferDescCount)};
|
||||
auto bufferDescViews{ctx.executor.allocator->AllocateUntracked<DynamicBufferBinding>(descriptorInfo.totalBufferDescCount)};
|
||||
auto bufferDescDynamicBindings{ctx.executor.allocator->AllocateUntracked<DynamicBufferBinding>(descriptorInfo.totalBufferDescCount)};
|
||||
|
||||
auto writeBufferDescs{[&](vk::DescriptorType type, const auto &descs, u32 count, auto getBufferCb) {
|
||||
if (!descs.empty()) {
|
||||
@ -631,7 +631,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
for (size_t descIdx{}; descIdx < descs.size(); descIdx++) {
|
||||
const auto &shaderDesc{descs[descIdx]};
|
||||
for (size_t arrayIdx{}; arrayIdx < shaderDesc.count; arrayIdx++)
|
||||
bufferDescViews[bufferIdx++] = getBufferCb(shaderDesc, descIdx, arrayIdx);
|
||||
bufferDescDynamicBindings[bufferIdx++] = getBufferCb(shaderDesc, descIdx, arrayIdx);
|
||||
}
|
||||
}
|
||||
}};
|
||||
@ -652,22 +652,35 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
return GetStorageBufferBinding(ctx, stage.info, constantBuffers[i][desc.cbuf_index], storageBufferViews[descIdx], descIdx);
|
||||
});
|
||||
}
|
||||
|
||||
return ctx.executor.allocator->EmplaceUntracked<DescriptorUpdateInfo>(DescriptorUpdateInfo{
|
||||
.writes = writes,
|
||||
.bufferDescs = bufferDescs,
|
||||
.bufferDescDynamicBindings = bufferDescDynamicBindings,
|
||||
.pipelineLayout = compiledPipeline.pipelineLayout,
|
||||
.descriptorSetLayout = compiledPipeline.descriptorSetLayout,
|
||||
.bindPoint = vk::PipelineBindPoint::eGraphics,
|
||||
.descriptorSetIndex = 0,
|
||||
});
|
||||
}
|
||||
|
||||
void Pipeline::SyncDescriptorsQuickBind(InterconnectContext &ctx, ConstantBufferSet &constantBuffers, ConstantBuffers::QuickBind quickBind) {
|
||||
const auto &cbufUsageInfo{descriptorInfo.cbufUsages[static_cast<size_t>(quickBind.stage)][quickBind.index]};
|
||||
const auto &shaderInfo{shaderStages[static_cast<size_t>(quickBind.stage)].info};
|
||||
auto &stageConstantBuffers{constantBuffers[static_cast<size_t>(quickBind.stage)]};
|
||||
auto copy{ctx.executor.allocator->AllocateUntracked<vk::CopyDescriptorSet>()};
|
||||
DescriptorUpdateInfo *Pipeline::SyncDescriptorsQuickBind(InterconnectContext &ctx, ConstantBufferSet &constantBuffers, ConstantBuffers::QuickBind quickBind) {
|
||||
size_t stageIndex{static_cast<size_t>(quickBind.stage)};
|
||||
|
||||
const auto &cbufUsageInfo{descriptorInfo.cbufUsages[stageIndex][quickBind.index]};
|
||||
const auto &shaderInfo{shaderStages[stageIndex].info};
|
||||
auto &stageConstantBuffers{constantBuffers[stageIndex]};
|
||||
auto copies{ctx.executor.allocator->AllocateUntracked<vk::CopyDescriptorSet>(1)};
|
||||
auto writes{ctx.executor.allocator->AllocateUntracked<vk::WriteDescriptorSet>(cbufUsageInfo.writeDescCount)};
|
||||
|
||||
size_t writeIdx{};
|
||||
size_t bufferIdx{};
|
||||
|
||||
auto bufferDescs{ctx.executor.allocator->AllocateUntracked<vk::DescriptorBufferInfo>(cbufUsageInfo.totalBufferDescCount)};
|
||||
auto bufferDescViews{ctx.executor.allocator->AllocateUntracked<DynamicBufferBinding>(cbufUsageInfo.totalBufferDescCount)};
|
||||
auto bufferDescDynamicBindings{ctx.executor.allocator->AllocateUntracked<DynamicBufferBinding>(cbufUsageInfo.totalBufferDescCount)};
|
||||
|
||||
// TODO: opt this to do partial copy
|
||||
*copy = vk::CopyDescriptorSet{
|
||||
// TODO: opt this to do partial copy and avoid updating twice
|
||||
copies[0] = vk::CopyDescriptorSet{
|
||||
.srcBinding = 0,
|
||||
.srcArrayElement = 0,
|
||||
.dstBinding = 0,
|
||||
@ -687,7 +700,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
};
|
||||
|
||||
for (size_t i{}; i < shaderDesc.count; i++)
|
||||
bufferDescViews[bufferIdx++] = getBufferCb(shaderDesc, usage.shaderDescIdx, i);
|
||||
bufferDescDynamicBindings[bufferIdx++] = getBufferCb(shaderDesc, usage.shaderDescIdx, i);
|
||||
}
|
||||
}};
|
||||
|
||||
@ -701,6 +714,17 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
[&](const Shader::StorageBufferDescriptor &desc, size_t descIdx, size_t arrayIdx) {
|
||||
return GetStorageBufferBinding(ctx, shaderInfo, stageConstantBuffers[desc.cbuf_index], storageBufferViews[bufferIdx], descIdx);
|
||||
});
|
||||
|
||||
return ctx.executor.allocator->EmplaceUntracked<DescriptorUpdateInfo>(DescriptorUpdateInfo{
|
||||
.copies = copies,
|
||||
.writes = writes,
|
||||
.bufferDescs = bufferDescs,
|
||||
.bufferDescDynamicBindings = bufferDescDynamicBindings,
|
||||
.pipelineLayout = compiledPipeline.pipelineLayout,
|
||||
.descriptorSetLayout = compiledPipeline.descriptorSetLayout,
|
||||
.bindPoint = vk::PipelineBindPoint::eGraphics,
|
||||
.descriptorSetIndex = 0,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,9 +94,9 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
|
||||
bool CheckBindingMatch(Pipeline *other);
|
||||
|
||||
void SyncDescriptors(InterconnectContext &ctx, ConstantBufferSet &constantBuffers);
|
||||
DescriptorUpdateInfo *SyncDescriptors(InterconnectContext &ctx, ConstantBufferSet &constantBuffers);
|
||||
|
||||
void SyncDescriptorsQuickBind(InterconnectContext &ctx, ConstantBufferSet &constantBuffers, ConstantBuffers::QuickBind quickBind);
|
||||
DescriptorUpdateInfo *SyncDescriptorsQuickBind(InterconnectContext &ctx, ConstantBufferSet &constantBuffers, ConstantBuffers::QuickBind quickBind);
|
||||
};
|
||||
|
||||
class PipelineManager {
|
||||
|
@ -12,7 +12,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
*/
|
||||
struct StateUpdateCmdHeader {
|
||||
StateUpdateCmdHeader *next;
|
||||
using RecordFunc = void (*)(vk::raii::CommandBuffer &commandBuffer, StateUpdateCmdHeader *header);
|
||||
using RecordFunc = void (*)(GPU &gpu, vk::raii::CommandBuffer &commandBuffer, StateUpdateCmdHeader *header);
|
||||
RecordFunc record;
|
||||
};
|
||||
|
||||
@ -30,13 +30,13 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
|
||||
CmdHolder() = default;
|
||||
|
||||
static void Record(vk::raii::CommandBuffer &commandBuffer, StateUpdateCmdHeader *header) {
|
||||
reinterpret_cast<CmdHolder *>(header)->cmd.Record(commandBuffer);
|
||||
static void Record(GPU &gpu, vk::raii::CommandBuffer &commandBuffer, StateUpdateCmdHeader *header) {
|
||||
reinterpret_cast<CmdHolder *>(header)->cmd.Record(gpu, commandBuffer);
|
||||
}
|
||||
};
|
||||
|
||||
struct SetVertexBuffersCmdImpl {
|
||||
void Record(vk::raii::CommandBuffer &commandBuffer) {
|
||||
void Record(GPU &gpu, vk::raii::CommandBuffer &commandBuffer) {
|
||||
commandBuffer.bindVertexBuffers(firstBinding,
|
||||
span(buffers).subspan(firstBinding, bindingCount),
|
||||
span(offsets).subspan(firstBinding, bindingCount));
|
||||
@ -50,7 +50,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
using SetVertexBuffersCmd = CmdHolder<SetVertexBuffersCmdImpl>;
|
||||
|
||||
struct SetVertexBuffersDynamicCmdImpl {
|
||||
void Record(vk::raii::CommandBuffer &commandBuffer) {
|
||||
void Record(GPU &gpu, vk::raii::CommandBuffer &commandBuffer) {
|
||||
for (u32 i{base.firstBinding}; i < base.firstBinding + base.bindingCount; i++) {
|
||||
base.buffers[i] = views[i].GetBuffer()->GetBacking();
|
||||
base.offsets[i] = views[i].GetOffset();
|
||||
@ -59,13 +59,13 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
base.Record(commandBuffer);
|
||||
}
|
||||
|
||||
SetVertexBuffersCmdImpl base;
|
||||
SetVertexBuffersCmdImpl base{};
|
||||
std::array<BufferView, engine::VertexStreamCount> views;
|
||||
};
|
||||
using SetVertexBuffersDynamicCmd = CmdHolder<SetVertexBuffersDynamicCmdImpl>;
|
||||
|
||||
struct SetIndexBufferCmdImpl {
|
||||
void Record(vk::raii::CommandBuffer &commandBuffer) {
|
||||
void Record(GPU &gpu, vk::raii::CommandBuffer &commandBuffer) {
|
||||
commandBuffer.bindIndexBuffer(buffer, offset, indexType);
|
||||
}
|
||||
|
||||
@ -76,7 +76,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
using SetIndexBufferCmd = CmdHolder<SetIndexBufferCmdImpl>;
|
||||
|
||||
struct SetIndexBufferDynamicCmdImpl {
|
||||
void Record(vk::raii::CommandBuffer &commandBuffer) {
|
||||
void Record(GPU &gpu, vk::raii::CommandBuffer &commandBuffer) {
|
||||
base.buffer = view.GetBuffer()->GetBacking();
|
||||
base.offset = view.GetOffset();
|
||||
base.Record(commandBuffer);
|
||||
@ -88,7 +88,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
using SetIndexBufferDynamicCmd = CmdHolder<SetIndexBufferDynamicCmdImpl>;
|
||||
|
||||
struct SetTransformFeedbackBufferCmdImpl {
|
||||
void Record(vk::raii::CommandBuffer &commandBuffer) {
|
||||
void Record(GPU &gpu, vk::raii::CommandBuffer &commandBuffer) {
|
||||
commandBuffer.bindTransformFeedbackBuffersEXT(binding, buffer, offset, size);
|
||||
}
|
||||
|
||||
@ -100,7 +100,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
using SetTransformFeedbackBufferCmd = CmdHolder<SetTransformFeedbackBufferCmdImpl>;
|
||||
|
||||
struct SetTransformFeedbackBufferDynamicCmdImpl {
|
||||
void Record(vk::raii::CommandBuffer &commandBuffer) {
|
||||
void Record(GPU &gpu, vk::raii::CommandBuffer &commandBuffer) {
|
||||
base.buffer = view.GetBuffer()->GetBacking();
|
||||
base.offset = view.GetOffset();
|
||||
base.Record(commandBuffer);
|
||||
@ -112,7 +112,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
using SetTransformFeedbackBufferDynamicCmd = CmdHolder<SetTransformFeedbackBufferDynamicCmdImpl>;
|
||||
|
||||
struct SetViewportCmdImpl {
|
||||
void Record(vk::raii::CommandBuffer &commandBuffer) {
|
||||
void Record(GPU &gpu, vk::raii::CommandBuffer &commandBuffer) {
|
||||
commandBuffer.setViewport(index, viewport);
|
||||
}
|
||||
|
||||
@ -122,7 +122,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
using SetViewportCmd = CmdHolder<SetViewportCmdImpl>;
|
||||
|
||||
struct SetScissorCmdImpl {
|
||||
void Record(vk::raii::CommandBuffer &commandBuffer) {
|
||||
void Record(GPU &gpu, vk::raii::CommandBuffer &commandBuffer) {
|
||||
commandBuffer.setScissor(index, scissor);
|
||||
}
|
||||
|
||||
@ -132,7 +132,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
using SetScissorCmd = CmdHolder<SetScissorCmdImpl>;
|
||||
|
||||
struct SetLineWidthCmdImpl {
|
||||
void Record(vk::raii::CommandBuffer &commandBuffer) {
|
||||
void Record(GPU &gpu, vk::raii::CommandBuffer &commandBuffer) {
|
||||
commandBuffer.setLineWidth(lineWidth);
|
||||
}
|
||||
|
||||
@ -141,7 +141,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
using SetLineWidthCmd = CmdHolder<SetLineWidthCmdImpl>;
|
||||
|
||||
struct SetDepthBiasCmdImpl {
|
||||
void Record(vk::raii::CommandBuffer &commandBuffer) {
|
||||
void Record(GPU &gpu, vk::raii::CommandBuffer &commandBuffer) {
|
||||
commandBuffer.setDepthBias(depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor);
|
||||
}
|
||||
|
||||
@ -152,7 +152,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
using SetDepthBiasCmd = CmdHolder<SetDepthBiasCmdImpl>;
|
||||
|
||||
struct SetBlendConstantsCmdImpl {
|
||||
void Record(vk::raii::CommandBuffer &commandBuffer) {
|
||||
void Record(GPU &gpu, vk::raii::CommandBuffer &commandBuffer) {
|
||||
commandBuffer.setBlendConstants(blendConstants.data());
|
||||
}
|
||||
|
||||
@ -161,7 +161,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
using SetBlendConstantsCmd = CmdHolder<SetBlendConstantsCmdImpl>;
|
||||
|
||||
struct SetDepthBoundsCmdImpl {
|
||||
void Record(vk::raii::CommandBuffer &commandBuffer) {
|
||||
void Record(GPU &gpu, vk::raii::CommandBuffer &commandBuffer) {
|
||||
commandBuffer.setDepthBounds(minDepthBounds, maxDepthBounds);
|
||||
}
|
||||
|
||||
@ -171,7 +171,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
using SetDepthBoundsCmd = CmdHolder<SetDepthBoundsCmdImpl>;
|
||||
|
||||
struct SetBaseStencilStateCmdImpl {
|
||||
void Record(vk::raii::CommandBuffer &commandBuffer) {
|
||||
void Record(GPU &gpu, vk::raii::CommandBuffer &commandBuffer) {
|
||||
commandBuffer.setStencilCompareMask(flags, funcMask);
|
||||
commandBuffer.setStencilReference(flags, funcRef);
|
||||
commandBuffer.setStencilWriteMask(flags, mask);
|
||||
@ -184,6 +184,52 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
};
|
||||
using SetBaseStencilStateCmd = CmdHolder<SetBaseStencilStateCmdImpl>;
|
||||
|
||||
struct SetDescriptorSetWithUpdateCmdImpl {
|
||||
void Record(GPU &gpu, vk::raii::CommandBuffer &commandBuffer) {
|
||||
// Resolve descriptor infos from dynamic bindings
|
||||
for (size_t i{}; i < updateInfo->bufferDescDynamicBindings.size(); i++) {
|
||||
auto &dynamicBinding{updateInfo->bufferDescDynamicBindings[i]};
|
||||
if (auto view{std::get_if<BufferView>(&dynamicBinding)}) {
|
||||
updateInfo->bufferDescs[i] = vk::DescriptorBufferInfo{
|
||||
.buffer = view->GetBuffer()->GetBacking(),
|
||||
.offset = view->GetOffset(),
|
||||
.range = view->size
|
||||
};
|
||||
} else if (auto binding{std::get_if<BufferBinding>(&dynamicBinding)}) {
|
||||
updateInfo->bufferDescs[i] = vk::DescriptorBufferInfo{
|
||||
.buffer = binding->buffer,
|
||||
.offset = binding->offset,
|
||||
.range = binding->size
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Set the destination/(source) descriptor set(s) for all writes/(copies)
|
||||
for (auto &write : updateInfo->writes)
|
||||
write.dstSet = **dstSet;
|
||||
|
||||
for (auto © : updateInfo->copies) {
|
||||
copy.dstSet = **dstSet;
|
||||
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, 0);
|
||||
}
|
||||
|
||||
DescriptorUpdateInfo *updateInfo;
|
||||
DescriptorAllocator::ActiveDescriptorSet *srcSet;
|
||||
DescriptorAllocator::ActiveDescriptorSet *dstSet;
|
||||
};
|
||||
using SetDescriptorSetWithUpdateCmd = CmdHolder<SetDescriptorSetWithUpdateCmdImpl>;
|
||||
|
||||
/**
|
||||
* @brief Single-use helper for recording a batch of state updates into a command buffer
|
||||
*/
|
||||
@ -197,9 +243,9 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
/**
|
||||
* @brief Records all contained state updates into the given command buffer
|
||||
*/
|
||||
void RecordAll(vk::raii::CommandBuffer &commandBuffer) const {
|
||||
void RecordAll(GPU &gpu, vk::raii::CommandBuffer &commandBuffer) const {
|
||||
for (StateUpdateCmdHeader *cmd{first}; cmd; cmd = cmd->next)
|
||||
cmd->record(commandBuffer, cmd);
|
||||
cmd->record(gpu, commandBuffer, cmd);
|
||||
}
|
||||
};
|
||||
|
||||
@ -359,5 +405,13 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
.mask = mask,
|
||||
});
|
||||
}
|
||||
|
||||
void SetDescriptorSetWithUpdate(DescriptorUpdateInfo *updateInfo, DescriptorAllocator::ActiveDescriptorSet *dstSet, DescriptorAllocator::ActiveDescriptorSet *srcSet) {
|
||||
AppendCmd<SetDescriptorSetWithUpdateCmd>({
|
||||
.updateInfo = updateInfo,
|
||||
.srcSet = srcSet,
|
||||
.dstSet = dstSet,
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user