641{
642 const auto& params = safe_variant_get_or_throw<ChainedParams>(ctx.parameters,
643 "GpuResourceManager: dispatch_batched requires ChainedParams");
644
648
649 const uint32_t workgroups_per_pass = groups[0] * groups[1] * groups[2];
650
651 const uint32_t default_passes = std::max(1U, 65536U / std::max(1U, workgroups_per_pass));
652
653 const uint32_t effective_passes_per_batch = params.passes_per_batch.value_or(default_passes);
654 for (uint32_t base = 0; base < params.pass_count; base += effective_passes_per_batch) {
655 const uint32_t batch_end = std::min(base + effective_passes_per_batch, params.pass_count);
656 auto cmd_id = foundry.begin_commands(
658
659 for (uint32_t pass = base; pass < batch_end; ++pass) {
660 std::vector<uint8_t> pc_data(push_constant_size);
661 params.pc_updater(pass, pc_data.data());
662 compute_press.bind_all(
663 cmd_id, unit.pipeline_id, unit.descriptor_set_ids,
664 pc_data.data(), push_constant_size);
665 compute_press.dispatch(cmd_id, groups[0], groups[1], groups[2]);
666
667 for (
const auto&
b : bindings) {
669 continue;
670
673 const bool is_shared =
m_shared->slots.contains({
b.set,
static_cast<size_t>(
b.binding) });
674
676 if (
static_cast<size_t>(
b.binding) < unit.image_slots.size() && unit.image_slots[
b.binding]) {
677 foundry.image_barrier(
678 cmd_id,
679 unit.image_slots[
b.binding]->get_image(),
680 vk::ImageLayout::eGeneral,
681 vk::ImageLayout::eGeneral,
682 vk::AccessFlagBits::eShaderWrite | vk::AccessFlagBits::eShaderRead,
683 vk::AccessFlagBits::eShaderWrite | vk::AccessFlagBits::eShaderRead,
684 vk::PipelineStageFlagBits::eComputeShader,
685 vk::PipelineStageFlagBits::eComputeShader);
686 }
687 }
else if (!is_shared &&
static_cast<size_t>(
b.binding) < unit.impl->buffers.size()
688 && unit.impl->buffers[
b.binding].buffer) {
689 foundry.buffer_barrier(
690 cmd_id,
691 unit.impl->buffers[
b.binding].buffer,
692 vk::AccessFlagBits::eShaderWrite | vk::AccessFlagBits::eShaderRead,
693 vk::AccessFlagBits::eShaderWrite | vk::AccessFlagBits::eShaderRead,
694 vk::PipelineStageFlagBits::eComputeShader,
695 vk::PipelineStageFlagBits::eComputeShader);
696 }
697 }
698 }
699
700 for (
const auto&
b : bindings) {
705 const bool is_shared =
m_shared->slots.contains({
b.set,
static_cast<size_t>(
b.binding) });
706 if (!
is_image && !is_shared &&
static_cast<size_t>(
b.binding) < unit.impl->buffers.size()
707 && unit.impl->buffers[
b.binding].buffer) {
708 foundry.buffer_barrier(
709 cmd_id,
710 unit.impl->buffers[
b.binding].buffer,
711 vk::AccessFlagBits::eShaderWrite,
712 vk::AccessFlagBits::eHostRead,
713 vk::PipelineStageFlagBits::eComputeShader,
714 vk::PipelineStageFlagBits::eHost);
715 }
716 }
717 }
718
719 foundry.submit_and_wait(cmd_id);
720 }
721}
std::unique_ptr< SharedBuffers > m_shared
PipelineUnit & unit_for(const std::string &key)
MAYAFLUX_API ShaderFoundry & get_shader_foundry()
Get the global shader compiler instance.
MAYAFLUX_API ComputePress & get_compute_press()
bool is_image(const fs::path &filepath)