Skip to content

Instantly share code, notes, and snippets.

@YellowOnion
Last active March 31, 2026 06:50
Show Gist options
  • Select an option

  • Save YellowOnion/cbf40c3c8f848de45878cd575d79acec to your computer and use it in GitHub Desktop.

Select an option

Save YellowOnion/cbf40c3c8f848de45878cd575d79acec to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <vulkan/vulkan.h>
#include <vulkan/vk_layer.h>
#include <assert.h>
#include <glib.h>
#include <time.h>
#include "kairos.h"
const char* _LAYER_PREFIX = "VK_LAYER_KAIROS";
const char* _LAYER_NAME = "VK_LAYER_KAIROS_Dynamic";
enum LOG_LEVEL {
LOG_TRACE,
LOG_DEBUG,
LOG_MSG,
LOG_ERROR
};
FILE *__log_file_fd = NULL;
const int log_level = LOG_TRACE;
#define LOG_MSG(level, ...) ({ \
if (level >= log_level) { \
fprintf(__log_file_fd, __VA_ARGS__); \
fflush(__log_file_fd); \
} \
})
typedef struct {
int64_t t_cpu;
int64_t t_gpu;
int64_t t_idle;
int64_t t_slew;
int64_t t_t3;
} time_stats_t;
time_stats_t __time_stats = {0, 0, 0, 0, 0};
int64_t gettime() {
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return (int64_t)ts.tv_sec * 1000 * 1000 * 1000 + (int64_t)ts.tv_nsec;
}
#define GET_KEY(name) (*(void **)name)
#define NON_OVERRIDES() \
X(CreateInstance) \
X(GetInstanceProcAddr) \
X(GetDeviceProcAddr)
#define INSTANCE_OVERRIDES() \
X(DestroyInstance) \
X(CreateDevice) \
X(DestroyDevice) \
X(EnumerateInstanceLayerProperties) \
X(EnumerateInstanceExtensionProperties) \
X(EnumerateDeviceExtensionProperties)
#define DEVICE_OVERRIDES() \
X(CreateDevice) \
X(DestroyDevice) \
X(QueuePresentKHR)
enum INSTANCE_CMD {
#define X(name) name,
INSTANCE_OVERRIDES
#undef X
};
typedef struct instance_override_t {
PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
#define X(name) PFN_vk##name name;
INSTANCE_OVERRIDES()
#undef X
} instance_override_t;
GRWLock instance_lock;
GHashTable *instance_overrides = NULL;
typedef struct device_override_t {
PFN_vkGetDeviceProcAddr GetDeviceProcAddr;
#define X(name) PFN_vk##name name;
DEVICE_OVERRIDES()
#undef X
} device_override_t;
GRWLock device_lock;
GHashTable *device_overrides = NULL;
__attribute__((constructor))
static void __Kairos_construct() {
__log_file_fd = fopen("kairos.log", "w+");
g_rw_lock_init(&instance_lock);
instance_overrides = g_hash_table_new(&g_direct_hash, &g_direct_equal);
g_rw_lock_init(&device_lock);
device_overrides = g_hash_table_new(&g_direct_hash, &g_direct_equal);
}
__attribute__((destructor))
static void __Kairos_destruct() {
fclose(__log_file_fd);
g_hash_table_destroy(instance_overrides);
g_hash_table_destroy(device_overrides);
}
extern VkResult VKAPI_CALL Kairos_CreateInstance(
const VkInstanceCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkInstance* pInstance) {
LOG_MSG(LOG_TRACE, "CreateInstance\n");
VkLayerInstanceCreateInfo *layerCreateInfo =
(VkLayerInstanceCreateInfo *)pCreateInfo->pNext;
while (layerCreateInfo &&
!(layerCreateInfo->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO
&& layerCreateInfo->function == VK_LAYER_LINK_INFO)) {
layerCreateInfo = (VkLayerInstanceCreateInfo *)layerCreateInfo->pNext;
}
assert(layerCreateInfo != NULL);
PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr =
layerCreateInfo->u.pLayerInfo->pfnNextGetInstanceProcAddr;
PFN_vkCreateInstance fpCreateInstance =
(PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance");
if (fpCreateInstance == NULL)
return VK_ERROR_INITIALIZATION_FAILED;
// Advance the link info for the next element of the chain.
// This ensures that the next layer gets it's layer info and not
// the info for our current layer.
layerCreateInfo->u.pLayerInfo = layerCreateInfo->u.pLayerInfo->pNext;
// Continue call down the chain
VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
if (result != VK_SUCCESS)
return result;
instance_override_t *instance_override = g_new0(instance_override_t, 1);
instance_override->GetInstanceProcAddr = fpGetInstanceProcAddr;
#define X(cmdname) \
instance_override->cmdname = (PFN_vk##cmdname)fpGetInstanceProcAddr(*pInstance, "vk"#cmdname);
INSTANCE_OVERRIDES()
#undef X
g_rw_lock_writer_lock(&instance_lock);
g_hash_table_insert(instance_overrides, GET_KEY(*pInstance),
instance_override);
g_rw_lock_writer_unlock(&instance_lock);
__time_stats.t_t3 = gettime();
return VK_SUCCESS;
}
extern void VKAPI_CALL Kairos_DestroyInstance(
VkInstance pInstance,
VkAllocationCallbacks *pAllocator) {
LOG_MSG(LOG_TRACE, "DestroyInstance\n");
instance_override_t *instance_override = NULL;
g_rw_lock_writer_lock(&instance_lock);
g_hash_table_lookup(instance_overrides, instance_override);
g_free(instance_override);
g_hash_table_remove(instance_overrides, GET_KEY(pInstance));
g_rw_lock_writer_unlock(&instance_lock);
}
extern PFN_vkVoidFunction Kairos_GetInstanceProcAddr(
VkInstance pInstance,
const char* name) {
LOG_MSG(LOG_TRACE, "GIPA: %s\n", name);
#define X(cmdname) \
if (!strcmp("vk" #cmdname, name)) return (PFN_vkVoidFunction)&Kairos_##cmdname;\
NON_OVERRIDES()
INSTANCE_OVERRIDES()
DEVICE_OVERRIDES()
#undef X
g_rw_lock_reader_lock(&instance_lock);
instance_override_t *ret = g_hash_table_lookup(instance_overrides, GET_KEY(pInstance));
g_rw_lock_reader_unlock(&instance_lock);
assert(ret != 0);
return ret->GetInstanceProcAddr(pInstance, name);
}
extern VkResult VKAPI_CALL Kairos_CreateDevice(
VkPhysicalDevice physicalDevice,
const VkDeviceCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkDevice* pDevice) {
LOG_MSG(LOG_TRACE, "CreateDevice\n");
VkLayerDeviceCreateInfo *layerCreateInfo =
(VkLayerDeviceCreateInfo *)pCreateInfo->pNext;
// step through the chain of pNext until we get to the link info
while (layerCreateInfo &&
!(layerCreateInfo->sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO
&& layerCreateInfo->function == VK_LAYER_LINK_INFO)) {
layerCreateInfo = (VkLayerDeviceCreateInfo *)layerCreateInfo->pNext;
}
if (layerCreateInfo == NULL) {
LOG_MSG(LOG_TRACE, "layerCreateInfo is NULL\n");
return VK_ERROR_INITIALIZATION_FAILED;
}
PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr
= layerCreateInfo->u.pLayerInfo->pfnNextGetInstanceProcAddr;
PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr =
layerCreateInfo->u.pLayerInfo->pfnNextGetDeviceProcAddr;
// move chain on for next layer
layerCreateInfo->u.pLayerInfo = layerCreateInfo->u.pLayerInfo->pNext;
PFN_vkCreateDevice fpCreateDevice =
(PFN_vkCreateDevice)fpGetInstanceProcAddr(VK_NULL_HANDLE, "vkCreateDevice");
VkResult ret = fpCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);
if (ret != VK_SUCCESS) {
LOG_MSG(LOG_TRACE, "fpCreateDevice failed ret: %d", ret);
return ret;
}
device_override_t *device_override = g_new0(device_override_t, 1);
device_override->GetDeviceProcAddr = fpGetDeviceProcAddr;
#define X(cmdname) \
device_override->cmdname = (PFN_vk##cmdname)fpGetDeviceProcAddr(*pDevice, "vk"#cmdname);\
DEVICE_OVERRIDES()
#undef X
g_rw_lock_writer_lock(&device_lock);
g_hash_table_insert(device_overrides, GET_KEY(*pDevice),
device_override);
g_rw_lock_writer_unlock(&device_lock);
return VK_SUCCESS;
}
extern void VKAPI_CALL Kairos_DestroyDevice(
VkDevice pDevice,
const VkAllocationCallbacks* pAllocator) {
LOG_MSG(LOG_TRACE, "DestroyDevice\n");
device_override_t *device_override = NULL;
g_rw_lock_writer_lock(&device_lock);
g_hash_table_lookup(device_overrides, device_override);
g_free(device_override);
g_hash_table_remove(device_overrides, GET_KEY(pDevice));
g_rw_lock_writer_unlock(&device_lock);
}
extern PFN_vkVoidFunction Kairos_GetDeviceProcAddr(
VkDevice pDevice,
const char* name) {
LOG_MSG(LOG_TRACE, "GDPA: %s\n", name);
#define X(cmdname) \
if (!strcmp("vk" #cmdname, name)) return (PFN_vkVoidFunction)&Kairos_##cmdname; \
NON_OVERRIDES()
DEVICE_OVERRIDES()
#undef X
if (pDevice == NULL) return NULL;
g_rw_lock_reader_lock(&device_lock);
device_override_t *ret = g_hash_table_lookup(device_overrides, GET_KEY(pDevice));
g_rw_lock_reader_unlock(&device_lock);
assert(ret != 0);
return ret->GetDeviceProcAddr(pDevice, name);
}
extern VkResult VKAPI_CALL Kairos_EnumerateInstanceLayerProperties(
uint32_t *pPropertyCount,
VkLayerProperties *pProperties) {
LOG_MSG(LOG_TRACE, "EnumerateInstanceLayersProperties: start\n");
if(pPropertyCount) *pPropertyCount = 1;
if(pProperties) {
strcpy(pProperties->layerName, _LAYER_NAME);
strcpy(pProperties->description, "a dynamic framerate control");
pProperties->implementationVersion = 1;
pProperties->specVersion = VK_API_VERSION_1_0;
}
return VK_SUCCESS;
}
extern VkResult VKAPI_CALL Kairos_EnumerateInstanceExtensionProperties(
const char *pLayerName,
uint32_t *pPropertyCount,
VkExtensionProperties *pProperties) {
LOG_MSG(LOG_TRACE, "EnumerateInstanceExtensionProperties: %s\n", pLayerName);
if(pLayerName == NULL || strcmp(pLayerName, _LAYER_NAME))
return VK_ERROR_LAYER_NOT_PRESENT;
// don't expose any extensions
if(pPropertyCount) *pPropertyCount = 0;
return VK_SUCCESS;
}
extern VkResult VKAPI_CALL Kairos_EnumerateDeviceExtensionProperties(
VkPhysicalDevice physicalDevice,
const char *pLayerName,
uint32_t *pPropertyCount,
VkExtensionProperties *pProperties) {
LOG_MSG(LOG_TRACE, "EnumerateInstanceExtensionProperties: %s\n", pLayerName);
// pass through any queries that aren't to us
if(pLayerName == NULL || strcmp(pLayerName, _LAYER_NAME)) {
if(physicalDevice == VK_NULL_HANDLE)
return VK_SUCCESS;
g_rw_lock_reader_lock(&device_lock);
instance_override_t *ret = g_hash_table_lookup(instance_overrides, GET_KEY(physicalDevice));
g_rw_lock_reader_unlock(&device_lock);
assert(ret != 0);
return ret->EnumerateDeviceExtensionProperties(
physicalDevice, pLayerName, pPropertyCount, pProperties);
}
// don't expose any extensions
if(pPropertyCount) *pPropertyCount = 0;
return VK_SUCCESS;
}
void print_time(const char * name, int64_t time, const bool nl) {
const int64_t ms = div(time / 1000, 1000).quot;
const int64_t us = div(time / 1000, 1000).rem;
const char *sign = us < 0 && ms < 0 ? "-" : "+";
fprintf(__log_file_fd,
"%s: %s%ld.%03ld ms%s",
name,
sign,
ABS(ms),
ABS(us),
nl ? "\n": " ");
}
extern VkResult VKAPI_CALL Kairos_QueuePresentKHR(
VkQueue queue,
VkPresentInfoKHR *pPresentInfo) {
g_rw_lock_reader_lock(&device_lock);
device_override_t *ret = g_hash_table_lookup(device_overrides, GET_KEY(queue));
g_rw_lock_reader_unlock(&device_lock);
assert(ret != 0);
PFN_vkQueuePresentKHR fpQueuePresentKHR = ret->QueuePresentKHR;
time_stats_t old_time_stats = __time_stats;
int64_t t1 = gettime();
VkResult qp_ret = fpQueuePresentKHR(queue, pPresentInfo);
int64_t t2 = gettime();
int64_t cpu = (t1 - old_time_stats.t_t3 + old_time_stats.t_cpu) / 2;
int64_t gpu = (t2 - t1 + old_time_stats.t_gpu) / 2;
int64_t max = 20 * 1000 * 1000;
int64_t min = 0;
int64_t dyn = 95 * (old_time_stats.t_idle + gpu - cpu) / 100;
int64_t delay = MIN(max, MAX(dyn, min));
print_time("delay", delay, false);
print_time("cpu", cpu, false);
print_time("gpu", gpu, false);
print_time("idle", old_time_stats.t_idle, false);
print_time("slew", old_time_stats.t_slew, true);
assert (ABS(delay) < (uint64_t)10 * 1000 * 1000 * 1000);
if (delay > 0) {
const div_t d = div(delay, 1000 * 1000 * 1000);
struct timespec ts = {d.quot, d.rem};
//struct timespec rem = {0,0};
clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL);
}
int64_t t3 = gettime();
int64_t idle = t3 - t2;
int64_t slew = ((delay > 0 ? idle - delay : 0 ) + old_time_stats.t_slew) / 2 ;
__time_stats.t_cpu = cpu;
__time_stats.t_gpu = gpu;
__time_stats.t_idle = idle;
__time_stats.t_slew = slew;
__time_stats.t_t3 = t3;
return qp_ret;
}
#ifndef KAIROS_H_
#define KAIROS_H_
#include <vulkan/vulkan.h>
extern void VKAPI_CALL Kairos_DestroyInstance(
VkInstance pInstance,
VkAllocationCallbacks *pAllocator);
extern PFN_vkVoidFunction Kairos_GetDeviceProcAddr(
VkDevice pDevice,
const char* name);
extern VkResult VKAPI_CALL Kairos_CreateDevice(
VkPhysicalDevice physicalDevice,
const VkDeviceCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkDevice* pDevice);
extern void VKAPI_CALL Kairos_DestroyDevice(
VkDevice pDevice,
const VkAllocationCallbacks* pAllocator);
extern VkResult VKAPI_CALL Kairos_EnumerateInstanceLayerProperties(
uint32_t *pPropertyCount,
VkLayerProperties *pProperties);
extern VkResult VKAPI_CALL Kairos_EnumerateDeviceLayerProperties(
VkPhysicalDevice physicalDevice,
uint32_t *pPropertyCount,
VkLayerProperties *pProperties);
extern VkResult VKAPI_CALL Kairos_EnumerateInstanceExtensionProperties(
const char *pLayerName,
uint32_t *pPropertyCount,
VkExtensionProperties *pProperties);
extern VkResult VKAPI_CALL Kairos_EnumerateDeviceExtensionProperties(
VkPhysicalDevice physicalDevice,
const char *pLayerName,
uint32_t *pPropertyCount,
VkExtensionProperties *pProperties);
extern VkResult VKAPI_CALL Kairos_QueuePresentKHR(
VkQueue pQueue,
VkPresentInfoKHR *pPresentInfo);
#endif // KAIROS_H_
{
"file_format_version" : "1.0.0",
"layer" : {
"name": "VK_LAYER_KAIROS_Dynamic",
"type": "GLOBAL",
"library_path": "/home/daniel/dev/kairos/build/libkairos.so",
"api_version": "1.4.0",
"implementation_version": "1",
"description": "Dynamic Framerate control",
"functions": {
"vkGetInstanceProcAddr": "Kairos_GetInstanceProcAddr",
"vkGetDeviceProcAddr": "Kairos_GetDeviceProcAddr"
},
"enable_environment": {
"ENABLE_KAIROS_LAYER": "1"
},
"disable_environment": {
"DISABLE_KAIROS_LAYER": "1"
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment