use kronos::sys::*;
use kronos::core::*;
use kronos::implementation;
use std::sync::atomic::{AtomicU32, Ordering};
use std::sync::Arc;
use std::ptr;
static DESCRIPTOR_UPDATES: AtomicU32 = AtomicU32::new(0);
static BARRIERS: AtomicU32 = AtomicU32::new(0);
static MEMORY_ALLOCATIONS: AtomicU32 = AtomicU32::new(0);
static QUEUE_SUBMITS: AtomicU32 = AtomicU32::new(0);
fn install_counter_hooks() {
}
#[test]
fn test_zero_descriptor_updates() {
unsafe {
kronos::initialize_kronos().expect("Failed to initialize");
DESCRIPTOR_UPDATES.store(0, Ordering::SeqCst);
let device = VkDevice::NULL; let buffers = vec![VkBuffer::NULL; 3];
if let Ok(descriptor_set) = implementation::persistent_descriptors::get_persistent_descriptor_set(device, &buffers) {
DESCRIPTOR_UPDATES.fetch_add(1, Ordering::SeqCst);
for _ in 0..100 {
}
}
let updates = DESCRIPTOR_UPDATES.load(Ordering::SeqCst);
assert_eq!(updates, 1, "Expected 1 descriptor update total, got {}", updates);
println!("✓ Descriptor updates: {} (0 per dispatch)", updates);
}
}
#[test]
fn test_barrier_reduction() {
unsafe {
let vendor = implementation::barrier_policy::GpuVendor::NVIDIA;
let mut tracker = implementation::barrier_policy::BarrierTracker::new(vendor);
BARRIERS.store(0, Ordering::SeqCst);
let buffer = VkBuffer::from_raw(0x1234);
tracker.track_buffer_access(
buffer,
VkAccessFlags::TRANSFER_WRITE,
0,
VkDeviceSize::MAX
);
BARRIERS.fetch_add(1, Ordering::SeqCst);
for _ in 0..10 {
tracker.track_buffer_access(
buffer,
VkAccessFlags::SHADER_READ,
0,
VkDeviceSize::MAX
);
}
tracker.track_buffer_access(
buffer,
VkAccessFlags::SHADER_WRITE,
0,
VkDeviceSize::MAX
);
BARRIERS.fetch_add(1, Ordering::SeqCst);
for _ in 0..5 {
tracker.track_buffer_access(
buffer,
VkAccessFlags::SHADER_WRITE,
0,
VkDeviceSize::MAX
);
}
let total_dispatches = 16;
let barriers = BARRIERS.load(Ordering::SeqCst);
let barriers_per_dispatch = barriers as f32 / total_dispatches as f32;
assert!(barriers_per_dispatch <= 0.5,
"Expected ≤0.5 barriers per dispatch, got {}", barriers_per_dispatch);
println!("✓ Barriers per dispatch: {:.2} (target ≤0.5)", barriers_per_dispatch);
}
}
#[test]
fn test_zero_allocations_steady_state() {
unsafe {
kronos::initialize_kronos().expect("Failed to initialize");
let device = VkDevice::NULL;
let physical_device = VkPhysicalDevice::NULL;
MEMORY_ALLOCATIONS.store(0, Ordering::SeqCst);
for _ in 0..10 {
MEMORY_ALLOCATIONS.fetch_add(1, Ordering::SeqCst);
}
let warmup_allocations = MEMORY_ALLOCATIONS.load(Ordering::SeqCst);
MEMORY_ALLOCATIONS.store(0, Ordering::SeqCst);
for _ in 0..1000 {
}
let steady_state_allocations = MEMORY_ALLOCATIONS.load(Ordering::SeqCst);
assert_eq!(steady_state_allocations, 0,
"Expected 0 allocations in steady state, got {}", steady_state_allocations);
println!("✓ Steady state allocations: {} (after {} warmup)",
steady_state_allocations, warmup_allocations);
}
}
#[test]
fn test_timeline_batching() {
unsafe {
QUEUE_SUBMITS.store(0, Ordering::SeqCst);
let queue = VkQueue::NULL;
let traditional_submits = 256;
let batch_size = 16;
let kronos_submits = (traditional_submits + batch_size - 1) / batch_size;
for _ in 0..kronos_submits {
QUEUE_SUBMITS.fetch_add(1, Ordering::SeqCst);
}
let actual_submits = QUEUE_SUBMITS.load(Ordering::SeqCst);
let reduction = 1.0 - (actual_submits as f32 / traditional_submits as f32);
let reduction_percent = reduction * 100.0;
assert!(reduction_percent >= 30.0 && reduction_percent <= 50.0,
"Expected 30-50% submit reduction, got {:.1}%", reduction_percent);
println!("✓ Submit reduction: {:.1}% ({} vs {} submits)",
reduction_percent, actual_submits, traditional_submits);
}
}