diff --git a/cmake/options.cmake b/cmake/options.cmake index ce0265e..ed06d46 100644 --- a/cmake/options.cmake +++ b/cmake/options.cmake @@ -31,7 +31,7 @@ MESSAGE(STATUS "Link Time Optimizaiton.. ${ENABLE_LTO}") # # Examples # -option(BUILD_EXAMPLES "Build Examples" ON) +option(BUILD_EXAMPLES "Build Examples" OFF) MESSAGE(STATUS "Build Examples ......... ${BUILD_EXAMPLES}") # diff --git a/examples/presentation-shm.cc b/examples/presentation-shm.cc index 5de1da4..05f7037 100644 --- a/examples/presentation-shm.cc +++ b/examples/presentation-shm.cc @@ -33,43 +33,43 @@ #include "window/xdg_toplevel.h" enum run_mode { - RUN_MODE_FEEDBACK, - RUN_MODE_FEEDBACK_IDLE, - RUN_MODE_PRESENT, + RUN_MODE_FEEDBACK, + RUN_MODE_FEEDBACK_IDLE, + RUN_MODE_PRESENT, }; static constexpr char run_mode_name[3][16] = { - "feedback", - "feedback-idle", - "low-lat present", + "feedback", + "feedback-idle", + "low-lat present", }; static constexpr int kResizeMargin = 12; struct Configuration { - int width; - int height; - enum run_mode mode; - int refresh_nsec; - int commit_delay_msecs; + int width; + int height; + enum run_mode mode; + int refresh_nsec; + int commit_delay_msecs; }; struct Feedback { - Window *window; - struct wp_presentation_feedback *wp_presentation_feedback; - unsigned frame_no; - struct timespec commit; - struct timespec target; - uint32_t frame_stamp; - struct timespec present; + Window* window; + struct wp_presentation_feedback* wp_presentation_feedback; + unsigned frame_no; + struct timespec commit; + struct timespec target; + uint32_t frame_stamp; + struct timespec present; }; struct Context { - struct wl_display *display; - std::shared_ptr wm; - std::shared_ptr toplevel; - Configuration config; - std::vector> feedback_list; + struct wl_display* display; + std::shared_ptr wm; + std::shared_ptr toplevel; + Configuration config; + std::vector> feedback_list; }; static constexpr int kBufferCount = 60; @@ -89,176 +89,176 @@ static volatile bool running = true; * @return void */ void handle_signal(const int signal) { - if (signal == SIGINT) { - running = false; - } + if (signal == SIGINT) { + running = false; + } } -static void paint_pixels(void *image, int width, int height, uint32_t phase) { - const int halfh = height / 2; - const int halfw = width / 2; - uint32_t *pixel = static_cast(image); - int y, or_; - double ang = M_PI * 2.0 / 1000000.0 * phase; - double s = sin(ang); - double c = cos(ang); - - /// squared radii thresholds - or_ = (halfw < halfh ? halfw : halfh) - 16; - or_ *= or_; - - for (y = 0; y < height; y++) { - int x; - int oy = y - halfh; - int y2 = oy * oy; - - for (x = 0; x < width; x++) { - int ox = x - halfw; - uint32_t v = 0xff000000; - double rx, ry; - - if (ox * ox + y2 > or_) { - if (ox * oy > 0) - *pixel++ = 0xff000000; - else - *pixel++ = 0xffffffff; - continue; - } - - rx = c * ox + s * oy; - ry = -s * ox + c * oy; - - if (rx < 0.0) - v |= 0x00ff0000; - if (ry < 0.0) - v |= 0x0000ff00; - if ((rx < 0.0) == (ry < 0.0)) - v |= 0x000000ff; - - *pixel++ = v; - } +static void paint_pixels(void* image, int width, int height, uint32_t phase) { + const int halfh = height / 2; + const int halfw = width / 2; + uint32_t* pixel = static_cast(image); + int y, or_; + double ang = M_PI * 2.0 / 1000000.0 * phase; + double s = sin(ang); + double c = cos(ang); + + /// squared radii thresholds + or_ = (halfw < halfh ? halfw : halfh) - 16; + or_ *= or_; + + for (y = 0; y < height; y++) { + int x; + int oy = y - halfh; + int y2 = oy * oy; + + for (x = 0; x < width; x++) { + int ox = x - halfw; + uint32_t v = 0xff000000; + double rx, ry; + + if (ox * ox + y2 > or_) { + if (ox * oy > 0) + *pixel++ = 0xff000000; + else + *pixel++ = 0xffffffff; + continue; + } + + rx = c * ox + s * oy; + ry = -s * ox + c * oy; + + if (rx < 0.0) + v |= 0x00ff0000; + if (ry < 0.0) + v |= 0x0000ff00; + if ((rx < 0.0) == (ry < 0.0)) + v |= 0x000000ff; + + *pixel++ = v; } + } } static void feedback_sync_output( - void *data, - struct wp_presentation_feedback *wp_presentation_feedback, - struct wl_output *output) { - auto ctx = static_cast(data); - if (ctx->wp_presentation_feedback != wp_presentation_feedback) { - return; - } - DLOG_DEBUG("feedback_sync_output: 0x{:x}", fmt::ptr(output)); - (void) output; + void* data, + struct wp_presentation_feedback* wp_presentation_feedback, + struct wl_output* output) { + auto ctx = static_cast(data); + if (ctx->wp_presentation_feedback != wp_presentation_feedback) { + return; + } + DLOG_DEBUG("feedback_sync_output: 0x{:x}", fmt::ptr(output)); + (void)output; } static void feedback_presented( - void *data, - struct wp_presentation_feedback *wp_presentation_feedback, - uint32_t tv_sec_hi, - uint32_t tv_sec_lo, - uint32_t tv_nsec, - uint32_t refresh_nsec, - uint32_t seq_hi, - uint32_t seq_lo, - uint32_t flags) { - auto ctx = static_cast(data); - if (ctx->wp_presentation_feedback != wp_presentation_feedback) { - return; - } - - auto seconds = (static_cast(tv_sec_hi) << 32) + tv_sec_lo; - auto duration = - std::chrono::seconds{seconds} + std::chrono::nanoseconds{tv_nsec}; - - uint64_t seq = (static_cast(seq_hi) << 32) + seq_lo; - - LOG_DEBUG( - "feedback_presented: ts: {} nS, refresh: {} nS, sequence: {}, flags: {}", - std::chrono::nanoseconds(duration).count(), refresh_nsec, seq, flags); + void* data, + struct wp_presentation_feedback* wp_presentation_feedback, + uint32_t tv_sec_hi, + uint32_t tv_sec_lo, + uint32_t tv_nsec, + uint32_t refresh_nsec, + uint32_t seq_hi, + uint32_t seq_lo, + uint32_t flags) { + auto ctx = static_cast(data); + if (ctx->wp_presentation_feedback != wp_presentation_feedback) { + return; + } + + auto seconds = (static_cast(tv_sec_hi) << 32) + tv_sec_lo; + auto duration = + std::chrono::seconds{seconds} + std::chrono::nanoseconds{tv_nsec}; + + uint64_t seq = (static_cast(seq_hi) << 32) + seq_lo; + + LOG_DEBUG( + "feedback_presented: ts: {} nS, refresh: {} nS, sequence: {}, flags: {}", + std::chrono::nanoseconds(duration).count(), refresh_nsec, seq, flags); } -static void destroy_feedback(struct Feedback *feedback) { - if (feedback->wp_presentation_feedback) { - wp_presentation_feedback_destroy(feedback->wp_presentation_feedback); - } +static void destroy_feedback(struct Feedback* feedback) { + if (feedback->wp_presentation_feedback) { + wp_presentation_feedback_destroy(feedback->wp_presentation_feedback); + } - auto ctx = static_cast(feedback->window->get_user_data()); + auto ctx = static_cast(feedback->window->get_user_data()); - auto idx = std::find_if( - ctx->feedback_list.begin(), ctx->feedback_list.end(), - [&](std::unique_ptr const &s) { return s.get() == feedback; }); + auto idx = std::find_if( + ctx->feedback_list.begin(), ctx->feedback_list.end(), + [&](std::unique_ptr const& s) { return s.get() == feedback; }); - ctx->feedback_list.erase(idx); + ctx->feedback_list.erase(idx); } static void feedback_discarded( - void *data, - struct wp_presentation_feedback *wp_presentation_feedback) { - auto feedback = static_cast(data); - if (feedback->wp_presentation_feedback != wp_presentation_feedback) { - return; - } + void* data, + struct wp_presentation_feedback* wp_presentation_feedback) { + auto feedback = static_cast(data); + if (feedback->wp_presentation_feedback != wp_presentation_feedback) { + return; + } - spdlog::info("feedback_discarded {}", feedback->frame_no); + spdlog::info("feedback_discarded {}", feedback->frame_no); - destroy_feedback(feedback); + destroy_feedback(feedback); } static constexpr struct wp_presentation_feedback_listener feedback_listener = { - .sync_output = feedback_sync_output, - .presented = feedback_presented, - .discarded = feedback_discarded, + .sync_output = feedback_sync_output, + .presented = feedback_presented, + .discarded = feedback_discarded, }; -void create_feedback(Window *window, uint32_t time) { - LOG_DEBUG("create_feedback: {}", time); - static unsigned seq = 0; - auto *ctx = static_cast(window->get_user_data()); - LOG_DEBUG("context: {}", fmt::ptr(ctx)); +void create_feedback(Window* window, uint32_t time) { + LOG_DEBUG("create_feedback: {}", time); + static unsigned seq = 0; + auto* ctx = static_cast(window->get_user_data()); + LOG_DEBUG("context: {}", fmt::ptr(ctx)); - auto feedback = std::make_unique(); - feedback->window = window; - feedback->wp_presentation_feedback = wp_presentation_feedback( - ctx->wm->get_wp_presentation(), window->get_surface()); - wp_presentation_feedback_add_listener(feedback->wp_presentation_feedback, - &feedback_listener, feedback.get()); + auto feedback = std::make_unique(); + feedback->window = window; + feedback->wp_presentation_feedback = wp_presentation_feedback( + ctx->wm->get_wp_presentation(), window->get_surface()); + wp_presentation_feedback_add_listener(feedback->wp_presentation_feedback, + &feedback_listener, feedback.get()); - feedback->frame_no = ++seq; + feedback->frame_no = ++seq; - clock_gettime(ctx->wm->get_clk_id(), &feedback->commit); - feedback->target = feedback->commit; - feedback->frame_stamp = time; + clock_gettime(ctx->wm->get_clk_id(), &feedback->commit); + feedback->target = feedback->commit; + feedback->frame_stamp = time; - ctx->feedback_list.push_back(std::move(feedback)); + ctx->feedback_list.push_back(std::move(feedback)); } -static void emulate_rendering(Window *window) { - LOG_DEBUG("emulate_rendering"); - auto *config = static_cast(window->get_user_data()); - if (config->commit_delay_msecs <= 0) { - return; - } +static void emulate_rendering(Window* window) { + LOG_DEBUG("emulate_rendering"); + auto* config = static_cast(window->get_user_data()); + if (config->commit_delay_msecs <= 0) { + return; + } - std::chrono::milliseconds ms(config->commit_delay_msecs); - auto ns = std::chrono::duration_cast(ms); - std::this_thread::sleep_for(ns); + std::chrono::milliseconds ms(config->commit_delay_msecs); + auto ns = std::chrono::duration_cast(ms); + std::this_thread::sleep_for(ns); } -static void redraw_mode_feedback(void *data, uint32_t time) { - auto window = static_cast(data); +static void redraw_mode_feedback(void* data, uint32_t time) { + auto window = static_cast(data); - emulate_rendering(window); - create_feedback(window, time); + emulate_rendering(window); + create_feedback(window, time); } -int main(const int argc, char **argv) { - std::signal(SIGINT, handle_signal); +int main(const int argc, char** argv) { + std::signal(SIGINT, handle_signal); - cxxopts::Options options("simple-presentation", - "Weston simple-presentation example"); - options.add_options() - // clang-format off + cxxopts::Options options("simple-presentation", + "Weston simple-presentation example"); + options.add_options() + // clang-format off ("f,feedback", "run in feedback mode (default)") ("i,feedback-idle", "run in feedback-idle mode; sleep 1s between frames") ("p,present", "run in low-latency presentation mode") @@ -267,89 +267,87 @@ int main(const int argc, char **argv) { ("w,width", "Set width", cxxopts::value()->default_value("250")) ("h,height", "Set height", cxxopts::value()->default_value("250")); - // clang-format on - auto result = options.parse(argc, argv); + // clang-format on + auto result = options.parse(argc, argv); - auto logging = std::make_unique(); - auto ctx = std::make_unique(); + auto logging = std::make_unique(); + auto ctx = std::make_unique(); - ctx->config = { - .width = result["width"].as(), - .height = result["height"].as(), - .commit_delay_msecs = result["msecs"].as(), - }; + ctx->config = { + .width = result["width"].as(), + .height = result["height"].as(), + .commit_delay_msecs = result["msecs"].as(), + }; + ctx->config.mode = RUN_MODE_FEEDBACK; + if (result["feedback"].as()) { ctx->config.mode = RUN_MODE_FEEDBACK; - if (result["feedback"].as()) { - ctx->config.mode = RUN_MODE_FEEDBACK; - } else if (result["feedback-idle"].as()) { - ctx->config.mode = RUN_MODE_FEEDBACK_IDLE; - } else if (result["present"].as()) { - ctx->config.mode = RUN_MODE_PRESENT; + } else if (result["feedback-idle"].as()) { + ctx->config.mode = RUN_MODE_FEEDBACK_IDLE; + } else if (result["present"].as()) { + ctx->config.mode = RUN_MODE_PRESENT; + } + + ctx->config.refresh_nsec = kNanoSecondPerSecond / 60; + + ctx->display = wl_display_connect(nullptr); + if (!ctx->display) { + spdlog::critical("Unable to connect to Wayland socket."); + exit(EXIT_FAILURE); + } + + ctx->wm = std::make_unique(ctx->display); + + spdlog::info("XDG Window Manager Version: {}", ctx->wm->get_version()); + + std::stringstream title; + title << "presentation-shm: " << run_mode_name[ctx->config.mode] << "[Delay " + << ctx->config.commit_delay_msecs << " msecs]"; + LOG_DEBUG("title: {}", title.str().c_str()); + + ctx->toplevel = ctx->wm->create_top_level( + title.str().c_str(), "jwinarske.waypp.simple_presentation", + ctx->config.width, ctx->config.height, kResizeMargin, kBufferCount, + WL_SHM_FORMAT_XRGB8888, false, false, false, false, redraw_mode_feedback); + spdlog::info("XDG Window Version: {}", ctx->toplevel->get_version()); + + LOG_DEBUG("context: {}", fmt::ptr(&ctx->config)); + ctx->toplevel->set_user_data(&ctx->config); + ctx->toplevel->set_min_size(ctx->config.width, ctx->config.height); + ctx->toplevel->set_max_size(ctx->config.width, ctx->config.height); + + /// pre-render + auto& buffers = ctx->toplevel->get_buffers(); + static constexpr uint32_t time_factor = 1000000 / kBufferCount; + + uint32_t i = 0; + for (auto& buffer : buffers) { + if (buffer->is_busy()) { + spdlog::error("wl_buffer id {} is busy", buffer->get_id()); } - - ctx->config.refresh_nsec = kNanoSecondPerSecond / 60; - - ctx->display = wl_display_connect(nullptr); - if (!ctx->display) { - spdlog::critical("Unable to connect to Wayland socket."); - exit(EXIT_FAILURE); - } - - ctx->wm = std::make_unique(ctx->display); - - spdlog::info("XDG Window Manager Version: {}", ctx->wm->get_version()); - - std::stringstream title; - title << "presentation-shm: " << run_mode_name[ctx->config.mode] << "[Delay " - << ctx->config.commit_delay_msecs << " msecs]"; - LOG_DEBUG("title: {}", title.str().c_str()); - - ctx->toplevel = ctx->wm->create_top_level( - title.str().c_str(), - "jwinarske.waypp.simple_presentation", - ctx->config.width, ctx->config.height, kResizeMargin, kBufferCount, - WL_SHM_FORMAT_XRGB8888, false, false, false, false, redraw_mode_feedback); - spdlog::info("XDG Window Version: {}", ctx->toplevel->get_version()); - - LOG_DEBUG("context: {}", fmt::ptr(&ctx->config)); - ctx->toplevel->set_user_data(&ctx->config); - ctx->toplevel->set_min_size(ctx->config.width, ctx->config.height); - ctx->toplevel->set_max_size(ctx->config.width, ctx->config.height); - - /// pre-render - auto &buffers = ctx->toplevel->get_buffers(); - static constexpr uint32_t time_factor = 1000000 / kBufferCount; - - uint32_t i = 0; - for (auto &buffer: buffers) { - if (buffer->is_busy()) { - spdlog::error("wl_buffer id {} is busy", buffer->get_id()); - } - paint_pixels(buffer->get_shm_data(), buffer->get_width(), - buffer->get_height(), i * time_factor); - i++; - } - - switch (ctx->config.mode) { - case RUN_MODE_FEEDBACK: - case RUN_MODE_FEEDBACK_IDLE: - ctx->toplevel->start_frame_callbacks(); - break; - case RUN_MODE_PRESENT: - // firstdraw_mode_burst(window); - break; - } - - while (running && ctx->toplevel->is_valid() && - ctx->wm->display_dispatch() != -1) { - } - - ctx->toplevel.reset() - ctx->wm.reset(); - - wl_display_flush(ctx->display); - wl_display_disconnect(ctx->display); - - return EXIT_SUCCESS; + paint_pixels(buffer->get_shm_data(), buffer->get_width(), + buffer->get_height(), i * time_factor); + i++; + } + + switch (ctx->config.mode) { + case RUN_MODE_FEEDBACK: + case RUN_MODE_FEEDBACK_IDLE: + ctx->toplevel->start_frame_callbacks(); + break; + case RUN_MODE_PRESENT: + // firstdraw_mode_burst(window); + break; + } + + while (running && ctx->toplevel->is_valid() && + ctx->wm->display_dispatch() != -1) { + } + + ctx->toplevel.reset() ctx->wm.reset(); + + wl_display_flush(ctx->display); + wl_display_disconnect(ctx->display); + + return EXIT_SUCCESS; } \ No newline at end of file diff --git a/examples/view_manager/view_manager_wayland.cc b/examples/view_manager/view_manager_wayland.cc index 1eb56c2..83d67fe 100644 --- a/examples/view_manager/view_manager_wayland.cc +++ b/examples/view_manager/view_manager_wayland.cc @@ -197,17 +197,17 @@ void ViewManagerWayland::notify_pointer_axis(Pointer* /* pointer */, double /* value */) {} void ViewManagerWayland::notify_pointer_frame(Pointer* /* pointer */, - wl_pointer* /* pointer */){}; + wl_pointer* /* pointer */) {}; void ViewManagerWayland::notify_pointer_axis_source( Pointer* /* pointer */, wl_pointer* /* pointer */, - uint32_t /* axis_source */){}; + uint32_t /* axis_source */) {}; void ViewManagerWayland::notify_pointer_axis_stop(Pointer* /* pointer */, wl_pointer* /* pointer */, uint32_t /* time */, - uint32_t /* axis */){}; + uint32_t /* axis */) {}; void ViewManagerWayland::notify_pointer_axis_discrete(Pointer* /* pointer */, wl_pointer* /*pointer */, diff --git a/examples/vk-shadertoy/app.cc b/examples/vk-shadertoy/app.cc index 1143917..e583f4f 100644 --- a/examples/vk-shadertoy/app.cc +++ b/examples/vk-shadertoy/app.cc @@ -25,246 +25,231 @@ #include - -void App::draw_frame(void *data, const uint32_t time) { - auto window = static_cast(data); - auto shader_toy = static_cast(window->get_user_data()); - shader_toy->draw_frame(time); +void App::draw_frame(void* data, const uint32_t time) { + auto window = static_cast(data); + auto shader_toy = static_cast(window->get_user_data()); + shader_toy->draw_frame(time); } -App::App(const Configuration &config) : logging_(std::make_unique()) { - spdlog::info("{}", kAppTitle); - - display_ = wl_display_connect(nullptr); - if (!display_) { - spdlog::critical("Unable to connect to Wayland socket."); - exit(EXIT_FAILURE); - } +App::App(const Configuration& config) : logging_(std::make_unique()) { + spdlog::info("{}", kAppTitle); - shader_toy_ = std::make_unique(); - wm_ = std::make_shared(display_, config.disable_cursor); - auto seat = wm_->get_seat(); - if (seat.has_value()) { - seat.value()->register_observer(this, this); - } + display_ = wl_display_connect(nullptr); + if (!display_) { + spdlog::critical("Unable to connect to Wayland socket."); + exit(EXIT_FAILURE); + } - spdlog::debug("XDG Window Manager Version: {}", wm_->get_version()); + shader_toy_ = std::make_unique(); + wm_ = std::make_shared(display_, config.disable_cursor); + auto seat = wm_->get_seat(); + if (seat.has_value()) { + seat.value()->register_observer(this, this); + } - toplevel_ = wm_->create_top_level( - kAppTitle, kAppId, config.width, config.height, kResizeMargin, 0, 0, config.fullscreen, - config.maximized, true, config.tearing, draw_frame); - spdlog::debug("XDG Window Version: {}", toplevel_->get_version()); + spdlog::debug("XDG Window Manager Version: {}", wm_->get_version()); - shader_toy_->init(config.width, - config.height, - display_, - toplevel_->get_surface(), - config.dev_index, - config.use_gpu_idx, - config.debug, - config.reload_shaders, - static_cast(config.present_mode)); + toplevel_ = wm_->create_top_level( + kAppTitle, kAppId, config.width, config.height, kResizeMargin, 0, 0, + config.fullscreen, config.maximized, true, config.tearing, draw_frame); + spdlog::debug("XDG Window Version: {}", toplevel_->get_version()); + shader_toy_->init(config.width, config.height, display_, + toplevel_->get_surface(), config.dev_index, + config.use_gpu_idx, config.debug, config.reload_shaders, + static_cast(config.present_mode)); - /// paint padding - toplevel_->set_surface_damage(0, 0, config.width, config.height); + /// paint padding + toplevel_->set_surface_damage(0, 0, config.width, config.height); - /// start frame callbacks with user_data pointing to shadertoy - toplevel_->start_frame_callbacks(shader_toy_.get()); + /// start frame callbacks with user_data pointing to shadertoy + toplevel_->start_frame_callbacks(shader_toy_.get()); } App::~App() { - toplevel_.reset(); - wm_.reset(); - wl_display_flush(display_); - wl_display_flush(display_); + toplevel_.reset(); + wm_.reset(); + wl_display_flush(display_); + wl_display_flush(display_); } bool App::run() { - /// display_dispatch is blocking - return (toplevel_->is_valid() && wm_->display_dispatch() != -1); + /// display_dispatch is blocking + return (toplevel_->is_valid() && wm_->display_dispatch() != -1); } -void App::notify_seat_capabilities(Seat *seat, - wl_seat * /* seat */, +void App::notify_seat_capabilities(Seat* seat, + wl_seat* /* seat */, uint32_t /* caps */) { - if (seat) { - auto keyboard = seat->get_keyboard(); + if (seat) { + auto keyboard = seat->get_keyboard(); - if (keyboard.has_value()) { - keyboard.value()->register_observer(this, this); - } + if (keyboard.has_value()) { + keyboard.value()->register_observer(this, this); + } - auto pointer = seat->get_pointer(); - if (pointer.has_value()) { - pointer.value()->register_observer(this, this); - } + auto pointer = seat->get_pointer(); + if (pointer.has_value()) { + pointer.value()->register_observer(this, this); } + } } -void App::notify_seat_name(Seat * /* seat */, - wl_seat * /* seat */, - const char * /* name */) { -} +void App::notify_seat_name(Seat* /* seat */, + wl_seat* /* seat */, + const char* /* name */) {} -void App::notify_keyboard_enter(Keyboard * /* keyboard */, - wl_keyboard * /* wl_keyboard */, +void App::notify_keyboard_enter(Keyboard* /* keyboard */, + wl_keyboard* /* wl_keyboard */, uint32_t /* serial */, - wl_surface * /* surface */, - wl_array * /* keys */) { -} + wl_surface* /* surface */, + wl_array* /* keys */) {} -void App::notify_keyboard_leave(Keyboard * /* keyboard */, - wl_keyboard * /* wl_keyboard */, +void App::notify_keyboard_leave(Keyboard* /* keyboard */, + wl_keyboard* /* wl_keyboard */, uint32_t /* serial */, - wl_surface * /* surface */) { -} + wl_surface* /* surface */) {} -void App::notify_keyboard_keymap(Keyboard * /* keyboard */, - wl_keyboard * /* wl_keyboard */, +void App::notify_keyboard_keymap(Keyboard* /* keyboard */, + wl_keyboard* /* wl_keyboard */, uint32_t /* format */, int32_t /* fd */, - uint32_t /* size */) { -} + uint32_t /* size */) {} -void App::notify_keyboard_xkb_v1_key(Keyboard *keyboard, - wl_keyboard * /* wl_keyboard */, +void App::notify_keyboard_xkb_v1_key(Keyboard* keyboard, + wl_keyboard* /* wl_keyboard */, uint32_t /* serial */, uint32_t /* time */, uint32_t /* xkb_scancode */, bool /* key_repeats */, uint32_t state, int xdg_key_symbol_count, - const xkb_keysym_t *xdg_key_symbols) { - - if (xdg_key_symbol_count && state == KeyState::KEY_STATE_PRESS) { - - auto app = static_cast(keyboard->get_user_data()); - auto shader_toy = app->shader_toy_.get(); - - switch (xdg_key_symbols[0]) { - case XKB_KEY_Escape: - spdlog::info("Quit"); - app->toplevel_->close(); - break; - case XKB_KEY_space: - spdlog::info("Toggle Pause"); - shader_toy->toggle_pause(); - break; - case XKB_KEY_0: - spdlog::info("Toggle Draw Debug"); - shader_toy->toggle_draw_debug(); - break; - case XKB_KEY_1: - spdlog::info("Toggle FPS Lock"); - shader_toy->toggle_fps_lock(); - break; - case XKB_KEY_z: - spdlog::info("Screen shot"); - shader_toy->screen_shot(); - break; - case XKB_KEY_f: - case XKB_KEY_F11: - spdlog::info("Toggle fullscreen"); - app->toggle_fullscreen(); - break; - } + const xkb_keysym_t* xdg_key_symbols) { + if (xdg_key_symbol_count && state == KeyState::KEY_STATE_PRESS) { + auto app = static_cast(keyboard->get_user_data()); + auto shader_toy = app->shader_toy_.get(); + + switch (xdg_key_symbols[0]) { + case XKB_KEY_Escape: + spdlog::info("Quit"); + app->toplevel_->close(); + break; + case XKB_KEY_space: + spdlog::info("Toggle Pause"); + shader_toy->toggle_pause(); + break; + case XKB_KEY_0: + spdlog::info("Toggle Draw Debug"); + shader_toy->toggle_draw_debug(); + break; + case XKB_KEY_1: + spdlog::info("Toggle FPS Lock"); + shader_toy->toggle_fps_lock(); + break; + case XKB_KEY_z: + spdlog::info("Screen shot"); + shader_toy->screen_shot(); + break; + case XKB_KEY_f: + case XKB_KEY_F11: + spdlog::info("Toggle fullscreen"); + app->toggle_fullscreen(); + break; } + } } -void App::notify_pointer_enter(Pointer *pointer, - wl_pointer * /* pointer */, +void App::notify_pointer_enter(Pointer* pointer, + wl_pointer* /* pointer */, uint32_t serial, - wl_surface * /* surface */, + wl_surface* /* surface */, double /* sx */, double /* sy */) { - pointer->set_cursor(serial, "left_ptr"); + pointer->set_cursor(serial, "left_ptr"); } -void App::notify_pointer_leave(Pointer * /* pointer */, - wl_pointer * /* pointer */, +void App::notify_pointer_leave(Pointer* /* pointer */, + wl_pointer* /* pointer */, uint32_t /* serial */, - wl_surface * /* surface */) { -} + wl_surface* /* surface */) {} -void App::notify_pointer_motion(Pointer *pointer, - wl_pointer * /* pointer */, +void App::notify_pointer_motion(Pointer* pointer, + wl_pointer* /* pointer */, uint32_t /* time */, double sx, double sy) { - - auto app = static_cast(pointer->get_user_data()); - auto shader_toy = app->shader_toy_.get(); - auto os_window = shader_toy->get_app_os_window(); - os_window->app_data.iMouse[0] = sx; - os_window->app_data.iMouse[1] = os_window->app_data.iResolution[1] - sy; + auto app = static_cast(pointer->get_user_data()); + auto shader_toy = app->shader_toy_.get(); + auto os_window = shader_toy->get_app_os_window(); + os_window->app_data.iMouse[0] = sx; + os_window->app_data.iMouse[1] = os_window->app_data.iResolution[1] - sy; } -void App::notify_pointer_button(Pointer *pointer, - wl_pointer * /* pointer */, +void App::notify_pointer_button(Pointer* pointer, + wl_pointer* /* pointer */, uint32_t /* serial */, uint32_t /* time */, uint32_t button, uint32_t state) { - - auto app = static_cast(pointer->get_user_data()); - auto shader_toy = app->shader_toy_.get(); - auto os_window = shader_toy->get_app_os_window(); - - switch (button) { - case BTN_LEFT: - os_window->app_data.iMouse_click[0] = state; - if (state) { - os_window->app_data.iMouse_lclick[0] = static_cast(os_window->app_data.iMouse[0]); - os_window->app_data.iMouse_lclick[1] = static_cast(os_window->app_data.iResolution[1] - - os_window->app_data.iMouse[1]); - } else { - os_window->app_data.iMouse_lclick[0] = -os_window->app_data.iMouse_lclick[0]; - os_window->app_data.iMouse_lclick[1] = -os_window->app_data.iMouse_lclick[1]; - } - break; - case BTN_MIDDLE: - break; - case BTN_RIGHT: - os_window->app_data.iMouse_click[1] = state; - if (state) { - os_window->app_data.iMouse_rclick[0] = static_cast(os_window->app_data.iMouse[0]); - os_window->app_data.iMouse_rclick[1] = static_cast(os_window->app_data.iResolution[1] - - os_window->app_data.iMouse[1]); - } else { - os_window->app_data.iMouse_rclick[0] = -os_window->app_data.iMouse_rclick[0]; - os_window->app_data.iMouse_rclick[1] = -os_window->app_data.iMouse_rclick[1]; - } - break; - default: - break; - } -} - -void App::notify_pointer_axis(Pointer * /* pointer */, - wl_pointer * /* pointer */, + auto app = static_cast(pointer->get_user_data()); + auto shader_toy = app->shader_toy_.get(); + auto os_window = shader_toy->get_app_os_window(); + + switch (button) { + case BTN_LEFT: + os_window->app_data.iMouse_click[0] = state; + if (state) { + os_window->app_data.iMouse_lclick[0] = + static_cast(os_window->app_data.iMouse[0]); + os_window->app_data.iMouse_lclick[1] = static_cast( + os_window->app_data.iResolution[1] - os_window->app_data.iMouse[1]); + } else { + os_window->app_data.iMouse_lclick[0] = + -os_window->app_data.iMouse_lclick[0]; + os_window->app_data.iMouse_lclick[1] = + -os_window->app_data.iMouse_lclick[1]; + } + break; + case BTN_MIDDLE: + break; + case BTN_RIGHT: + os_window->app_data.iMouse_click[1] = state; + if (state) { + os_window->app_data.iMouse_rclick[0] = + static_cast(os_window->app_data.iMouse[0]); + os_window->app_data.iMouse_rclick[1] = static_cast( + os_window->app_data.iResolution[1] - os_window->app_data.iMouse[1]); + } else { + os_window->app_data.iMouse_rclick[0] = + -os_window->app_data.iMouse_rclick[0]; + os_window->app_data.iMouse_rclick[1] = + -os_window->app_data.iMouse_rclick[1]; + } + break; + default: + break; + } +} + +void App::notify_pointer_axis(Pointer* /* pointer */, + wl_pointer* /* pointer */, uint32_t /* time */, uint32_t /* axis */, - double /* value */) { -} + double /* value */) {} -void App::notify_pointer_frame(Pointer * /* pointer */, - wl_pointer * /* pointer */) { -}; +void App::notify_pointer_frame(Pointer* /* pointer */, + wl_pointer* /* pointer */) {}; -void App::notify_pointer_axis_source(Pointer * /* pointer */, - wl_pointer * /* pointer */, - uint32_t /* axis_source */) { -}; +void App::notify_pointer_axis_source(Pointer* /* pointer */, + wl_pointer* /* pointer */, + uint32_t /* axis_source */) {}; -void App::notify_pointer_axis_stop(Pointer * /* pointer */, - wl_pointer * /* pointer */, +void App::notify_pointer_axis_stop(Pointer* /* pointer */, + wl_pointer* /* pointer */, uint32_t /* time */, - uint32_t /* axis */) { -}; + uint32_t /* axis */) {}; -void App::notify_pointer_axis_discrete(Pointer * /* pointer */, - wl_pointer * /*pointer */, +void App::notify_pointer_axis_discrete(Pointer* /* pointer */, + wl_pointer* /*pointer */, uint32_t /* axis */, - int32_t /* discrete */) { -} + int32_t /* discrete */) {} diff --git a/examples/vk-shadertoy/app.h b/examples/vk-shadertoy/app.h index deefa17..fb38675 100644 --- a/examples/vk-shadertoy/app.h +++ b/examples/vk-shadertoy/app.h @@ -25,118 +25,120 @@ #include "shader_toy.h" #include "waypp/window/xdg_toplevel.h" -class App : public SeatObserver, public PointerObserver, public KeyboardObserver { -public: - static constexpr char kAppTitle[] = "Shadertoy"; - static constexpr char kAppId[] = "org.waypp.vk-shadertoy"; - - struct Configuration { - uint32_t dev_index; - bool use_gpu_idx; - int present_mode; - bool debug; - bool reload_shaders; - int width; - int height; - bool disable_cursor; - bool fullscreen; - bool maximized; - bool tearing; - }; - - explicit App(const Configuration &config); - - ~App() override; - - bool run(); - - void toggle_fullscreen() { toplevel_->set_fullscreen(); } - -private: - static constexpr int kResizeMargin = 12; - struct wl_display *display_; - std::unique_ptr logging_; - std::shared_ptr wm_; - std::unique_ptr shader_toy_; - std::shared_ptr toplevel_; - - static void draw_frame(void *data, uint32_t time); - - void notify_seat_capabilities(Seat *seat, wl_seat *, uint32_t) override; - - void notify_seat_name(Seat *, wl_seat *, const char *name) override; - - void notify_keyboard_enter(Keyboard *, - wl_keyboard *, - uint32_t, - wl_surface *, - wl_array *) override; - - void notify_keyboard_leave(Keyboard *, - wl_keyboard *, - uint32_t, - wl_surface *) override; - - void notify_keyboard_keymap(Keyboard *, - wl_keyboard *, - uint32_t, - int32_t, - uint32_t) override; - - void notify_keyboard_xkb_v1_key(Keyboard *, - wl_keyboard *, - uint32_t, - uint32_t, - uint32_t, - bool, - uint32_t, - int, - const xkb_keysym_t *) override; - - void notify_pointer_enter(Pointer *, - wl_pointer *, - uint32_t, - wl_surface *, - double, - double) override; +class App : public SeatObserver, + public PointerObserver, + public KeyboardObserver { + public: + static constexpr char kAppTitle[] = "Shadertoy"; + static constexpr char kAppId[] = "org.waypp.vk-shadertoy"; + + struct Configuration { + uint32_t dev_index; + bool use_gpu_idx; + int present_mode; + bool debug; + bool reload_shaders; + int width; + int height; + bool disable_cursor; + bool fullscreen; + bool maximized; + bool tearing; + }; + + explicit App(const Configuration& config); + + ~App() override; + + bool run(); + + void toggle_fullscreen() { toplevel_->set_fullscreen(); } + + private: + static constexpr int kResizeMargin = 12; + struct wl_display* display_; + std::unique_ptr logging_; + std::shared_ptr wm_; + std::unique_ptr shader_toy_; + std::shared_ptr toplevel_; + + static void draw_frame(void* data, uint32_t time); + + void notify_seat_capabilities(Seat* seat, wl_seat*, uint32_t) override; + + void notify_seat_name(Seat*, wl_seat*, const char* name) override; + + void notify_keyboard_enter(Keyboard*, + wl_keyboard*, + uint32_t, + wl_surface*, + wl_array*) override; - void notify_pointer_leave(Pointer *, - wl_pointer *, - uint32_t, - wl_surface *) override; - - void notify_pointer_motion(Pointer *, - wl_pointer *, - uint32_t, - double, - double) override; - - void notify_pointer_button(Pointer *, - wl_pointer *, - uint32_t, - uint32_t, - uint32_t, - uint32_t state) override; - - void notify_pointer_axis(Pointer *, - wl_pointer *, + void notify_keyboard_leave(Keyboard*, + wl_keyboard*, uint32_t, + wl_surface*) override; + + void notify_keyboard_keymap(Keyboard*, + wl_keyboard*, + uint32_t, + int32_t, + uint32_t) override; + + void notify_keyboard_xkb_v1_key(Keyboard*, + wl_keyboard*, + uint32_t, + uint32_t, + uint32_t, + bool, + uint32_t, + int, + const xkb_keysym_t*) override; + + void notify_pointer_enter(Pointer*, + wl_pointer*, + uint32_t, + wl_surface*, + double, + double) override; + + void notify_pointer_leave(Pointer*, + wl_pointer*, + uint32_t, + wl_surface*) override; + + void notify_pointer_motion(Pointer*, + wl_pointer*, uint32_t, + double, double) override; - void notify_pointer_frame(Pointer *, wl_pointer *) override; + void notify_pointer_button(Pointer*, + wl_pointer*, + uint32_t, + uint32_t, + uint32_t, + uint32_t state) override; - void notify_pointer_axis_source(Pointer *, - wl_pointer *, - uint32_t axis_source) override; + void notify_pointer_axis(Pointer*, + wl_pointer*, + uint32_t, + uint32_t, + double) override; - void notify_pointer_axis_stop(Pointer *, - wl_pointer *, - uint32_t, - uint32_t axis) override; + void notify_pointer_frame(Pointer*, wl_pointer*) override; + + void notify_pointer_axis_source(Pointer*, + wl_pointer*, + uint32_t axis_source) override; + + void notify_pointer_axis_stop(Pointer*, + wl_pointer*, + uint32_t, + uint32_t axis) override; - void notify_pointer_axis_discrete(Pointer *, - wl_pointer *, - uint32_t axis, - int32_t discrete) override; + void notify_pointer_axis_discrete(Pointer*, + wl_pointer*, + uint32_t axis, + int32_t discrete) override; }; diff --git a/examples/vk-shadertoy/main.cc b/examples/vk-shadertoy/main.cc index bead127..0217af6 100644 --- a/examples/vk-shadertoy/main.cc +++ b/examples/vk-shadertoy/main.cc @@ -41,17 +41,17 @@ static volatile bool gRunning = true; * @return void */ void handle_signal(const int signal) { - if (signal == SIGINT) { - gRunning = false; - } + if (signal == SIGINT) { + gRunning = false; + } } -int main(const int argc, char **argv) { - std::signal(SIGINT, handle_signal); +int main(const int argc, char** argv) { + std::signal(SIGINT, handle_signal); - cxxopts::Options options("vk-shadertoy", "Vulkan Shadertoy Launcher"); - options.add_options() - // clang-format off + cxxopts::Options options("vk-shadertoy", "Vulkan Shadertoy Launcher"); + options.add_options() + // clang-format off ("g,gpu", "GPU index", cxxopts::value()->default_value("255")) ("p,present", "Present Mode", cxxopts::value()->default_value("2")) ("r,reload_shaders", "Reload shaders on re-size") @@ -63,25 +63,25 @@ int main(const int argc, char **argv) { ("m,maximized", "Run in maximized mode") ("t,tearing", "Enable tearing via the tearing_control protocol"); - // clang-format on - const auto result = options.parse(argc, argv); + // clang-format on + const auto result = options.parse(argc, argv); - App app({ - .dev_index = result["gpu"].as(), - .use_gpu_idx = result["gpu"].as() < 255, - .present_mode = result["present"].as(), - .debug = result["debug"].as(), - .reload_shaders = result["reload_shaders"].as(), - .width = result["width"].as(), - .height = result["height"].as(), - .disable_cursor = result["disable-cursor"].as(), - .fullscreen = result["fullscreen"].as(), - .maximized = result["maximized"].as(), - .tearing = result["tearing"].as(), - }); + App app({ + .dev_index = result["gpu"].as(), + .use_gpu_idx = result["gpu"].as() < 255, + .present_mode = result["present"].as(), + .debug = result["debug"].as(), + .reload_shaders = result["reload_shaders"].as(), + .width = result["width"].as(), + .height = result["height"].as(), + .disable_cursor = result["disable-cursor"].as(), + .fullscreen = result["fullscreen"].as(), + .maximized = result["maximized"].as(), + .tearing = result["tearing"].as(), + }); - while (gRunning && app.run()) { - } + while (gRunning && app.run()) { + } - return EXIT_SUCCESS; + return EXIT_SUCCESS; } \ No newline at end of file diff --git a/examples/vk-shadertoy/shader_toy.cc b/examples/vk-shadertoy/shader_toy.cc index 88e5d37..b625098 100644 --- a/examples/vk-shadertoy/shader_toy.cc +++ b/examples/vk-shadertoy/shader_toy.cc @@ -291,7 +291,7 @@ vk_error ShaderToy::allocate_render_data(vk_physical_device* phy_dev, } #endif } - struct VkExtent2D init_size {}; + struct VkExtent2D init_size{}; #if defined(VK_USE_PLATFORM_WAYLAND_KHR) init_size.width = resize_size_[0]; init_size.height = resize_size_[1]; @@ -458,7 +458,7 @@ vk_error ShaderToy::allocate_render_data(vk_physical_device* phy_dev, .pSetLayouts = &render_data->buf_layout[i].set_layout, }; auto res = d.vkAllocateDescriptorSets(dev->device, &set_info, - &render_data->buf_desc_set[i]); + &render_data->buf_desc_set[i]); retval = VK_ERROR_NONE; vk_error_set_vkresult(&retval, res); if (res) { @@ -556,7 +556,7 @@ vk_error ShaderToy::allocate_render_data(vk_physical_device* phy_dev, .pSetLayouts = &render_data->main_layout.set_layout, }; auto res = d.vkAllocateDescriptorSets(dev->device, &set_info, - &render_data->main_desc_set); + &render_data->main_desc_set); retval = VK_ERROR_NONE; vk_error_set_vkresult(&retval, res); if (res) { diff --git a/examples/vk-shadertoy/shader_toy.h b/examples/vk-shadertoy/shader_toy.h index e6d5684..a747d34 100644 --- a/examples/vk-shadertoy/shader_toy.h +++ b/examples/vk-shadertoy/shader_toy.h @@ -21,193 +21,229 @@ * DEALINGS IN THE SOFTWARE. */ -// Danil, 2021+ Vulkan shader launcher, self https://github.com/danilw/vulkan-shadertoy-launcher -// The MIT License +// Danil, 2021+ Vulkan shader launcher, self +// https://github.com/danilw/vulkan-shadertoy-launcher The MIT License #pragma once -#include "vulkan/utils.h" #include "vulkan/render.h" +#include "vulkan/utils.h" class VulkanUtils; class VulkanRender; class ShaderToy : public VulkanUtils, public VulkanRender { -public: - - ShaderToy(); - - ~ShaderToy(); - - int init(int width, int height, struct wl_display *wl_display, struct wl_surface *wl_surface, uint32_t dev_index, - bool use_gpu_idx, bool debug, bool reload_shaders, - VkPresentModeKHR present_mode = VkPresentModeKHR::VK_PRESENT_MODE_FIFO_KHR); - - void draw_frame(uint32_t time); - - struct app_os_window *get_app_os_window() { return &os_window_; } - - void toggle_pause() { os_window_.app_data.pause = !os_window_.app_data.pause; } - - void toggle_draw_debug() { os_window_.app_data.drawdebug = !os_window_.app_data.drawdebug; } - - void toggle_fps_lock() { os_window_.fps_lock = !os_window_.fps_lock; } - - void screen_shot() { screenshot_once_ = true; } - -private: - - uint32_t resize_size_[2]{}; - - bool main_image_srgb_ = false; // srgb surface fix - - // keyboard is texture that send from this data - uint8_t keyboard_texture_[256 * 3 * 4]{}; // texture - bool keyboard_draw_{}; - bool screenshot_once_{}; - - // update to 2021 Shadertoy iMouse.w change https://www.shadertoy.com/view/llySRh (comments) - bool last_iMousel_clicked_[2] = {}; - - // do not edit, it just to see where keyboard texture used - static constexpr uint32_t iKeyboard = UINT32_C(1); - - // to build-in compressed shaders into bin(exe) file - // used OFFSCREEN_BUFFERS size, names of .hex files should be set manually(and edit yariv_shaders[]), this example using 4 buffers same as on shadertoy - //#define YARIV_SHADER - - struct shaders_push_constants { - float iMouse[4]; - float iDate[4]; - int iMouse_lr[2]; - float iResolution[2]; - int debugdraw; // look function check_hotkeys - int pCustom; //custom data - float iTime; - float iTimeDelta; - int iFrame; - }; - - enum { - BUFFER_VERTICES = 0, - BUFFER_INDICES = 1, - }; - enum { - SHADER_MAIN_VERTEX = 0, - SHADER_MAIN_FRAGMENT = 1, - }; - - struct render_data { - struct objects { - struct vertex { - float pos[3]; - } vertices[3]; - - uint16_t indices[3]; - } objects; - - struct shaders_push_constants push_constants; - - struct vk_image images[IMAGE_TEXTURES + OFFSCREEN_BUFFERS + iKeyboard]; - struct vk_buffer buffers[2]; - struct vk_shader shaders[2 + OFFSCREEN_BUFFERS * 2]; - struct vk_graphics_buffers *main_gbuffers; - struct vk_offscreen_buffers *buf_obuffers; - - VkRenderPass buf_render_pass[OFFSCREEN_BUFFERS]; - struct vk_layout buf_layout[OFFSCREEN_BUFFERS]; - struct vk_pipeline buf_pipeline[OFFSCREEN_BUFFERS]; - VkDescriptorSet buf_desc_set[OFFSCREEN_BUFFERS]; - - VkRenderPass main_render_pass; - struct vk_layout main_layout; - struct vk_pipeline main_pipeline; - VkDescriptorSet main_desc_set; - - } render_data_{}; - - uint32_t dev_index_{}; - bool use_gpu_idx_{}; - - VkInstance vk_{}; - struct vk_physical_device phy_dev_{}; - struct vk_device dev_{}; - struct vk_swapchain swapchain_{}; - struct app_os_window os_window_{}; - - struct vk_render_essentials essentials_{}; - - VkFence offscreen_fence_ = VK_NULL_HANDLE; - VkQueue offscreen_queue_[OFFSCREEN_BUFFERS] = {VK_NULL_HANDLE}; - VkCommandBuffer offscreen_cmd_buffer_[OFFSCREEN_BUFFERS] = {VK_NULL_HANDLE}; - VkSemaphore wait_buf_sem_ = VK_NULL_HANDLE; - VkSemaphore wait_main_sem_ = VK_NULL_HANDLE; - bool first_submission_ = true; - - void update_key_map(int w, int h, bool val); - - void update_keypress(); - - void check_hotkeys(struct app_os_window *os_window); - - vk_error allocate_render_data(struct vk_physical_device *phy_dev, struct vk_device *dev, - struct vk_swapchain *swapchain, struct vk_render_essentials *essentials, - struct render_data *render_data, bool reload_shaders); - - static void free_render_data(struct vk_device *dev, struct vk_render_essentials *essentials, - struct render_data *render_data); - - static void exit_cleanup_render_loop(struct vk_device *dev, struct vk_render_essentials *essentials, - struct render_data *render_data, VkSemaphore wait_buf_sem, - VkSemaphore wait_main_sem, VkFence offscreen_fence); - - void - render_loop_init(struct vk_physical_device *phy_dev, struct vk_device *dev, struct vk_swapchain *swapchain, - struct app_os_window *os_window); - - static void exit_cleanup(VkInstance vk, struct vk_device *dev, struct vk_swapchain *swapchain); - - bool on_window_resize(struct vk_physical_device *phy_dev, struct vk_device *dev, - struct vk_render_essentials *essentials, struct vk_swapchain *swapchain, - struct render_data *render_data, struct app_os_window *os_window); - - static void update_params(struct app_data_struct *app_data, bool fps_lock); - - void set_push_constants(struct app_os_window *os_window); - - void update_push_constants_window_size(struct app_os_window *os_window); - - void update_push_constants_local_size(float width, float height); - - static bool render_loop_buf(struct vk_physical_device * /* phy_dev */, struct vk_device *dev, - struct vk_render_essentials *essentials, struct render_data *render_data, - VkCommandBuffer cmd_buffer, int render_index, int buffer_index, - struct app_data_struct * /* app_data */); - - bool - render_loop_draw(struct vk_physical_device *phy_dev, struct vk_device *dev, struct vk_swapchain *swapchain, - struct app_os_window *os_window); - - bool update_iKeyboard_texture(struct vk_physical_device * /* phy_dev */, struct vk_device * /* dev */, - struct vk_render_essentials * /* essentials */, - struct render_data * /* render_data */); - - static vk_error - transition_images_screenshot_swapchain_begin(struct vk_device *dev, struct vk_render_essentials *essentials, - struct vk_image *srcImage, struct vk_image *dstImage); - - static vk_error - transition_images_screenshot_swapchain_end(struct vk_device *dev, struct vk_render_essentials *essentials, - struct vk_image *srcImage, struct vk_image *dstImage); - -// RGBA BMP from https://en.wikipedia.org/wiki/BMP_file_format - static inline unsigned char ev(int32_t v); - - static void write_bmp(uint32_t w, uint32_t h, const uint8_t *rgba); - - static vk_error - make_screenshot(struct vk_physical_device *phy_dev, struct vk_device *dev, struct vk_swapchain *swapchain, - struct vk_render_essentials *essentials, struct render_data *render_data, - uint32_t image_index); + public: + ShaderToy(); + + ~ShaderToy(); + + int init(int width, + int height, + struct wl_display* wl_display, + struct wl_surface* wl_surface, + uint32_t dev_index, + bool use_gpu_idx, + bool debug, + bool reload_shaders, + VkPresentModeKHR present_mode = + VkPresentModeKHR::VK_PRESENT_MODE_FIFO_KHR); + + void draw_frame(uint32_t time); + + struct app_os_window* get_app_os_window() { return &os_window_; } + + void toggle_pause() { + os_window_.app_data.pause = !os_window_.app_data.pause; + } + + void toggle_draw_debug() { + os_window_.app_data.drawdebug = !os_window_.app_data.drawdebug; + } + + void toggle_fps_lock() { os_window_.fps_lock = !os_window_.fps_lock; } + + void screen_shot() { screenshot_once_ = true; } + + private: + uint32_t resize_size_[2]{}; + + bool main_image_srgb_ = false; // srgb surface fix + + // keyboard is texture that send from this data + uint8_t keyboard_texture_[256 * 3 * 4]{}; // texture + bool keyboard_draw_{}; + bool screenshot_once_{}; + + // update to 2021 Shadertoy iMouse.w change + // https://www.shadertoy.com/view/llySRh (comments) + bool last_iMousel_clicked_[2] = {}; + + // do not edit, it just to see where keyboard texture used + static constexpr uint32_t iKeyboard = UINT32_C(1); + + // to build-in compressed shaders into bin(exe) file + // used OFFSCREEN_BUFFERS size, names of .hex files should be set manually(and + // edit yariv_shaders[]), this example using 4 buffers same as on shadertoy + // #define YARIV_SHADER + + struct shaders_push_constants { + float iMouse[4]; + float iDate[4]; + int iMouse_lr[2]; + float iResolution[2]; + int debugdraw; // look function check_hotkeys + int pCustom; // custom data + float iTime; + float iTimeDelta; + int iFrame; + }; + + enum { + BUFFER_VERTICES = 0, + BUFFER_INDICES = 1, + }; + enum { + SHADER_MAIN_VERTEX = 0, + SHADER_MAIN_FRAGMENT = 1, + }; + + struct render_data { + struct objects { + struct vertex { + float pos[3]; + } vertices[3]; + + uint16_t indices[3]; + } objects; + + struct shaders_push_constants push_constants; + + struct vk_image images[IMAGE_TEXTURES + OFFSCREEN_BUFFERS + iKeyboard]; + struct vk_buffer buffers[2]; + struct vk_shader shaders[2 + OFFSCREEN_BUFFERS * 2]; + struct vk_graphics_buffers* main_gbuffers; + struct vk_offscreen_buffers* buf_obuffers; + + VkRenderPass buf_render_pass[OFFSCREEN_BUFFERS]; + struct vk_layout buf_layout[OFFSCREEN_BUFFERS]; + struct vk_pipeline buf_pipeline[OFFSCREEN_BUFFERS]; + VkDescriptorSet buf_desc_set[OFFSCREEN_BUFFERS]; + + VkRenderPass main_render_pass; + struct vk_layout main_layout; + struct vk_pipeline main_pipeline; + VkDescriptorSet main_desc_set; + + } render_data_{}; + + uint32_t dev_index_{}; + bool use_gpu_idx_{}; + + VkInstance vk_{}; + struct vk_physical_device phy_dev_{}; + struct vk_device dev_{}; + struct vk_swapchain swapchain_{}; + struct app_os_window os_window_{}; + + struct vk_render_essentials essentials_{}; + + VkFence offscreen_fence_ = VK_NULL_HANDLE; + VkQueue offscreen_queue_[OFFSCREEN_BUFFERS] = {VK_NULL_HANDLE}; + VkCommandBuffer offscreen_cmd_buffer_[OFFSCREEN_BUFFERS] = {VK_NULL_HANDLE}; + VkSemaphore wait_buf_sem_ = VK_NULL_HANDLE; + VkSemaphore wait_main_sem_ = VK_NULL_HANDLE; + bool first_submission_ = true; + + void update_key_map(int w, int h, bool val); + + void update_keypress(); + + void check_hotkeys(struct app_os_window* os_window); + + vk_error allocate_render_data(struct vk_physical_device* phy_dev, + struct vk_device* dev, + struct vk_swapchain* swapchain, + struct vk_render_essentials* essentials, + struct render_data* render_data, + bool reload_shaders); + + static void free_render_data(struct vk_device* dev, + struct vk_render_essentials* essentials, + struct render_data* render_data); + + static void exit_cleanup_render_loop(struct vk_device* dev, + struct vk_render_essentials* essentials, + struct render_data* render_data, + VkSemaphore wait_buf_sem, + VkSemaphore wait_main_sem, + VkFence offscreen_fence); + + void render_loop_init(struct vk_physical_device* phy_dev, + struct vk_device* dev, + struct vk_swapchain* swapchain, + struct app_os_window* os_window); + + static void exit_cleanup(VkInstance vk, + struct vk_device* dev, + struct vk_swapchain* swapchain); + + bool on_window_resize(struct vk_physical_device* phy_dev, + struct vk_device* dev, + struct vk_render_essentials* essentials, + struct vk_swapchain* swapchain, + struct render_data* render_data, + struct app_os_window* os_window); + + static void update_params(struct app_data_struct* app_data, bool fps_lock); + + void set_push_constants(struct app_os_window* os_window); + + void update_push_constants_window_size(struct app_os_window* os_window); + + void update_push_constants_local_size(float width, float height); + + static bool render_loop_buf(struct vk_physical_device* /* phy_dev */, + struct vk_device* dev, + struct vk_render_essentials* essentials, + struct render_data* render_data, + VkCommandBuffer cmd_buffer, + int render_index, + int buffer_index, + struct app_data_struct* /* app_data */); + + bool render_loop_draw(struct vk_physical_device* phy_dev, + struct vk_device* dev, + struct vk_swapchain* swapchain, + struct app_os_window* os_window); + + bool update_iKeyboard_texture(struct vk_physical_device* /* phy_dev */, + struct vk_device* /* dev */, + struct vk_render_essentials* /* essentials */, + struct render_data* /* render_data */); + + static vk_error transition_images_screenshot_swapchain_begin( + struct vk_device* dev, + struct vk_render_essentials* essentials, + struct vk_image* srcImage, + struct vk_image* dstImage); + + static vk_error transition_images_screenshot_swapchain_end( + struct vk_device* dev, + struct vk_render_essentials* essentials, + struct vk_image* srcImage, + struct vk_image* dstImage); + + // RGBA BMP from https://en.wikipedia.org/wiki/BMP_file_format + static inline unsigned char ev(int32_t v); + + static void write_bmp(uint32_t w, uint32_t h, const uint8_t* rgba); + + static vk_error make_screenshot(struct vk_physical_device* phy_dev, + struct vk_device* dev, + struct vk_swapchain* swapchain, + struct vk_render_essentials* essentials, + struct render_data* render_data, + uint32_t image_index); }; \ No newline at end of file diff --git a/examples/vk-shadertoy/textures.h b/examples/vk-shadertoy/textures.h index e98c23f..a124cc0 100644 --- a/examples/vk-shadertoy/textures.h +++ b/examples/vk-shadertoy/textures.h @@ -21,8 +21,8 @@ * DEALINGS IN THE SOFTWARE. */ -// Danil, 2021+ Vulkan shader launcher, self https://github.com/danilw/vulkan-shadertoy-launcher -// The MIT License +// Danil, 2021+ Vulkan shader launcher, self +// https://github.com/danilw/vulkan-shadertoy-launcher The MIT License #include "vulkan/render.h" @@ -30,81 +30,102 @@ class VulkanRender; -static vk_error -init_texture_mem(struct vk_physical_device *phy_dev, struct vk_device *dev, struct vk_render_essentials *essentials, - struct vk_image *image, uint8_t *texture, int width, int height, const char *name, bool mipmaps, - bool linear) { - vk_error retval = VK_ERROR_NONE; - VkFormat img_format = VK_FORMAT_R8G8B8A8_UNORM; //VK_FORMAT_R8G8B8A8_SRGB - *image = (struct vk_image) { - .format = img_format, - .extent = {.width = static_cast(width), .height = static_cast(height)}, - .usage = (VkImageUsageFlagBits) (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | - VK_IMAGE_USAGE_TRANSFER_SRC_BIT), - .stage = VK_SHADER_STAGE_FRAGMENT_BIT, - .make_view = true, - .host_visible = false, - .anisotropyEnable = true, - .repeat_mode = VK_SAMPLER_ADDRESS_MODE_REPEAT, //VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER //VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE - .mipmaps = mipmaps, - .linear = linear || mipmaps, - }; +static vk_error init_texture_mem(struct vk_physical_device* phy_dev, + struct vk_device* dev, + struct vk_render_essentials* essentials, + struct vk_image* image, + uint8_t* texture, + int width, + int height, + const char* name, + bool mipmaps, + bool linear) { + vk_error retval = VK_ERROR_NONE; + VkFormat img_format = VK_FORMAT_R8G8B8A8_UNORM; // VK_FORMAT_R8G8B8A8_SRGB + *image = (struct vk_image){ + .format = img_format, + .extent = {.width = static_cast(width), + .height = static_cast(height)}, + .usage = (VkImageUsageFlagBits)(VK_IMAGE_USAGE_SAMPLED_BIT | + VK_IMAGE_USAGE_TRANSFER_DST_BIT | + VK_IMAGE_USAGE_TRANSFER_SRC_BIT), + .stage = VK_SHADER_STAGE_FRAGMENT_BIT, + .make_view = true, + .host_visible = false, + .anisotropyEnable = true, + .repeat_mode = + VK_SAMPLER_ADDRESS_MODE_REPEAT, // VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER + // //VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE + .mipmaps = mipmaps, + .linear = linear || mipmaps, + }; - retval = VulkanUtils::create_images(phy_dev, dev, image, 1); - if (!vk_error_is_success(&retval)) { - retval.error.type = VK_ERROR_ERRNO; - vk_error_printf(&retval, "Failed to create texture images\n"); - return retval; - } - retval = VulkanRender::init_texture(phy_dev, dev, essentials, image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - texture, - name); + retval = VulkanUtils::create_images(phy_dev, dev, image, 1); + if (!vk_error_is_success(&retval)) { + retval.error.type = VK_ERROR_ERRNO; + vk_error_printf(&retval, "Failed to create texture images\n"); return retval; + } + retval = VulkanRender::init_texture(phy_dev, dev, essentials, image, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + texture, name); + return retval; } #ifdef USE_stb_image -static vk_error -init_texture_file(struct vk_physical_device *phy_dev, struct vk_device *dev, struct vk_render_essentials *essentials, - struct vk_image *image, const char *name, bool mipmaps) { - vk_error retval = VK_ERROR_NONE; - int width, height, channels; - stbi_set_flip_vertically_on_load(true); //flip image Y - uint8_t *generated_texture = stbi_load(name, &width, &height, &channels, STBI_rgb_alpha); - if (generated_texture == nullptr) { - retval.error.type = VK_ERROR_ERRNO; - spdlog::error("Error in loading image {}", name); - return retval; - } - - retval = init_texture_mem(phy_dev, dev, essentials, image, generated_texture, width, height, name, mipmaps, true); - stbi_image_free(generated_texture); +static vk_error init_texture_file(struct vk_physical_device* phy_dev, + struct vk_device* dev, + struct vk_render_essentials* essentials, + struct vk_image* image, + const char* name, + bool mipmaps) { + vk_error retval = VK_ERROR_NONE; + int width, height, channels; + stbi_set_flip_vertically_on_load(true); // flip image Y + uint8_t* generated_texture = + stbi_load(name, &width, &height, &channels, STBI_rgb_alpha); + if (generated_texture == nullptr) { + retval.error.type = VK_ERROR_ERRNO; + spdlog::error("Error in loading image {}", name); return retval; + } + + retval = init_texture_mem(phy_dev, dev, essentials, image, generated_texture, + width, height, name, mipmaps, true); + stbi_image_free(generated_texture); + return retval; } #endif -static vk_error -texture_empty(struct vk_physical_device *phy_dev, struct vk_device *dev, struct vk_render_essentials *essentials, - struct vk_image *image, int width, int height) { - vk_error retval = VK_ERROR_NONE; - size_t texture_size = static_cast(width * height * 4) * sizeof(uint8_t); - auto *generated_texture = (uint8_t *) malloc(texture_size); - if (generated_texture == nullptr) { - retval.error.type = VK_ERROR_ERRNO; - spdlog::error("Error in allocating memory"); - return retval; - } - for (unsigned int i = 0; i < height; ++i) { - for (unsigned int j = 0; j < width; ++j) { - size_t pixel = (i * static_cast(width) + j) * 4 * sizeof(uint8_t); - generated_texture[pixel + 0] = 0x00; - generated_texture[pixel + 1] = 0x00; - generated_texture[pixel + 2] = 0x00; - generated_texture[pixel + 3] = 0x00; - } - } - retval = init_texture_mem(phy_dev, dev, essentials, image, generated_texture, width, height, "empty", false, false); - free(generated_texture); +static vk_error texture_empty(struct vk_physical_device* phy_dev, + struct vk_device* dev, + struct vk_render_essentials* essentials, + struct vk_image* image, + int width, + int height) { + vk_error retval = VK_ERROR_NONE; + size_t texture_size = + static_cast(width * height * 4) * sizeof(uint8_t); + auto* generated_texture = (uint8_t*)malloc(texture_size); + if (generated_texture == nullptr) { + retval.error.type = VK_ERROR_ERRNO; + spdlog::error("Error in allocating memory"); return retval; + } + for (unsigned int i = 0; i < height; ++i) { + for (unsigned int j = 0; j < width; ++j) { + size_t pixel = + (i * static_cast(width) + j) * 4 * sizeof(uint8_t); + generated_texture[pixel + 0] = 0x00; + generated_texture[pixel + 1] = 0x00; + generated_texture[pixel + 2] = 0x00; + generated_texture[pixel + 3] = 0x00; + } + } + retval = init_texture_mem(phy_dev, dev, essentials, image, generated_texture, + width, height, "empty", false, false); + free(generated_texture); + return retval; } diff --git a/examples/vk-shadertoy/vulkan/common.h b/examples/vk-shadertoy/vulkan/common.h index f1f6598..cf5c09d 100644 --- a/examples/vk-shadertoy/vulkan/common.h +++ b/examples/vk-shadertoy/vulkan/common.h @@ -24,7 +24,6 @@ #ifndef EXAMPLES_VK_SHADERTOY_VULKAN_COMMON_H_ #define EXAMPLES_VK_SHADERTOY_VULKAN_COMMON_H_ - #define VULKAN_HPP_NO_EXCEPTIONS 1 #define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1 #include @@ -38,8 +37,7 @@ vk::resultCheck(static_cast(x), LOCATION); \ } while (0) -#include "vulkan/vk_struct.h" #include "vulkan/vk_error_print.h" +#include "vulkan/vk_struct.h" - -#endif // EXAMPLES_VK_SHADERTOY_VULKAN_COMMON_H_ +#endif // EXAMPLES_VK_SHADERTOY_VULKAN_COMMON_H_ diff --git a/examples/vk-shadertoy/vulkan/render.cc b/examples/vk-shadertoy/vulkan/render.cc index 68a8b63..83346ec 100644 --- a/examples/vk-shadertoy/vulkan/render.cc +++ b/examples/vk-shadertoy/vulkan/render.cc @@ -72,7 +72,7 @@ int VulkanRender::get_essentials(vk_render_essentials* essentials, }; auto res = d.vkCreateSemaphore(dev->device, &sem_info, nullptr, - &essentials->sem_post_acquire); + &essentials->sem_post_acquire); vk_error_set_vkresult(&retval, res); if (res) { vk_error_printf(&retval, "Failed to create post-acquire semaphore\n"); @@ -132,12 +132,10 @@ VkResult VulkanRender::start(vk_render_essentials* essentials, if (res == VK_SUBOPTIMAL_KHR) { spdlog::warn("presentation is suboptimal."); - } - else if (res == VK_ERROR_OUT_OF_DATE_KHR) { + } else if (res == VK_ERROR_OUT_OF_DATE_KHR) { // this is not error, this is resize event for AMD hardware return res; - } - else if (res < 0) { + } else if (res < 0) { vk_error_printf(&retval, "Couldn't acquire image\n"); return res; } diff --git a/examples/vk-shadertoy/vulkan/utils.cc b/examples/vk-shadertoy/vulkan/utils.cc index ebdbc73..6d3d2eb 100644 --- a/examples/vk-shadertoy/vulkan/utils.cc +++ b/examples/vk-shadertoy/vulkan/utils.cc @@ -1223,8 +1223,8 @@ vk_error VulkanUtils::make_graphics_layouts(vk_device* dev, set_layout_info.bindingCount = binding_count; set_layout_info.pBindings = set_layout_bindings; - auto res = d.vkCreateDescriptorSetLayout(dev->device, &set_layout_info, nullptr, - &layout->set_layout); + auto res = d.vkCreateDescriptorSetLayout(dev->device, &set_layout_info, + nullptr, &layout->set_layout); vk_error_sub_set_vkresult(&retval, res); if (res) { free(set_layout_bindings); diff --git a/examples/vk-shadertoy/vulkan/vk_error_print.cc b/examples/vk-shadertoy/vulkan/vk_error_print.cc index 19ded8c..c7cba6f 100644 --- a/examples/vk-shadertoy/vulkan/vk_error_print.cc +++ b/examples/vk-shadertoy/vulkan/vk_error_print.cc @@ -21,176 +21,189 @@ * DEALINGS IN THE SOFTWARE. */ -// Danil, 2021+ Vulkan shader launcher, self https://github.com/danilw/vulkan-shadertoy-launcher -// The MIT License +// Danil, 2021+ Vulkan shader launcher, self +// https://github.com/danilw/vulkan-shadertoy-launcher The MIT License #include "vk_error_print.h" -void vk_error_data_set_vkresult(struct vk_error_data *error, VkResult vkresult, const char *file, unsigned int line) { - if (vkresult == 0) - return; - - if (error->type != VK_ERROR_SUCCESS && !(error->type == VK_ERROR_VKRESULT_WARNING && vkresult < 0)) - return; - - *error = (struct vk_error_data) { - .type = vkresult < 0 ? VK_ERROR_VKRESULT : VK_ERROR_VKRESULT_WARNING, - .vkresult = vkresult, - .file = file, - .line = line, - }; +void vk_error_data_set_vkresult(struct vk_error_data* error, + VkResult vkresult, + const char* file, + unsigned int line) { + if (vkresult == 0) + return; + + if (error->type != VK_ERROR_SUCCESS && + !(error->type == VK_ERROR_VKRESULT_WARNING && vkresult < 0)) + return; + + *error = (struct vk_error_data){ + .type = vkresult < 0 ? VK_ERROR_VKRESULT : VK_ERROR_VKRESULT_WARNING, + .vkresult = vkresult, + .file = file, + .line = line, + }; } -void vk_error_data_set_errno(struct vk_error_data *error, int err_no, const char *file, unsigned int line) { - if (err_no == 0) - return; - - if (error->type != VK_ERROR_SUCCESS && error->type != VK_ERROR_VKRESULT_WARNING) - return; - - *error = (struct vk_error_data) { - .type = VK_ERROR_ERRNO, - .err_no = err_no, - .file = file, - .line = line, - }; +void vk_error_data_set_errno(struct vk_error_data* error, + int err_no, + const char* file, + unsigned int line) { + if (err_no == 0) + return; + + if (error->type != VK_ERROR_SUCCESS && + error->type != VK_ERROR_VKRESULT_WARNING) + return; + + *error = (struct vk_error_data){ + .type = VK_ERROR_ERRNO, + .err_no = err_no, + .file = file, + .line = line, + }; } -bool vk_error_data_merge(struct vk_error_data *error, struct vk_error_data *other) { - if (other->type == VK_ERROR_SUCCESS) - return false; +bool vk_error_data_merge(struct vk_error_data* error, + struct vk_error_data* other) { + if (other->type == VK_ERROR_SUCCESS) + return false; - if (error->type != VK_ERROR_SUCCESS && !(error->type == VK_ERROR_VKRESULT_WARNING && - (other->type == VK_ERROR_VKRESULT || other->type == VK_ERROR_ERRNO))) - return false; + if (error->type != VK_ERROR_SUCCESS && + !(error->type == VK_ERROR_VKRESULT_WARNING && + (other->type == VK_ERROR_VKRESULT || other->type == VK_ERROR_ERRNO))) + return false; - *error = *other; - return true; + *error = *other; + return true; } -bool vk_error_is_success(struct vk_error *error) { - return error->error.type == VK_ERROR_SUCCESS; +bool vk_error_is_success(struct vk_error* error) { + return error->error.type == VK_ERROR_SUCCESS; } -bool vk_error_is_warning(struct vk_error *error) { - return error->error.type == VK_ERROR_VKRESULT_WARNING; +bool vk_error_is_warning(struct vk_error* error) { + return error->error.type == VK_ERROR_VKRESULT_WARNING; } -bool vk_error_is_error(struct vk_error *error) { - return !vk_error_is_success(error) && !vk_error_is_warning(error); +bool vk_error_is_error(struct vk_error* error) { + return !vk_error_is_success(error) && !vk_error_is_warning(error); } -static const char *VkResult_string(VkResult res) { - switch (res) { - case VK_SUCCESS: - return "Success"; - case VK_NOT_READY: - return "Not ready"; - case VK_TIMEOUT: - return "Timeout"; - case VK_EVENT_SET: - return "Event set"; - case VK_EVENT_RESET: - return "Event reset"; - case VK_INCOMPLETE: - return "Incomplete"; - case VK_ERROR_OUT_OF_HOST_MEMORY: - return "Out of host memory"; - case VK_ERROR_OUT_OF_DEVICE_MEMORY: - return "Out of device memory"; - case VK_ERROR_INITIALIZATION_FAILED: - return "Initialization failed"; - case VK_ERROR_DEVICE_LOST: - return "Device lost"; - case VK_ERROR_MEMORY_MAP_FAILED: - return "Memory map failed"; - case VK_ERROR_LAYER_NOT_PRESENT: - return "Layer not present"; - case VK_ERROR_EXTENSION_NOT_PRESENT: - return "Extension not present"; - case VK_ERROR_FEATURE_NOT_PRESENT: - return "Feature not present"; - case VK_ERROR_INCOMPATIBLE_DRIVER: - return "Incompatible driver"; - case VK_ERROR_TOO_MANY_OBJECTS: - return "Too many objects"; - case VK_ERROR_FORMAT_NOT_SUPPORTED: - return "Format not supported"; - case VK_ERROR_SURFACE_LOST_KHR: - return "Surface lost"; - case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR: - return "Native window is in use"; - case VK_SUBOPTIMAL_KHR: - return "Suboptimal"; - case VK_ERROR_OUT_OF_DATE_KHR: - return "Surface is out of date"; - case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR: - return "Incompatible display"; - case VK_ERROR_VALIDATION_FAILED_EXT: - return "Validation failed"; - default: - return "Unrecognized error"; - } +static const char* VkResult_string(VkResult res) { + switch (res) { + case VK_SUCCESS: + return "Success"; + case VK_NOT_READY: + return "Not ready"; + case VK_TIMEOUT: + return "Timeout"; + case VK_EVENT_SET: + return "Event set"; + case VK_EVENT_RESET: + return "Event reset"; + case VK_INCOMPLETE: + return "Incomplete"; + case VK_ERROR_OUT_OF_HOST_MEMORY: + return "Out of host memory"; + case VK_ERROR_OUT_OF_DEVICE_MEMORY: + return "Out of device memory"; + case VK_ERROR_INITIALIZATION_FAILED: + return "Initialization failed"; + case VK_ERROR_DEVICE_LOST: + return "Device lost"; + case VK_ERROR_MEMORY_MAP_FAILED: + return "Memory map failed"; + case VK_ERROR_LAYER_NOT_PRESENT: + return "Layer not present"; + case VK_ERROR_EXTENSION_NOT_PRESENT: + return "Extension not present"; + case VK_ERROR_FEATURE_NOT_PRESENT: + return "Feature not present"; + case VK_ERROR_INCOMPATIBLE_DRIVER: + return "Incompatible driver"; + case VK_ERROR_TOO_MANY_OBJECTS: + return "Too many objects"; + case VK_ERROR_FORMAT_NOT_SUPPORTED: + return "Format not supported"; + case VK_ERROR_SURFACE_LOST_KHR: + return "Surface lost"; + case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR: + return "Native window is in use"; + case VK_SUBOPTIMAL_KHR: + return "Suboptimal"; + case VK_ERROR_OUT_OF_DATE_KHR: + return "Surface is out of date"; + case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR: + return "Incompatible display"; + case VK_ERROR_VALIDATION_FAILED_EXT: + return "Validation failed"; + default: + return "Unrecognized error"; + } } #if defined(VK_USE_PLATFORM_WIN32_KHR) -void win_error(char *iout, char *iout2){ - int msgboxID = MessageBox( - NULL, - (LPCSTR)iout, - (LPCSTR)iout2, - MB_ICONHAND | MB_DEFBUTTON1 - ); +void win_error(char* iout, char* iout2) { + int msgboxID = MessageBox(NULL, (LPCSTR)iout, (LPCSTR)iout2, + MB_ICONHAND | MB_DEFBUTTON1); } #endif -void print_error(FILE *fout, struct vk_error_data *error_data, const char *prefix) { - fprintf(fout, "%s:%u: %s", error_data->file, error_data->line, prefix); - switch (error_data->type) { - case VK_ERROR_VKRESULT_WARNING: - case VK_ERROR_VKRESULT: - fprintf(fout, "%s (VkResult %d)\n", VkResult_string(error_data->vkresult), error_data->vkresult); - break; - case VK_ERROR_ERRNO: - fprintf(fout, "%s (errno %d)\n", std::strerror(error_data->err_no), error_data->err_no); - break; - default: - fprintf(fout, "\n"); - break; - } +void print_error(FILE* fout, + struct vk_error_data* error_data, + const char* prefix) { + fprintf(fout, "%s:%u: %s", error_data->file, error_data->line, prefix); + switch (error_data->type) { + case VK_ERROR_VKRESULT_WARNING: + case VK_ERROR_VKRESULT: + fprintf(fout, "%s (VkResult %d)\n", VkResult_string(error_data->vkresult), + error_data->vkresult); + break; + case VK_ERROR_ERRNO: + fprintf(fout, "%s (errno %d)\n", std::strerror(error_data->err_no), + error_data->err_no); + break; + default: + fprintf(fout, "\n"); + break; + } } -void vk_error_fprintf(FILE *fout, struct vk_error *error, const char *fmt, ...) { - if (error->error.type == VK_ERROR_SUCCESS) - return; - - va_list args; - va_start(args, fmt); - vfprintf(fout, fmt, args); - va_end(args); - - print_error(fout, &error->error, ""); - if (error->sub_error.type != VK_ERROR_SUCCESS) { - print_error(fout, &error->sub_error, " Resulting from this error: "); - } +void vk_error_fprintf(FILE* fout, + struct vk_error* error, + const char* fmt, + ...) { + if (error->error.type == VK_ERROR_SUCCESS) + return; + + va_list args; + va_start(args, fmt); + vfprintf(fout, fmt, args); + va_end(args); + + print_error(fout, &error->error, ""); + if (error->sub_error.type != VK_ERROR_SUCCESS) { + print_error(fout, &error->sub_error, " Resulting from this error: "); + } } - -/* The following functions get a readable string out of the Vulkan standard enums */ -const char *vk_VkPhysicalDeviceType_string(VkPhysicalDeviceType type) { - switch (type) { - case VK_PHYSICAL_DEVICE_TYPE_OTHER: - return "Neither GPU nor CPU"; - case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: - return "Integrated GPU"; - case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: - return "Discrete GPU"; - case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: - return "Virtual GPU"; - case VK_PHYSICAL_DEVICE_TYPE_CPU: - return "CPU"; - default: - return "Unrecognized device type"; - } +/* The following functions get a readable string out of the Vulkan standard + * enums */ +const char* vk_VkPhysicalDeviceType_string(VkPhysicalDeviceType type) { + switch (type) { + case VK_PHYSICAL_DEVICE_TYPE_OTHER: + return "Neither GPU nor CPU"; + case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: + return "Integrated GPU"; + case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: + return "Discrete GPU"; + case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: + return "Virtual GPU"; + case VK_PHYSICAL_DEVICE_TYPE_CPU: + return "CPU"; + default: + return "Unrecognized device type"; + } } diff --git a/examples/vk-shadertoy/vulkan/vk_error_print.h b/examples/vk-shadertoy/vulkan/vk_error_print.h index e88b2ef..3d0e3f5 100644 --- a/examples/vk-shadertoy/vulkan/vk_error_print.h +++ b/examples/vk-shadertoy/vulkan/vk_error_print.h @@ -21,16 +21,16 @@ * DEALINGS IN THE SOFTWARE. */ -// Danil, 2021+ Vulkan shader launcher, self https://github.com/danilw/vulkan-shadertoy-launcher -// The MIT License +// Danil, 2021+ Vulkan shader launcher, self +// https://github.com/danilw/vulkan-shadertoy-launcher The MIT License #ifndef EXAMPLES_VK_SHADERTOY_VULKAN_VK_ERROR_PRINT_H_ #define EXAMPLES_VK_SHADERTOY_VULKAN_VK_ERROR_PRINT_H_ +#include +#include #include #include -#include -#include #define VULKAN_HPP_NO_EXCEPTIONS 1 #define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1 @@ -44,55 +44,75 @@ #endif enum vk_error_type { - VK_ERROR_SUCCESS = 0, - VK_ERROR_VKRESULT, - VK_ERROR_VKRESULT_WARNING, - VK_ERROR_ERRNO, + VK_ERROR_SUCCESS = 0, + VK_ERROR_VKRESULT, + VK_ERROR_VKRESULT_WARNING, + VK_ERROR_ERRNO, }; typedef struct vk_error_data { - vk_error_type type; - union { - VkResult vkresult; - int err_no; - }; - const char *file; - unsigned int line; + vk_error_type type; + union { + VkResult vkresult; + int err_no; + }; + const char* file; + unsigned int line; } vk_error_data; typedef struct vk_error { - struct vk_error_data error; - struct vk_error_data sub_error; /* - * Used in cases where error is e.g. "VK_INCOMPLETE", and it is due to - * another error. - */ + struct vk_error_data error; + struct vk_error_data + sub_error; /* + * Used in cases where error is e.g. "VK_INCOMPLETE", and it is + * due to another error. + */ } vk_error; -#define VK_ERROR_NONE (struct vk_error){ .error = { .type = VK_ERROR_SUCCESS,}, .sub_error = { .type = VK_ERROR_SUCCESS,}, } - -#define vk_error_set_vkresult(es, e) vk_error_data_set_vkresult(&(es)->error, (e), __FILE__, __LINE__) -#define vk_error_set_errno(es, e) vk_error_data_set_errno (&(es)->error, (e), __FILE__, __LINE__) -#define vk_error_sub_set_vkresult(es, e) vk_error_data_set_vkresult(&(es)->sub_error, (e), __FILE__, __LINE__) -#define vk_error_sub_merge(es, os) vk_error_data_merge(&(es)->sub_error, &(os)->error) - -void vk_error_data_set_vkresult(struct vk_error_data *error, VkResult vkresult, const char *file, unsigned int line); - -void vk_error_data_set_errno(struct vk_error_data *error, int err_no, const char *file, unsigned int line); - -bool vk_error_data_merge(struct vk_error_data *error, struct vk_error_data *other); - -bool vk_error_is_success(struct vk_error *error); - -bool vk_error_is_warning(struct vk_error *error); - -bool vk_error_is_error(struct vk_error *error); +#define VK_ERROR_NONE \ + (struct vk_error) { \ + .error = \ + { \ + .type = VK_ERROR_SUCCESS, \ + }, \ + .sub_error = { \ + .type = VK_ERROR_SUCCESS, \ + }, \ + } + +#define vk_error_set_vkresult(es, e) \ + vk_error_data_set_vkresult(&(es)->error, (e), __FILE__, __LINE__) +#define vk_error_set_errno(es, e) \ + vk_error_data_set_errno(&(es)->error, (e), __FILE__, __LINE__) +#define vk_error_sub_set_vkresult(es, e) \ + vk_error_data_set_vkresult(&(es)->sub_error, (e), __FILE__, __LINE__) +#define vk_error_sub_merge(es, os) \ + vk_error_data_merge(&(es)->sub_error, &(os)->error) + +void vk_error_data_set_vkresult(struct vk_error_data* error, + VkResult vkresult, + const char* file, + unsigned int line); + +void vk_error_data_set_errno(struct vk_error_data* error, + int err_no, + const char* file, + unsigned int line); + +bool vk_error_data_merge(struct vk_error_data* error, + struct vk_error_data* other); + +bool vk_error_is_success(struct vk_error* error); + +bool vk_error_is_warning(struct vk_error* error); + +bool vk_error_is_error(struct vk_error* error); #define vk_error_printf(es, ...) vk_error_fprintf(stdout, (es), __VA_ARGS__) -void vk_error_fprintf(FILE *fout, struct vk_error *error, const char *fmt, ...) ATTR_UNUSED; - - -const char *vk_VkPhysicalDeviceType_string(VkPhysicalDeviceType type); +void vk_error_fprintf(FILE* fout, struct vk_error* error, const char* fmt, ...) + ATTR_UNUSED; +const char* vk_VkPhysicalDeviceType_string(VkPhysicalDeviceType type); -#endif // EXAMPLES_VK_SHADERTOY_VULKAN_VK_ERROR_PRINT_H_ +#endif // EXAMPLES_VK_SHADERTOY_VULKAN_VK_ERROR_PRINT_H_ diff --git a/examples/vk-shadertoy/vulkan/vk_struct.h b/examples/vk-shadertoy/vulkan/vk_struct.h index 684d0da..9eea59b 100644 --- a/examples/vk-shadertoy/vulkan/vk_struct.h +++ b/examples/vk-shadertoy/vulkan/vk_struct.h @@ -21,8 +21,8 @@ * DEALINGS IN THE SOFTWARE. */ -// Danil, 2021+ Vulkan shader launcher, self https://github.com/danilw/vulkan-shadertoy-launcher -// The MIT License +// Danil, 2021+ Vulkan shader launcher, self +// https://github.com/danilw/vulkan-shadertoy-launcher The MIT License #ifndef EXAMPLES_VK_SHADERTOY_VULKAN_VK_STRUCT_H_ #define EXAMPLES_VK_SHADERTOY_VULKAN_VK_STRUCT_H_ @@ -32,8 +32,9 @@ static constexpr uint32_t kMaxPresentModes = UINT32_C(4); static constexpr uint32_t kAppNameStrLen = UINT32_C(80); // numbers buffers <*.frag> files -// number of buffers to create, any number(>0), if you need 0 use https://github.com/danilw/vulkan-shader-launcher -// names shaders/spv/.spv look files names in that folder +// number of buffers to create, any number(>0), if you need 0 use +// https://github.com/danilw/vulkan-shader-launcher names shaders/spv/.spv +// look files names in that folder static constexpr uint32_t OFFSCREEN_BUFFERS = UINT32_C(4); // number of images(>0) @@ -46,252 +47,253 @@ static constexpr bool USE_MIPMAPS = true; // do not edit, it just to see where keyboard texture used static constexpr uint32_t iKeyboard = UINT32_C(1); - struct vk_physical_device { - VkPhysicalDevice physical_device; - VkPhysicalDeviceProperties properties; - VkPhysicalDeviceFeatures features; - VkPhysicalDeviceMemoryProperties memories; - VkQueueFamilyProperties queue_families[kMaxQueueFamily]; - uint32_t queue_family_count; - bool queue_families_incomplete; + VkPhysicalDevice physical_device; + VkPhysicalDeviceProperties properties; + VkPhysicalDeviceFeatures features; + VkPhysicalDeviceMemoryProperties memories; + VkQueueFamilyProperties queue_families[kMaxQueueFamily]; + uint32_t queue_family_count; + bool queue_families_incomplete; }; struct vk_commands { - VkQueueFlags qflags; + VkQueueFlags qflags; - VkCommandPool pool; - VkQueue *queues; - uint32_t queue_count; - VkCommandBuffer *buffers; - uint32_t buffer_count; + VkCommandPool pool; + VkQueue* queues; + uint32_t queue_count; + VkCommandBuffer* buffers; + uint32_t buffer_count; }; struct vk_device { - VkDevice device; - struct vk_commands *command_pools; - uint32_t command_pool_count; + VkDevice device; + struct vk_commands* command_pools; + uint32_t command_pool_count; }; struct vk_swapchain { - VkSurfaceKHR surface; - VkSwapchainKHR swapchain; - VkSurfaceFormatKHR surface_format; - VkSurfaceCapabilitiesKHR surface_caps; - VkPresentModeKHR present_modes[kMaxPresentModes]; - uint32_t present_modes_count; + VkSurfaceKHR surface; + VkSwapchainKHR swapchain; + VkSurfaceFormatKHR surface_format; + VkSurfaceCapabilitiesKHR surface_caps; + VkPresentModeKHR present_modes[kMaxPresentModes]; + uint32_t present_modes_count; }; struct vk_image { - VkFormat format; - VkExtent2D extent; - VkImageUsageFlagBits usage; - VkShaderStageFlagBits stage; - bool make_view; - bool will_be_initialized; - bool host_visible; - bool multisample; - uint32_t *sharing_queues; - uint32_t sharing_queue_count; - VkImage image; - VkDeviceMemory image_mem; - VkImageView view; - VkSampler sampler; - bool anisotropyEnable; - VkSamplerAddressMode repeat_mode; - bool mipmaps; - bool linear; + VkFormat format; + VkExtent2D extent; + VkImageUsageFlagBits usage; + VkShaderStageFlagBits stage; + bool make_view; + bool will_be_initialized; + bool host_visible; + bool multisample; + uint32_t* sharing_queues; + uint32_t sharing_queue_count; + VkImage image; + VkDeviceMemory image_mem; + VkImageView view; + VkSampler sampler; + bool anisotropyEnable; + VkSamplerAddressMode repeat_mode; + bool mipmaps; + bool linear; }; struct vk_buffer { - VkFormat format; - uint32_t size; - VkBufferUsageFlagBits usage; - VkShaderStageFlagBits stage; - bool make_view; - bool host_visible; - uint32_t *sharing_queues; - uint32_t sharing_queue_count; - VkBuffer buffer; - VkDeviceMemory buffer_mem; - VkBufferView view; + VkFormat format; + uint32_t size; + VkBufferUsageFlagBits usage; + VkShaderStageFlagBits stage; + bool make_view; + bool host_visible; + uint32_t* sharing_queues; + uint32_t sharing_queue_count; + VkBuffer buffer; + VkDeviceMemory buffer_mem; + VkBufferView view; }; struct vk_shader { - const char *spirv_file; - VkShaderStageFlagBits stage; - VkShaderModule shader; + const char* spirv_file; + VkShaderStageFlagBits stage; + VkShaderModule shader; }; struct vk_graphics_buffers { - VkExtent2D surface_size; - VkImage swapchain_image; - VkImageView color_view; - struct vk_image depth; - VkFramebuffer framebuffer; + VkExtent2D surface_size; + VkImage swapchain_image; + VkImageView color_view; + struct vk_image depth; + VkFramebuffer framebuffer; }; struct vk_render_essentials { - VkImage *images; - uint32_t image_count; - VkQueue present_queue; - VkCommandBuffer cmd_buffer; + VkImage* images; + uint32_t image_count; + VkQueue present_queue; + VkCommandBuffer cmd_buffer; - VkSemaphore sem_post_acquire; - VkSemaphore sem_pre_submit; + VkSemaphore sem_post_acquire; + VkSemaphore sem_pre_submit; - VkFence exec_fence; - bool first_render; + VkFence exec_fence; + bool first_render; }; struct vk_resources { - struct vk_image *images; - uint32_t image_count; - struct vk_buffer *buffers; - uint32_t buffer_count; - struct vk_shader *shaders; - uint32_t shader_count; - VkPushConstantRange *push_constants; - uint32_t push_constant_count; - VkRenderPass render_pass; + struct vk_image* images; + uint32_t image_count; + struct vk_buffer* buffers; + uint32_t buffer_count; + struct vk_shader* shaders; + uint32_t shader_count; + VkPushConstantRange* push_constants; + uint32_t push_constant_count; + VkRenderPass render_pass; }; struct vk_layout { - struct vk_resources *resources; - VkDescriptorSetLayout set_layout; - VkPipelineLayout pipeline_layout; + struct vk_resources* resources; + VkDescriptorSetLayout set_layout; + VkPipelineLayout pipeline_layout; }; struct vk_pipeline { - struct vk_layout *layout; - VkPipelineVertexInputStateCreateInfo vertex_input_state; - VkPipelineInputAssemblyStateCreateInfo input_assembly_state; - VkPipelineTessellationStateCreateInfo tessellation_state; - uint32_t thread_count; - VkPipeline pipeline; - VkDescriptorPool set_pool; + struct vk_layout* layout; + VkPipelineVertexInputStateCreateInfo vertex_input_state; + VkPipelineInputAssemblyStateCreateInfo input_assembly_state; + VkPipelineTessellationStateCreateInfo tessellation_state; + uint32_t thread_count; + VkPipeline pipeline; + VkDescriptorPool set_pool; }; enum vk_render_pass_load_op { - VK_C_CLEAR = 0, - VK_KEEP = 1, + VK_C_CLEAR = 0, + VK_KEEP = 1, }; enum vk_make_depth_buffer { - VK_WITHOUT_DEPTH = 0, - VK_WITH_DEPTH = 1, + VK_WITHOUT_DEPTH = 0, + VK_WITH_DEPTH = 1, }; struct vk_offscreen_buffers { - VkExtent2D surface_size; - struct vk_image color; - struct vk_image depth; - VkFramebuffer framebuffer; + VkExtent2D surface_size; + struct vk_image color; + struct vk_image depth; + VkFramebuffer framebuffer; }; - struct app_data_struct { - int iResolution[2]; //resolution - double iMouse[2]; //mouse in window, it always updated (not like iMouse on shadertoy) - int iMouse_lclick[2]; //mouse left click pos (its -[last pos] when left mosue not clicked) - int iMouse_rclick[2]; //mouse right click pos (its -[last pos] when right mosue not clicked) - bool iMouse_click[2]; //is mouse button clicked(left/right) - float iTime; //time - float iTimeDelta; //time delta - int iFrame; //frames - - bool pause; //pause clicked - bool quit; //quit clicked/happend - bool drawdebug; //draw debug info, key press + int iResolution[2]; // resolution + double iMouse[2]; // mouse in window, it always updated (not like iMouse on + // shadertoy) + int iMouse_lclick[2]; // mouse left click pos (its -[last pos] when left + // mosue not clicked) + int iMouse_rclick[2]; // mouse right click pos (its -[last pos] when right + // mosue not clicked) + bool iMouse_click[2]; // is mouse button clicked(left/right) + float iTime; // time + float iTimeDelta; // time delta + int iFrame; // frames + + bool pause; // pause clicked + bool quit; // quit clicked/happend + bool drawdebug; // draw debug info, key press }; struct app_os_window { #if defined(VK_USE_PLATFORM_WIN32_KHR) - HINSTANCE connection; - HWND window; - POINT minsize; + HINSTANCE connection; + HWND window; + POINT minsize; #elif defined(VK_USE_PLATFORM_XCB_KHR) - Display *display; - xcb_connection_t *connection; - xcb_screen_t *screen; - xcb_window_t xcb_window; - xcb_intern_atom_reply_t *atom_wm_delete_window; + Display* display; + xcb_connection_t* connection; + xcb_screen_t* screen; + xcb_window_t xcb_window; + xcb_intern_atom_reply_t* atom_wm_delete_window; #elif defined(VK_USE_PLATFORM_WAYLAND_KHR) - struct wl_display *wl_display; - struct wl_registry *registry; - struct wl_compositor *compositor; - struct wl_surface *wl_surface; - struct xdg_wm_base *shell; - struct wl_seat *seat; - struct wl_pointer *pointer; - struct wl_keyboard *keyboard; - struct xdg_surface *xdg_surface; - struct xdg_toplevel *xdg_toplevel; - bool configured; + struct wl_display* wl_display; + struct wl_registry* registry; + struct wl_compositor* compositor; + struct wl_surface* wl_surface; + struct xdg_wm_base* shell; + struct wl_seat* seat; + struct wl_pointer* pointer; + struct wl_keyboard* keyboard; + struct xdg_surface* xdg_surface; + struct xdg_toplevel* xdg_toplevel; + bool configured; #endif - char name[kAppNameStrLen]; + char name[kAppNameStrLen]; - bool prepared; // is vk setup prepared - bool is_minimized; //window controled events - bool resize_event; //window controled events - bool fps_lock; //key pressed event - bool reload_shaders_on_resize; //launch option - bool enable_debug; //launch option + bool prepared; // is vk setup prepared + bool is_minimized; // window controled events + bool resize_event; // window controled events + bool fps_lock; // key pressed event + bool reload_shaders_on_resize; // launch option + bool enable_debug; // launch option - bool pause_refresh; //used only in Windows, on pause when key pressed refresh + bool pause_refresh; // used only in Windows, on pause when key pressed + // refresh - VkPresentModeKHR present_mode; - struct app_data_struct app_data; + VkPresentModeKHR present_mode; + struct app_data_struct app_data; }; struct shaders_push_constants { - float iMouse[4]; - float iDate[4]; - int iMouse_lr[2]; - float iResolution[2]; - int debugdraw; // look function check_hotkeys - int pCustom; //custom data - float iTime; - float iTimeDelta; - int iFrame; + float iMouse[4]; + float iDate[4]; + int iMouse_lr[2]; + float iResolution[2]; + int debugdraw; // look function check_hotkeys + int pCustom; // custom data + float iTime; + float iTimeDelta; + int iFrame; }; enum { - BUFFER_VERTICES = 0, - BUFFER_INDICES = 1, + BUFFER_VERTICES = 0, + BUFFER_INDICES = 1, }; enum { - SHADER_MAIN_VERTEX = 0, - SHADER_MAIN_FRAGMENT = 1, + SHADER_MAIN_VERTEX = 0, + SHADER_MAIN_FRAGMENT = 1, }; struct render_data { - struct objects { - struct vertex { - float pos[3]; - } vertices[3]; - - uint16_t indices[3]; - } objects; - - struct shaders_push_constants push_constants; - - struct vk_image images[IMAGE_TEXTURES + OFFSCREEN_BUFFERS + iKeyboard]; - struct vk_buffer buffers[2]; - struct vk_shader shaders[2 + OFFSCREEN_BUFFERS * 2]; - struct vk_graphics_buffers *main_gbuffers; - struct vk_offscreen_buffers *buf_obuffers; - - VkRenderPass buf_render_pass[OFFSCREEN_BUFFERS]; - struct vk_layout buf_layout[OFFSCREEN_BUFFERS]; - struct vk_pipeline buf_pipeline[OFFSCREEN_BUFFERS]; - VkDescriptorSet buf_desc_set[OFFSCREEN_BUFFERS]; - - VkRenderPass main_render_pass; - struct vk_layout main_layout; - struct vk_pipeline main_pipeline; - VkDescriptorSet main_desc_set; + struct objects { + struct vertex { + float pos[3]; + } vertices[3]; + + uint16_t indices[3]; + } objects; + + struct shaders_push_constants push_constants; + + struct vk_image images[IMAGE_TEXTURES + OFFSCREEN_BUFFERS + iKeyboard]; + struct vk_buffer buffers[2]; + struct vk_shader shaders[2 + OFFSCREEN_BUFFERS * 2]; + struct vk_graphics_buffers* main_gbuffers; + struct vk_offscreen_buffers* buf_obuffers; + + VkRenderPass buf_render_pass[OFFSCREEN_BUFFERS]; + struct vk_layout buf_layout[OFFSCREEN_BUFFERS]; + struct vk_pipeline buf_pipeline[OFFSCREEN_BUFFERS]; + VkDescriptorSet buf_desc_set[OFFSCREEN_BUFFERS]; + + VkRenderPass main_render_pass; + struct vk_layout main_layout; + struct vk_pipeline main_pipeline; + VkDescriptorSet main_desc_set; }; - -#endif // EXAMPLES_VK_SHADERTOY_VULKAN_VK_STRUCT_H_ +#endif // EXAMPLES_VK_SHADERTOY_VULKAN_VK_STRUCT_H_ diff --git a/include/waypp/logging/logging.h b/include/waypp/logging/logging.h index 862b3b1..f539d98 100644 --- a/include/waypp/logging/logging.h +++ b/include/waypp/logging/logging.h @@ -29,7 +29,6 @@ #include #include -#include #define DLOG_DEBUG SPDLOG_DEBUG #define DLOG_TRACE SPDLOG_TRACE @@ -49,7 +48,7 @@ class Logging { Logging() { console_sink_ = std::make_shared(); logger_ = std::make_shared("waypp", console_sink_); - spdlog::set_default_logger(logger_); + set_default_logger(logger_); spdlog::set_pattern("[%H:%M:%S.%f] [%L] %v"); spdlog::flush_on(spdlog::level::err); diff --git a/include/waypp/seat/keyboard.h b/include/waypp/seat/keyboard.h index 9b7b7ba..bc292a1 100644 --- a/include/waypp/seat/keyboard.h +++ b/include/waypp/seat/keyboard.h @@ -96,7 +96,7 @@ class Keyboard { [[nodiscard]] int32_t get_repeat_rate() const { return repeat_.rate; } - void set_event_mask(event_mask& event_mask); + void set_event_mask(const event_mask& event_mask); // Disallow copy and assign. Keyboard(const Keyboard&) = delete; diff --git a/include/waypp/seat/pointer.h b/include/waypp/seat/pointer.h index 278e90e..5912139 100644 --- a/include/waypp/seat/pointer.h +++ b/include/waypp/seat/pointer.h @@ -17,7 +17,6 @@ #pragma once #include -#include #include #include @@ -94,7 +93,7 @@ class Pointer { wl_compositor* wl_compositor, wl_shm* wl_shm, bool disable_cursor, - event_mask& event_mask, + const event_mask& event_mask, int size = 24); ~Pointer(); @@ -126,7 +125,7 @@ class Pointer { [[nodiscard]] bool is_cursor_enabled() const { return !disable_cursor_; } - void set_event_mask(event_mask& event_mask); + void set_event_mask(const event_mask& event_mask); [[nodiscard]] std::pair get_xy() const { return {sx_, sy_}; } @@ -212,5 +211,7 @@ class Pointer { .axis_source = handle_axis_source, .axis_stop = handle_axis_stop, .axis_discrete = handle_axis_discrete, + .axis_value120 = nullptr, + .axis_relative_direction = nullptr, }; }; diff --git a/include/waypp/seat/touch.h b/include/waypp/seat/touch.h index 18fe692..b13e838 100644 --- a/include/waypp/seat/touch.h +++ b/include/waypp/seat/touch.h @@ -118,5 +118,7 @@ class Touch { .motion = handle_motion, .frame = handle_frame, .cancel = handle_cancel, + .shape = nullptr, + .orientation = nullptr, }; }; diff --git a/include/waypp/window/window.h b/include/waypp/window/window.h index 3601a19..6169de2 100644 --- a/include/waypp/window/window.h +++ b/include/waypp/window/window.h @@ -155,7 +155,7 @@ class Window { void swap_buffers_with_damage(EGLint* rects, EGLint n_rects) const; - Buffer* pick_free_buffer() const; + [[nodiscard]] Buffer* pick_free_buffer() const; [[nodiscard]] size_t get_num_buffers() const { return buffers_.size(); } diff --git a/include/waypp/window/xdg_toplevel.h b/include/waypp/window/xdg_toplevel.h index e4e718d..883053c 100644 --- a/include/waypp/window/xdg_toplevel.h +++ b/include/waypp/window/xdg_toplevel.h @@ -54,17 +54,19 @@ class XdgTopLevel : public Window { [[nodiscard]] const std::string& get_app_id() const { return app_id_; } - void set_app_id(const char* app_id) { + void set_app_id(const char* app_id) const { xdg_toplevel_set_app_id(xdg_toplevel_, app_id); } [[nodiscard]] const std::string& get_title() const { return title_; } - void set_title(const char* title) { + void set_title(const char* title) const { xdg_toplevel_set_title(xdg_toplevel_, title); } - void set_fullscreen() { xdg_toplevel_set_fullscreen(xdg_toplevel_, nullptr); } + void set_fullscreen() const { + xdg_toplevel_set_fullscreen(xdg_toplevel_, nullptr); + } void set_maximize() const { xdg_toplevel_set_maximized(xdg_toplevel_); } @@ -87,7 +89,7 @@ class XdgTopLevel : public Window { wl_surface_damage(get_surface(), x, y, width, height); } - xdg_toplevel_resize_edge check_edge_resize( + [[nodiscard]] xdg_toplevel_resize_edge check_edge_resize( const std::pair& xy) const; [[nodiscard]] bool is_resizing() const { return get_resizing(); } diff --git a/include/waypp/window_manager/output.h b/include/waypp/window_manager/output.h index 0035084..c799618 100644 --- a/include/waypp/window_manager/output.h +++ b/include/waypp/window_manager/output.h @@ -18,7 +18,6 @@ #include #include -#include #include #include diff --git a/include/waypp/window_manager/window_manager.h b/include/waypp/window_manager/window_manager.h index e87903d..5edfe84 100644 --- a/include/waypp/window_manager/window_manager.h +++ b/include/waypp/window_manager/window_manager.h @@ -64,9 +64,10 @@ class WindowManager : public Registrar { observers_.remove(observer); } - wl_output* get_primary_output(); + [[nodiscard]] wl_output* get_primary_output() const; - wl_output* find_output_by_name(const std::string& output_name); + [[nodiscard]] wl_output* find_output_by_name( + const std::string& output_name) const; // Disallow copy and assign. WindowManager(const WindowManager&) = delete; diff --git a/src/seat/keyboard.cc b/src/seat/keyboard.cc index bfece89..9c29260 100644 --- a/src/seat/keyboard.cc +++ b/src/seat/keyboard.cc @@ -26,7 +26,7 @@ #include "logging/logging.h" // workaround for Wayland macro not compiling in C++ -#define WL_ARRAY_FOR_EACH(pos, array, type) \ +#define WL_ARRAY_FOR_EACH(pos, array, type) \ for ((pos) = (type)(array)->data; \ (const char*)(pos) < ((const char*)(array)->data + (array)->size); \ (pos)++) @@ -209,6 +209,7 @@ void Keyboard::handle_key(void* data, // update notify values obj->repeat_.notify = { + .wl_keyboard = wl_keyboard, .serial = serial, .time = time, .xkb_scancode = xkb_scancode, @@ -230,7 +231,7 @@ void Keyboard::handle_key(void* data, return; } - for (auto observer : obj->observers_) { + for (const auto observer : obj->observers_) { observer->notify_keyboard_xkb_v1_key(obj, wl_keyboard, serial, time, xkb_scancode, key_repeats, state, xdg_keysym_count, key_syms); @@ -278,7 +279,7 @@ void Keyboard::handle_repeat_info(void* data, obj->repeat_.sev.sigev_notify = SIGEV_SIGNAL; obj->repeat_.sev.sigev_signo = SIGRTMIN; obj->repeat_.sev.sigev_value.sival_ptr = data; - auto res = + const auto res = timer_create(CLOCK_REALTIME, &obj->repeat_.sev, &obj->repeat_.timer); if (res != 0) { LOG_CRITICAL("Error timer_create: {}", std::strerror(errno)); @@ -316,7 +317,7 @@ void Keyboard::repeat_xkb_v1_key_callback(int /* sig */, return; } - for (auto observer : obj->observers_) { + for (const auto observer : obj->observers_) { observer->notify_keyboard_xkb_v1_key( obj, obj->repeat_.notify.wl_keyboard, obj->repeat_.notify.serial, obj->repeat_.notify.time, obj->repeat_.notify.xkb_scancode, @@ -325,7 +326,7 @@ void Keyboard::repeat_xkb_v1_key_callback(int /* sig */, } } -void Keyboard::set_event_mask(event_mask& event_mask) { +void Keyboard::set_event_mask(const event_mask& event_mask) { event_mask_.enabled = event_mask.enabled; event_mask_.all = event_mask.all; } \ No newline at end of file diff --git a/src/seat/pointer.cc b/src/seat/pointer.cc index c19958b..f6f362a 100644 --- a/src/seat/pointer.cc +++ b/src/seat/pointer.cc @@ -33,9 +33,9 @@ Pointer::Pointer(wl_pointer* pointer, wl_compositor* wl_compositor, wl_shm* wl_shm, - bool disable_cursor, - event_mask& event_mask, - int size) + const bool disable_cursor, + const event_mask& event_mask, + const int size) : wl_pointer_(pointer), wl_shm_(wl_shm), disable_cursor_(disable_cursor), @@ -187,7 +187,7 @@ void Pointer::handle_motion(void* data, * @brief Function to handle button events from the pointer * * @param data A pointer to user-defined data - * @param wl_pointer The Wayland pointer object + * @param pointer The Wayland pointer object * @param serial The serial number of the event * @param button The button that triggered the event * @param state The state of the button (pressed or released) @@ -222,7 +222,7 @@ void Pointer::handle_button(void* data, * scroll event. * * @param data A pointer to user-defined data. - * @param wl_pointer A pointer to the wl_pointer object that triggered the + * @param pointer A pointer to the wl_pointer object that triggered the * event. * @param time The timestamp of the event. * @param axis The axis identifier. @@ -259,7 +259,7 @@ void Pointer::handle_axis(void* data, * This function is called when a frame event is received for the pointer. * * @param data The user data associated with the pointer. - * @param wl_pointer The pointer object. + * @param pointer The pointer object. */ void Pointer::handle_frame(void* data, wl_pointer* pointer) { const auto obj = static_cast(data); @@ -282,7 +282,7 @@ void Pointer::handle_frame(void* data, wl_pointer* pointer) { * @brief Handles the axis source event for the Pointer object. * * @param data Unused parameter. - * @param wl_pointer The wl_pointer object associated with the event. + * @param pointer The wl_pointer object associated with the event. * @param axis_source The axis source. * * This function is called when the axis source event is received for the @@ -314,7 +314,7 @@ void Pointer::handle_axis_source(void* data, * This function is called when an axis stop event is received for the pointer. * * @param data A pointer to user-defined data. - * @param wl_pointer The pointer object that triggered the event. + * @param pointer The pointer object that triggered the event. * @param time The timestamp of the event. * @param axis The axis that stopped. */ @@ -344,7 +344,7 @@ void Pointer::handle_axis_stop(void* data, * This function is called when a discrete axis event is received. * * @param data The user data associated with the Pointer. - * @param wl_pointer The pointer object. + * @param pointer The pointer object. * @param axis The axis value. * @param discrete The discrete value. */ @@ -423,7 +423,7 @@ std::string Pointer::get_cursor_theme() { }); } - return std::move(res); + return res; } std::vector Pointer::get_available_cursors( @@ -447,10 +447,10 @@ std::vector Pointer::get_available_cursors( std::sort(cursor_list.begin(), cursor_list.end()); - return std::move(cursor_list); + return cursor_list; } -void Pointer::set_event_mask(event_mask& event_mask) { +void Pointer::set_event_mask(const event_mask& event_mask) { event_mask_.enabled = event_mask.enabled; event_mask_.all = event_mask.all; event_mask_.axis = event_mask.axis; diff --git a/src/window_manager/window_manager.cc b/src/window_manager/window_manager.cc index 4efca64..604fa2a 100644 --- a/src/window_manager/window_manager.cc +++ b/src/window_manager/window_manager.cc @@ -76,7 +76,7 @@ WindowManager::~WindowManager() { * @return The number of events dispatched on success, or a negative error code * on failure. */ -[[maybe_unused]] int WindowManager::dispatch(int timeout) const { +[[maybe_unused]] int WindowManager::dispatch(const int timeout) const { pollfd fds[1]; int dispatch_count = 0; @@ -91,7 +91,11 @@ WindowManager::~WindowManager() { return -errno; } - fds[0] = (pollfd){wl_display_get_fd(wl_display_), POLLIN}; + fds[0] = { + wl_display_get_fd(wl_display_), + .events = POLLIN, + .revents = 0, + }; const int ret = poll(fds, std::size(fds), timeout); if (ret > 0) { @@ -99,17 +103,17 @@ WindowManager::~WindowManager() { wl_display_read_events(wl_display_); dispatch_count += wl_display_dispatch_pending(wl_display_); return dispatch_count; - } else { - wl_display_cancel_read(wl_display_); - return dispatch_count; } - } else if (ret == 0) { + wl_display_cancel_read(wl_display_); return dispatch_count; - } else { + } + if (ret == 0) { wl_display_cancel_read(wl_display_); - return -errno; + return dispatch_count; } + wl_display_cancel_read(wl_display_); + return -errno; } /** @@ -120,7 +124,7 @@ WindowManager::~WindowManager() { * handling events using Wayland protocol. */ int WindowManager::poll_events(int /* timeout */) const { - for (auto observer : observers_) { + for (const auto observer : observers_) { observer->notify_task(); } @@ -137,22 +141,20 @@ int WindowManager::display_dispatch() const { return wl_display_dispatch(wl_display_); } -wl_output* WindowManager::get_primary_output() { +wl_output* WindowManager::get_primary_output() const { auto& outputs = get_outputs(); if (get_xdg_output_manager()) { - for (auto& output : outputs) { - if (output.second->get_xdg_output()->is_origin()) { - LOG_DEBUG("get_primary_output: (xdg_output) Origin: {}", - fmt::ptr(output.first)); - return output.first; + for (const auto& [fst, snd] : outputs) { + if (snd->get_xdg_output()->is_origin()) { + LOG_DEBUG("get_primary_output: (xdg_output) Origin: {}", fmt::ptr(fst)); + return fst; } } } else { - for (auto& output : outputs) { - LOG_DEBUG("get_primary_output: (fist) Origin: {}", - fmt::ptr(output.first)); - return output.first; + for (const auto& [fst, snd] : outputs) { + LOG_DEBUG("get_primary_output: (fist) Origin: {}", fmt::ptr(fst)); + return fst; } } @@ -160,20 +162,21 @@ wl_output* WindowManager::get_primary_output() { return nullptr; } -wl_output* WindowManager::find_output_by_name(const std::string& output_name) { +wl_output* WindowManager::find_output_by_name( + const std::string& output_name) const { auto& outputs = get_outputs(); if (get_xdg_output_manager()) { - for (auto& output : outputs) { - if (output.second->get_name() == output_name) { + for (const auto& [fst, snd] : outputs) { + if (snd->get_name() == output_name) { LOG_DEBUG("find_output_by_name: (xdg_output): {}", output_name); - return output.first; + return fst; } } } else { - for (auto& output : outputs) { + for (const auto& [fst, snd] : outputs) { LOG_DEBUG("find_output_by_name: (fist): {}", output_name); - return output.first; + return fst; } } return nullptr;