Skip to content

Commit

Permalink
merian-nodes: GraphRun: Add mechanism to sync cpu to GPU and back
Browse files Browse the repository at this point in the history
  • Loading branch information
LDAP committed Feb 3, 2025
1 parent d944af1 commit 5ee1d86
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 16 deletions.
72 changes: 71 additions & 1 deletion include/merian-nodes/graph/graph_run.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,14 @@ class GraphRun {
const ShaderCompilerHandle& shader_compiler)
: iterations_in_flight(iterations_in_flight), thread_pool(thread_pool),
cpu_queue(cpu_queue), profiler(profiler), allocator(allocator), queue(queue),
shader_compiler(shader_compiler) {}
shader_compiler(shader_compiler) {

semaphores.resize(iterations_in_flight);
semaphore_value.assign(iterations_in_flight, 1);
for (uint32_t i = 0; i < iterations_in_flight; i++) {
semaphores[i] = TimelineSemaphore::create(queue->get_context());
}
}

GraphRun(GraphRun& graph_run) = delete;
GraphRun(GraphRun&& graph_run) = delete;
Expand Down Expand Up @@ -191,6 +198,66 @@ class GraphRun {

// ------------------------------------------------------------------------------------

// Queues the callback to be called when the commandbuffer until this point has finished
// executing on the GPU. Calling this might trigger a GPU submit but graph is free to delay
// execution of the callback until the end of the run.
void sync_to_cpu(const std::function<void()>& callback) {
add_signal_semaphore(semaphores[get_in_flight_index()],
semaphore_value[get_in_flight_index()]);
cpu_queue->submit(semaphores[get_in_flight_index()], semaphore_value[get_in_flight_index()],
callback);
semaphore_value[get_in_flight_index()]++;
}

// Queues the callback to be called when the commandbuffer until this point has finished
// executing on the GPU. Calling this might trigger a GPU submit but graph is free to delay
// execution of the callback until the end of the run.
void sync_to_cpu(const std::function<void()>&& callback) {
add_signal_semaphore(semaphores[get_in_flight_index()],
semaphore_value[get_in_flight_index()]);
cpu_queue->submit(semaphores[get_in_flight_index()], semaphore_value[get_in_flight_index()],
callback);
semaphore_value[get_in_flight_index()]++;
}

// Queues the callback to be called when the commandbuffer until this point has finished
// executing on the GPU. GPU processing will be automatically continued when this callback
// finishes executing.
//
// Note: This can only be used if there is no present operation depending on the CPU execution.
void sync_to_cpu_and_back(const std::function<void()>& callback) {
add_signal_semaphore(semaphores[get_in_flight_index()],
semaphore_value[get_in_flight_index()]);
cmd->end();
submit();
cmd = cmd_cache->create_and_begin();
cpu_queue->submit(semaphores[get_in_flight_index()], semaphore_value[get_in_flight_index()],
semaphores[get_in_flight_index()],
semaphore_value[get_in_flight_index()] + 1, callback);
add_wait_semaphore(semaphores[get_in_flight_index()], vk::PipelineStageFlagBits::eTopOfPipe,
semaphore_value[get_in_flight_index()] + 1);
semaphore_value[get_in_flight_index()] += 2;
}

// Queues the callback to be called when the commandbuffer until this point has finished
// executing on the GPU. GPU processing will be automatically continued when this callback
// finishes executing.
//
// Note: This can only be used if there is no present operation depending on the CPU execution.
void sync_to_cpu_and_back(const std::function<void()>&& callback) {
add_signal_semaphore(semaphores[get_in_flight_index()],
semaphore_value[get_in_flight_index()]);
cmd->end();
submit();
cmd = cmd_cache->create_and_begin();
cpu_queue->submit(semaphores[get_in_flight_index()], semaphore_value[get_in_flight_index()],
semaphores[get_in_flight_index()],
semaphore_value[get_in_flight_index()] + 1, callback);
add_wait_semaphore(semaphores[get_in_flight_index()], vk::PipelineStageFlagBits::eTopOfPipe,
semaphore_value[get_in_flight_index()] + 1);
semaphore_value[get_in_flight_index()] += 2;
}

private:
void begin_run(const std::shared_ptr<CachingCommandPool>& cmd_cache,
const uint64_t iteration,
Expand Down Expand Up @@ -257,6 +324,9 @@ class GraphRun {
std::shared_ptr<CachingCommandPool> cmd_cache = nullptr;
CommandBufferHandle cmd = nullptr;

std::vector<TimelineSemaphoreHandle> semaphores;
std::vector<uint64_t> semaphore_value;

std::vector<vk::Semaphore> wait_semaphores;
std::vector<uint64_t> wait_values;
std::vector<vk::PipelineStageFlags> wait_stages;
Expand Down
4 changes: 2 additions & 2 deletions include/merian/vk/utils/profiler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,8 +276,8 @@ class ProfileScopeGPU {
}

private:
const ProfilerHandle profiler;
const CommandBufferHandle cmd;
const ProfilerHandle& profiler;
const CommandBufferHandle& cmd;
#ifndef NDEBUG
// Detect overlapping regions
uint32_t cpu_section_index = 0;
Expand Down
7 changes: 2 additions & 5 deletions src/merian-nodes/nodes/image_write/image_write.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,14 +240,11 @@ void ImageWrite::process(GraphRun& run,
vk::AccessFlagBits::eTransferWrite,
vk::AccessFlagBits::eHostRead));

TimelineSemaphoreHandle image_ready = TimelineSemaphore::create(context, 0);
run.add_signal_semaphore(image_ready, 1);

std::filesystem::create_directories(path.parent_path());
const std::string tmp_filename =
(path.parent_path() / (".interm_" + path.filename().string())).string();

std::function<void()> write_task = ([this, image_ready, linear_image, path, tmp_filename]() {
std::function<void()> write_task = ([this, linear_image, path, tmp_filename]() {
float* mem = linear_image->get_memory()->map_as<float>();

switch (this->format) {
Expand Down Expand Up @@ -285,7 +282,7 @@ void ImageWrite::process(GraphRun& run,
return;
});

run.get_cpu_queue()->submit(image_ready, 1, std::move(write_task));
run.sync_to_cpu(std::move(write_task));

if (rebuild_after_capture)
run.request_reconnect();
Expand Down
12 changes: 6 additions & 6 deletions src/merian/utils/input_controller_dummy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ DummyInputController::DummyInputController() {}

DummyInputController::~DummyInputController() {}

bool DummyInputController::request_raw_mouse_input(bool) {
bool DummyInputController::request_raw_mouse_input(bool /*enable*/) {
return false;
}

Expand All @@ -17,11 +17,11 @@ bool DummyInputController::get_raw_mouse_input() {
// Clear all callbacks
void DummyInputController::reset() {}

void DummyInputController::set_active(bool) {}
void DummyInputController::set_active(bool /*active*/) {}

void DummyInputController::set_mouse_cursor_callback(MouseCursorEventCallback) {}
void DummyInputController::set_mouse_button_callback(MouseButtonEventCallback) {}
void DummyInputController::set_scroll_event_callback(ScrollEventCallback) {}
void DummyInputController::set_key_event_callback(KeyEventCallback) {}
void DummyInputController::set_mouse_cursor_callback(MouseCursorEventCallback /*cb*/) {}
void DummyInputController::set_mouse_button_callback(MouseButtonEventCallback /*cb*/) {}
void DummyInputController::set_scroll_event_callback(ScrollEventCallback /*cb*/) {}
void DummyInputController::set_key_event_callback(KeyEventCallback /*cb*/) {}

} // namespace merian
4 changes: 2 additions & 2 deletions src/merian/utils/input_controller_glfw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ GLFWInputController::~GLFWInputController() {
}

bool GLFWInputController::request_raw_mouse_input(bool enable) {
if (!glfwRawMouseMotionSupported())
if (glfwRawMouseMotionSupported() == 0)
return false;

if (enable) {
Expand All @@ -123,7 +123,7 @@ bool GLFWInputController::request_raw_mouse_input(bool enable) {

// Returns true if raw mouse input is enabled.
bool GLFWInputController::get_raw_mouse_input() {
return glfwGetInputMode(*window, GLFW_RAW_MOUSE_MOTION);
return glfwGetInputMode(*window, GLFW_RAW_MOUSE_MOTION) != 0;
}

// Clear all callbacks
Expand Down

0 comments on commit 5ee1d86

Please sign in to comment.