MCPcopy Create free account
hub / github.com/a2flo/floor / execute_indirect

Method execute_indirect

src/device/device_queue.cpp:77–133  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

75}
76
77void device_queue::execute_indirect(const indirect_command_pipeline& indirect_cmd,
78 const indirect_execution_parameters_t& params,
79 kernel_completion_handler_f&& completion_handler,
80 const uint32_t command_offset,
81 const uint32_t command_count) const {
82 if (command_count == 0) {
83 return;
84 }
85 if (!dev.indirect_command_support || !dev.indirect_compute_command_support) {
86 log_error("device $ has no support for indirect command pipelines", dev.name);
87 return;
88 }
89
90#if defined(FLOOR_DEBUG)
91 if (indirect_cmd.get_description().command_type != indirect_command_description::COMMAND_TYPE::COMPUTE) {
92 log_error("specified indirect command pipeline \"$\" must be a compute pipeline",
93 indirect_cmd.get_description().debug_label);
94 return;
95 }
96#endif
97
98 const auto& generic_indirect_cmd = (const generic_indirect_command_pipeline&)indirect_cmd;
99 const auto generic_indirect_pipeline_entry = generic_indirect_cmd.get_pipeline_entry(dev);
100 if (!generic_indirect_pipeline_entry) {
101 log_error("no indirect command pipeline state for device \"$\" in indirect command pipeline \"$\"",
102 dev.name, indirect_cmd.get_description().debug_label);
103 return;
104 }
105
106 const auto range = generic_indirect_cmd.compute_and_validate_command_range(command_offset, command_count);
107 if (!range) {
108 return;
109 }
110
111 // wait fences handling: we add "wait_fences" to all kernel executions until we hit the first kernel that acts as a barrier,
112 // i.e. it has wait_until_completion set -> after that, we can safely ignore wait_fences
113 bool has_encountered_barrier = false;
114 const std::vector<const device_fence*> empty_wait_fences;
115 const std::vector<device_fence*> empty_signal_fences;
116 for (uint32_t cmd_idx = range->offset, cmd_end = range->offset + range->count; cmd_idx < cmd_end; ++cmd_idx) {
117 const auto& cmd = generic_indirect_pipeline_entry->commands[cmd_idx];
118 // the last command is somewhat special: it is used both to execute the final completion handler + emit "signal_fences"
119 const auto is_last_cmd = (cmd_idx + 1u == cmd_end);
120 cmd.kernel_ptr->execute(*this, false, cmd.wait_until_completion, cmd.dim, cmd.global_work_size, cmd.local_work_size, cmd.args,
121 !has_encountered_barrier && !params.wait_fences.empty() ? params.wait_fences : empty_wait_fences,
122 !is_last_cmd ? empty_signal_fences : params.signal_fences,
123 params.debug_label ? params.debug_label : generic_indirect_pipeline_entry->debug_label.c_str(),
124 is_last_cmd && completion_handler ? completion_handler : kernel_completion_handler_f {});
125 if (cmd.wait_until_completion) {
126 has_encountered_barrier = true;
127 }
128 }
129
130 if (params.wait_until_completion) {
131 finish();
132 }
133}
134

Callers

nothing calls this directly

Calls 4

get_pipeline_entryMethod · 0.80
executeMethod · 0.45
emptyMethod · 0.45

Tested by

no test coverage detected