tools/trace: add initial interposed Vulkan tracing library

This commit is contained in:
Danny Robson 2019-03-04 10:51:47 +11:00
parent 114e960810
commit 222b662995
2 changed files with 67 additions and 0 deletions

View File

@ -16,6 +16,7 @@ endif ()
############################################################################### ###############################################################################
set (GENERATED_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/cruft/vk/") set (GENERATED_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/cruft/vk/")
file (MAKE_DIRECTORY "${GENERATED_PREFIX}/load") file (MAKE_DIRECTORY "${GENERATED_PREFIX}/load")
file (MAKE_DIRECTORY "${GENERATED_PREFIX}/tools")
if (WIN32) if (WIN32)
@ -33,6 +34,7 @@ OUTPUT
"${GENERATED_PREFIX}/vk.hpp" "${GENERATED_PREFIX}/vk.hpp"
"${GENERATED_PREFIX}/load/dispatch.cpp" "${GENERATED_PREFIX}/load/dispatch.cpp"
"${GENERATED_PREFIX}/load/vtable.hpp" "${GENERATED_PREFIX}/load/vtable.hpp"
"${GENERATED_PREFIX}/tools/trace.cpp"
COMMENT COMMENT
"[spec.py] vk.hpp" "[spec.py] vk.hpp"
COMMAND COMMAND
@ -42,6 +44,7 @@ COMMAND
"--dst" "${GENERATED_PREFIX}/vk.hpp" "--dst" "${GENERATED_PREFIX}/vk.hpp"
"--load" "${GENERATED_PREFIX}/load/vtable.hpp" "--load" "${GENERATED_PREFIX}/load/vtable.hpp"
"--dispatch" "${GENERATED_PREFIX}/load/dispatch.cpp" "--dispatch" "${GENERATED_PREFIX}/load/dispatch.cpp"
"--trace" "${GENERATED_PREFIX}/tools/trace.cpp"
"--platform" "${VK_PLATFORM}" "--platform" "${VK_PLATFORM}"
DEPENDS DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/tools/spec.py" "${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_info cruft-vk cruft-vk-load)
target_link_libraries (vk_hello ${NC_CXX_STDCXXFS} cruft cruft-vk glfw vulkan) 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) add_dependencies (vk_hello hello.vert.spv hello.frag.spv)

View File

@ -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 <cruft/vk/vk.hpp>
#include <cruft/vk/load/vtable.hpp>
#include <cruft/vk/ostream.hpp>
#include <iostream>
#include <dlfcn.h>
#include <cstring>
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<decltype({obj.name})*> (dlsym (g_lib, "{obj.name}"));
{inner}
return (*fn) ({','.join (p.name for p in obj.params)});
}}""")
############################################################################### ###############################################################################
import argparse import argparse
@ -1005,6 +1053,7 @@ def main():
parser.add_argument('--dst', type=str, help='the output path for the result') 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('--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('--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( parser.add_argument(
'--platform', '--platform',
type=str, type=str,
@ -1104,6 +1153,9 @@ def main():
with open(args.dispatch, 'w') as dst: with open(args.dispatch, 'w') as dst:
write_dispatch(dst, q, reg) write_dispatch(dst, q, reg)
with open(args.trace, 'w') as dst:
write_trace(dst, q, reg)
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
if __name__ == '__main__': if __name__ == '__main__':