From 222b6629955b8a61daafc6218aa26e1a21a1b397 Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Mon, 4 Mar 2019 10:51:47 +1100 Subject: [PATCH] tools/trace: add initial interposed Vulkan tracing library --- CMakeLists.txt | 15 +++++++++++++++ tools/spec.py | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index b8dbfa6..7089093 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,7 @@ endif () ############################################################################### set (GENERATED_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/cruft/vk/") file (MAKE_DIRECTORY "${GENERATED_PREFIX}/load") +file (MAKE_DIRECTORY "${GENERATED_PREFIX}/tools") if (WIN32) @@ -33,6 +34,7 @@ OUTPUT "${GENERATED_PREFIX}/vk.hpp" "${GENERATED_PREFIX}/load/dispatch.cpp" "${GENERATED_PREFIX}/load/vtable.hpp" + "${GENERATED_PREFIX}/tools/trace.cpp" COMMENT "[spec.py] vk.hpp" COMMAND @@ -42,6 +44,7 @@ COMMAND "--dst" "${GENERATED_PREFIX}/vk.hpp" "--load" "${GENERATED_PREFIX}/load/vtable.hpp" "--dispatch" "${GENERATED_PREFIX}/load/dispatch.cpp" + "--trace" "${GENERATED_PREFIX}/tools/trace.cpp" "--platform" "${VK_PLATFORM}" DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/tools/spec.py" @@ -204,6 +207,18 @@ endforeach () target_link_libraries (vk_info cruft-vk cruft-vk-load) target_link_libraries (vk_hello ${NC_CXX_STDCXXFS} cruft cruft-vk glfw vulkan) +add_library (trace SHARED + "${GENERATED_PREFIX}/tools/trace.cpp" +) + +target_include_directories (trace +PUBLIC + "${CMAKE_CURRENT_SOURCE_DIR}" + "${CMAKE_CURRENT_BINARY_DIR}" + "${CMAKE_CURRENT_SOURCE_DIR}/specs/include/vulkan" +) + +target_link_libraries(trace cruft-vk) ##----------------------------------------------------------------------------- add_dependencies (vk_hello hello.vert.spv hello.frag.spv) diff --git a/tools/spec.py b/tools/spec.py index 766e278..8540d70 100644 --- a/tools/spec.py +++ b/tools/spec.py @@ -991,6 +991,54 @@ def write_dispatch(dst: TextIO, q: List[Type], reg: Registry): }} """) +def write_trace(dst: TextIO, q: List[Type], reg: Registry): + dst.write(""" + #include + #include + #include + #include + #include + #include + + static void* g_lib; + + void init [[gnu::constructor]] (void) { + g_lib = dlopen (getenv ("REAL_VULKAN"), RTLD_LAZY | RTLD_LOCAL); + } + + void deinit [[gnu::destructor]] (void) { + dlclose (g_lib); + g_lib = nullptr; + } + #pragma GCC diagnostic ignored "-Wsign-promo" + """) + + + for obj in (i for i in q if isinstance(i, Command)): + inner = "" + if obj.name in [ 'vkGetInstanceProcAddr' ]: + inner = """ + + #define FWD(NAME) \\ + if (!strcmp(#NAME,pName)) { \\ + if (fn (nullptr, #NAME)) \\ + return (PFN_vkVoidFunction)NAME; \\ + else \\ + return nullptr;\\ + } + MAP_INSTANCE_COMMANDS(FWD) + #undef FWD + std::clog << "Missed: " << pName << '\\n'; + """ + + dst.write(f""" + extern "C" {obj.result} {rename(obj.name)} ({", ".join(p.param for p in obj.params)}) noexcept {{ + std::clog << "{obj.name}" << " " << {'<< " " << '.join (p.name for p in obj.params)} << '\\n'; + static auto fn = reinterpret_cast (dlsym (g_lib, "{obj.name}")); + {inner} + return (*fn) ({','.join (p.name for p in obj.params)}); + }}""") + ############################################################################### import argparse @@ -1005,6 +1053,7 @@ def main(): parser.add_argument('--dst', type=str, help='the output path for the result') parser.add_argument('--load', type=str, help='the output path for the loading routines') parser.add_argument('--dispatch', type=str, help="the output path for function dispatch") + parser.add_argument('--trace', type=str, help="the output path for the vulkan tracing library") parser.add_argument( '--platform', type=str, @@ -1104,6 +1153,9 @@ def main(): with open(args.dispatch, 'w') as dst: write_dispatch(dst, q, reg) + with open(args.trace, 'w') as dst: + write_trace(dst, q, reg) + # ----------------------------------------------------------------------------- if __name__ == '__main__':