From 291fa055453e2832423e6f82914131fa2c748abc Mon Sep 17 00:00:00 2001 From: Konstantin Seurer Date: Sun, 8 Jan 2023 16:46:13 +0100 Subject: [PATCH] vulkan/wsi/x11: Capture traces using a hotkey Reviewed-by: Samuel Pitoiset Part-of: --- src/vulkan/runtime/vk_device.h | 1 + src/vulkan/wsi/wsi_common.c | 4 +++- src/vulkan/wsi/wsi_common_x11.c | 53 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/src/vulkan/runtime/vk_device.h b/src/vulkan/runtime/vk_device.h index ecf4bab..c4e307e 100644 --- a/src/vulkan/runtime/vk_device.h +++ b/src/vulkan/runtime/vk_device.h @@ -140,6 +140,7 @@ struct vk_device { VkResult (*capture_trace)(VkQueue queue); uint32_t current_frame; + bool trace_hotkey_trigger; simple_mtx_t trace_mtx; /* For VK_EXT_private_data */ diff --git a/src/vulkan/wsi/wsi_common.c b/src/vulkan/wsi/wsi_common.c index 59ea230..7268625 100644 --- a/src/vulkan/wsi/wsi_common.c +++ b/src/vulkan/wsi/wsi_common.c @@ -1248,9 +1248,11 @@ handle_trace(VkQueue queue, struct vk_device *device) #endif VkResult result = VK_SUCCESS; - if (frame_trigger || file_trigger) + if (frame_trigger || file_trigger || device->trace_hotkey_trigger) result = device->capture_trace(queue); + device->trace_hotkey_trigger = false; + simple_mtx_unlock(&device->trace_mtx); return result; diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c index a423559..d64115e 100644 --- a/src/vulkan/wsi/wsi_common_x11.c +++ b/src/vulkan/wsi/wsi_common_x11.c @@ -23,7 +23,13 @@ #include #include +#define XK_MISCELLANY +#define XK_LATIN1 +#include #include +#ifdef XCB_KEYSYMS_AVAILABLE +#include +#endif #include #include #include @@ -50,6 +56,7 @@ #include "vk_format.h" #include "vk_instance.h" #include "vk_physical_device.h" +#include "vk_device.h" #include "vk_util.h" #include "vk_enum_to_str.h" #include "wsi_common_entrypoints.h" @@ -1022,6 +1029,7 @@ struct x11_swapchain { bool has_mit_shm; xcb_connection_t * conn; + xcb_connection_t * capture_conn; xcb_window_t window; xcb_gc_t gc; uint32_t depth; @@ -1680,6 +1688,29 @@ x11_present_to_x11_sw(struct x11_swapchain *chain, uint32_t image_index, return x11_swapchain_result(chain, VK_SUCCESS); } +static void +x11_capture_trace(struct x11_swapchain *chain) +{ + if (!chain->capture_conn) + return; + + xcb_generic_event_t *event; + while ((event = xcb_poll_for_event(chain->capture_conn))) { + if ((event->response_type & ~0x80) != XCB_KEY_PRESS) { + free(event); + continue; + } + + VK_FROM_HANDLE(vk_device, device, chain->base.device); + + simple_mtx_lock(&device->trace_mtx); + device->trace_hotkey_trigger = true; + simple_mtx_unlock(&device->trace_mtx); + + free(event); + } +} + /** * Send image to the X server for presentation at target_msc. */ @@ -1687,6 +1718,8 @@ static VkResult x11_present_to_x11(struct x11_swapchain *chain, uint32_t image_index, uint64_t target_msc) { + x11_capture_trace(chain); + VkResult result; if (chain->base.wsi->sw && !chain->has_mit_shm) result = x11_present_to_x11_sw(chain, image_index, target_msc); @@ -2318,6 +2351,8 @@ x11_swapchain_destroy(struct wsi_swapchain *anv_chain, XCB_PRESENT_EVENT_MASK_NO_EVENT); xcb_discard_reply(chain->conn, cookie.sequence); + xcb_disconnect(chain->capture_conn); + pthread_mutex_destroy(&chain->present_poll_mutex); pthread_mutex_destroy(&chain->present_progress_mutex); pthread_cond_destroy(&chain->present_progress_cond); @@ -2601,6 +2636,24 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, if (chain == NULL) return VK_ERROR_OUT_OF_HOST_MEMORY; +#ifdef XCB_KEYSYMS_AVAILABLE + VK_FROM_HANDLE(vk_device, vk_device, device); + if (vk_device->capture_trace) { + chain->capture_conn = xcb_connect(NULL, NULL); + assert(!xcb_connection_has_error(chain->capture_conn)); + + xcb_key_symbols_t *key_symbols = xcb_key_symbols_alloc(conn); + xcb_keycode_t *keycodes = xcb_key_symbols_get_keycode(key_symbols, XK_F12); + if (keycodes) { + xcb_grab_key(chain->capture_conn, 1, window, XCB_MOD_MASK_ANY, keycodes[0], + XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); + } + xcb_key_symbols_free(key_symbols); + + xcb_flush(chain->capture_conn); + } +#endif + int ret = pthread_mutex_init(&chain->present_progress_mutex, NULL); if (ret != 0) { vk_free(pAllocator, chain); -- 2.7.4