Skip to content

Instantly share code, notes, and snippets.

@silversquirl
Created October 1, 2024 22:53
Show Gist options
  • Save silversquirl/b5919eea6a97f6c195c1546ae9347f55 to your computer and use it in GitHub Desktop.
Save silversquirl/b5919eea6a97f6c195c1546ae9347f55 to your computer and use it in GitHub Desktop.
Zig renderdoc API wrapper
//! Wrapper for RenderDoc in-application API, v1.4.1
pub fn load() ?*const Api {
if (!builtin.link_libc) {
return null;
}
var dl: std.DynLib = switch (builtin.os.tag) {
.linux => .{ .inner = .{
.handle = std.c.dlopen(
"librenderdoc.so",
std.c.RTLD.NOW | std.c.RTLD.NOLOAD,
) orelse return null,
} },
else => return null,
};
const getApi = dl.lookup(*const fn (c_int, **const Api) callconv(.C) c_int, "RENDERDOC_GetAPI") orelse return null;
var api: *const Api = undefined;
if (getApi(1_04_01, &api) == 0) {
if (getApi(1_00_00, &api) != 0) {
var version: [3]c_int = undefined;
api.getApiVersion(&version[0], &version[1], &version[2]);
std.log.warn("Failed to load RenderDoc API: requested version 1.4.1, got {}.{}.{}", .{
version[0], version[1], version[2],
});
} else {
std.log.warn("Failed to load RenderDoc API", .{});
}
return null;
}
return api;
}
pub const Api = extern struct {
getApiVersion: *const fn (major: *c_int, minor: *c_int, patch: *c_int) callconv(.C) void,
setCaptureOptionU32: *const fn (opt: CaptureOption, val: u32) callconv(.C) c_int,
setCaptureOptionF32: *const fn (opt: CaptureOption, val: f32) callconv(.C) c_int,
getCaptureOptionU32: *const fn (opt: CaptureOption) callconv(.C) u32,
getCaptureOptionF32: *const fn (opt: CaptureOption) callconv(.C) f32,
setFocusToggleKeys: *const fn (keys: [*]InputButton, num: c_int) callconv(.C) void,
setCaptureKeys: *const fn (keys: [*]InputButton, num: c_int) callconv(.C) void,
_getOverlayBits: *const fn () callconv(.C) u32,
_maskOverlayBits: *const fn (mask_and: u32, mask_or: u32) callconv(.C) void,
removeHooks: *const fn () callconv(.C) void,
unloadCrashHandler: *const fn () callconv(.C) void,
setCaptureFilePathTemplate: *const fn (path_template: [*:0]const u8) callconv(.C) void,
getCaptureFilePathTemplate: *const fn () callconv(.C) [*:0]const u8,
getNumCaptures: *const fn () callconv(.C) u32,
getCapture: *const fn (idx: u32, filename: ?[*]u8, pathlength: ?*u32, timestamp: ?*u64) callconv(.C) u32,
triggerCapture: *const fn () callconv(.C) void,
isTargetControlConnected: *const fn () callconv(.C) u32,
launchReplayUi: *const fn (connect: u32, cmdline: [*:0]const u8) callconv(.C) u32,
setActiveWindow: *const fn (device: DevicePointer, win: WindowHandle) callconv(.C) void,
startFrameCapture: *const fn (device: DevicePointer, win: WindowHandle) callconv(.C) void,
isFrameCapturing: *const fn () callconv(.C) u32,
endFrameCapture: *const fn (device: DevicePointer, win: WindowHandle) callconv(.C) u32,
triggerMultiFrameCapture: *const fn (num_frames: u32) callconv(.C) void,
setCaptureFileComments: *const fn (file_path: ?[*:0]const u8, comments: [*:0]const u8) callconv(.C) void,
discardFrameCapture: *const fn (device: DevicePointer, win: WindowHandle) callconv(.C) u32,
pub fn getOverlayBits(api: *const Api) OverlayBits {
return @bitCast(api._getOverlayBits());
}
pub fn setOverlayBits(api: *const Api, bits: OverlayBits) void {
const mask: u32 = @bitCast(bits);
api._maskOverlayBits(mask, mask);
}
pub fn getCapturePathArrayList(api: *const Api, str: *std.ArrayList(u8), idx: u32) !void {
var len: u32 = undefined;
if (api.getCapture(idx, null, &len, null) == 0) {
return error.OutOfRange;
}
const start = str.items.len;
try str.resize(start + len);
std.debug.assert(api.getCapture(idx, str.items[start..].ptr, null, null) != 0);
// Remove sentinel
str.shrinkRetainingCapacity(start + len - 1);
}
};
pub const CaptureOption = enum(c_int) {
allow_vsync,
allow_fullscreen,
api_validation,
capture_callstacks,
capture_callstacks_only_draws,
delay_for_debugger,
verify_buffer_access,
hook_into_children,
ref_all_resources,
/// Deprecated
___save_all_initials,
capture_all_command_lists,
mute_debug_output,
allow_unsupported_vendor_extensions,
};
pub const InputButton = enum(c_int) {
non_printable = 0x100,
divide,
multiply,
subtract,
plus,
f1,
f2,
f3,
f4,
f5,
f6,
f7,
f8,
f9,
f10,
f11,
f12,
home,
end,
insert,
delete,
page_up,
page_down,
backspace,
tab,
print_screen,
pause,
_, // ASCII letters and numbers can be used
};
pub const OverlayBits = packed struct {
enabled: bool = true,
frame_rate: bool = true,
frame_number: bool = true,
capture_list: bool = true,
_pad0: u4 = 0,
_pad1: u8 = 0,
_pad2: u16 = 0,
comptime {
std.debug.assert(@bitSizeOf(OverlayBits) == @bitSizeOf(u32));
}
};
pub const DevicePointer = ?*anyopaque;
pub const WindowHandle = ?*anyopaque;
const std = @import("std");
const builtin = @import("builtin");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment