kronos_compute/implementation/
buffer.rs

1//! Buffer creation and management
2
3use crate::sys::*;
4use crate::core::*;
5use crate::ffi::*;
6use crate::implementation::icd_loader;
7
8/// Create a buffer
9// SAFETY: This function is called from C code. Caller must ensure:
10// 1. device is a valid VkDevice created by vkCreateDevice
11// 2. pCreateInfo points to a valid VkBufferCreateInfo structure
12// 3. pAllocator is either null or points to valid allocation callbacks
13// 4. pBuffer points to valid memory for writing the buffer handle
14// 5. All fields in pCreateInfo are valid (size > 0, valid usage flags, etc.)
15#[no_mangle]
16pub unsafe extern "C" fn vkCreateBuffer(
17    device: VkDevice,
18    pCreateInfo: *const VkBufferCreateInfo,
19    pAllocator: *const VkAllocationCallbacks,
20    pBuffer: *mut VkBuffer,
21) -> VkResult {
22    if device.is_null() || pCreateInfo.is_null() || pBuffer.is_null() {
23        return VkResult::ErrorInitializationFailed;
24    }
25    
26    // Route via owning ICD if known
27    if let Some(icd) = icd_loader::icd_for_device(device) {
28        log::debug!("Found ICD for device {:?}", device);
29        if let Some(f) = icd.create_buffer { 
30            log::debug!("ICD has create_buffer function, calling it");
31            return f(device, pCreateInfo, pAllocator, pBuffer); 
32        } else {
33            log::error!("ICD for device {:?} does not have create_buffer function!", device);
34        }
35    } else {
36        log::warn!("No ICD found for device {:?} - checking fallback", device);
37    }
38    // Fallback
39    if let Some(icd) = super::forward::get_icd_if_enabled() {
40        log::info!("Using fallback ICD for buffer creation");
41        if let Some(create_buffer) = icd.create_buffer { 
42            log::info!("Fallback ICD has create_buffer function, calling it");
43            return create_buffer(device, pCreateInfo, pAllocator, pBuffer); 
44        } else {
45            log::error!("Fallback ICD does not have create_buffer function!");
46        }
47    }
48    log::error!("No ICD available for buffer creation - returning ErrorInitializationFailed");
49    VkResult::ErrorInitializationFailed
50}
51
52/// Destroy a buffer
53// SAFETY: This function is called from C code. Caller must ensure:
54// 1. device is a valid VkDevice
55// 2. buffer is a valid VkBuffer created by vkCreateBuffer, or VK_NULL_HANDLE
56// 3. pAllocator matches the allocator used in vkCreateBuffer (or both are null)
57// 4. The buffer is not currently bound to memory or in use by any operations
58// 5. All command buffers using this buffer have completed execution
59#[no_mangle]
60pub unsafe extern "C" fn vkDestroyBuffer(
61    device: VkDevice,
62    buffer: VkBuffer,
63    pAllocator: *const VkAllocationCallbacks,
64) {
65    if device.is_null() || buffer.is_null() {
66        return;
67    }
68    
69    if let Some(icd) = icd_loader::icd_for_device(device) {
70        if let Some(f) = icd.destroy_buffer { f(device, buffer, pAllocator); }
71        return;
72    }
73    if let Some(icd) = super::forward::get_icd_if_enabled() {
74        if let Some(destroy_buffer) = icd.destroy_buffer { destroy_buffer(device, buffer, pAllocator); }
75    }
76}
77
78/// Get buffer memory requirements
79// SAFETY: This function is called from C code. Caller must ensure:
80// 1. device is a valid VkDevice
81// 2. buffer is a valid VkBuffer created by vkCreateBuffer
82// 3. pMemoryRequirements points to valid memory for a VkMemoryRequirements structure
83// 4. The buffer has not been destroyed
84#[no_mangle]
85pub unsafe extern "C" fn vkGetBufferMemoryRequirements(
86    device: VkDevice,
87    buffer: VkBuffer,
88    pMemoryRequirements: *mut VkMemoryRequirements,
89) {
90    if device.is_null() || buffer.is_null() || pMemoryRequirements.is_null() {
91        return;
92    }
93    
94    if let Some(icd) = icd_loader::icd_for_device(device) {
95        if let Some(f) = icd.get_buffer_memory_requirements { f(device, buffer, pMemoryRequirements); }
96        return;
97    }
98    if let Some(icd) = super::forward::get_icd_if_enabled() {
99        if let Some(get_buffer_memory_requirements) = icd.get_buffer_memory_requirements { get_buffer_memory_requirements(device, buffer, pMemoryRequirements); }
100    }
101}
102
103/// Bind buffer to memory
104// SAFETY: This function is called from C code. Caller must ensure:
105// 1. device is a valid VkDevice
106// 2. buffer is a valid VkBuffer that has not been bound to memory yet
107// 3. memory is a valid VkDeviceMemory allocated with vkAllocateMemory
108// 4. memoryOffset + buffer.size <= memory.size (fits within allocated memory)
109// 5. The memory type is compatible with the buffer's memory requirements
110// 6. Neither buffer nor memory are currently in use by GPU operations
111#[no_mangle]
112pub unsafe extern "C" fn vkBindBufferMemory(
113    device: VkDevice,
114    buffer: VkBuffer,
115    memory: VkDeviceMemory,
116    memoryOffset: VkDeviceSize,
117) -> VkResult {
118    if device.is_null() || buffer.is_null() || memory.is_null() {
119        return VkResult::ErrorInitializationFailed;
120    }
121    
122    if let Some(icd) = icd_loader::icd_for_device(device) {
123        if let Some(f) = icd.bind_buffer_memory { return f(device, buffer, memory, memoryOffset); }
124    }
125    if let Some(icd) = super::forward::get_icd_if_enabled() {
126        if let Some(bind_buffer_memory) = icd.bind_buffer_memory { return bind_buffer_memory(device, buffer, memory, memoryOffset); }
127    }
128    VkResult::ErrorInitializationFailed
129}