kronos_compute/implementation/
descriptor.rs

1//! Descriptor set management implementation
2
3use crate::sys::*;
4use crate::core::*;
5use crate::ffi::*;
6use crate::implementation::icd_loader;
7
8/// Create descriptor set layout
9// SAFETY: This function is called from C code. Caller must ensure:
10// 1. device is a valid VkDevice
11// 2. pCreateInfo points to a valid VkDescriptorSetLayoutCreateInfo structure
12// 3. pAllocator is either null or points to valid allocation callbacks
13// 4. pSetLayout points to valid memory for writing the layout handle
14// 5. All binding descriptions in pCreateInfo are valid
15// 6. Descriptor types and shader stages are appropriate for compute
16#[no_mangle]
17pub unsafe extern "C" fn vkCreateDescriptorSetLayout(
18    device: VkDevice,
19    pCreateInfo: *const VkDescriptorSetLayoutCreateInfo,
20    pAllocator: *const VkAllocationCallbacks,
21    pSetLayout: *mut VkDescriptorSetLayout,
22) -> VkResult {
23    if device.is_null() || pCreateInfo.is_null() || pSetLayout.is_null() {
24        return VkResult::ErrorInitializationFailed;
25    }
26    
27    if let Some(icd) = icd_loader::icd_for_device(device) {
28        if let Some(f) = icd.create_descriptor_set_layout { return f(device, pCreateInfo, pAllocator, pSetLayout); }
29    }
30    if let Some(icd) = super::forward::get_icd_if_enabled() {
31        if let Some(create_descriptor_set_layout) = icd.create_descriptor_set_layout { return create_descriptor_set_layout(device, pCreateInfo, pAllocator, pSetLayout); }
32    }
33    VkResult::ErrorInitializationFailed
34}
35
36/// Destroy descriptor set layout
37// SAFETY: This function is called from C code. Caller must ensure:
38// 1. device is a valid VkDevice
39// 2. descriptorSetLayout is a valid VkDescriptorSetLayout, or VK_NULL_HANDLE
40// 3. pAllocator matches the allocator used in vkCreateDescriptorSetLayout
41// 4. No descriptor sets using this layout are currently allocated
42// 5. No pipelines reference this layout
43#[no_mangle]
44pub unsafe extern "C" fn vkDestroyDescriptorSetLayout(
45    device: VkDevice,
46    descriptorSetLayout: VkDescriptorSetLayout,
47    pAllocator: *const VkAllocationCallbacks,
48) {
49    if device.is_null() || descriptorSetLayout.is_null() {
50        return;
51    }
52    
53    if let Some(icd) = icd_loader::icd_for_device(device) {
54        if let Some(f) = icd.destroy_descriptor_set_layout { f(device, descriptorSetLayout, pAllocator); }
55        return;
56    }
57    if let Some(icd) = super::forward::get_icd_if_enabled() {
58        if let Some(destroy_descriptor_set_layout) = icd.destroy_descriptor_set_layout { destroy_descriptor_set_layout(device, descriptorSetLayout, pAllocator); }
59    }
60}
61
62/// Create descriptor pool
63// SAFETY: This function is called from C code. Caller must ensure:
64// 1. device is a valid VkDevice
65// 2. pCreateInfo points to a valid VkDescriptorPoolCreateInfo structure
66// 3. pAllocator is either null or points to valid allocation callbacks
67// 4. pDescriptorPool points to valid memory for writing the pool handle
68// 5. Pool sizes and max sets are reasonable values
69// 6. Descriptor types match what will be allocated from this pool
70#[no_mangle]
71pub unsafe extern "C" fn vkCreateDescriptorPool(
72    device: VkDevice,
73    pCreateInfo: *const VkDescriptorPoolCreateInfo,
74    pAllocator: *const VkAllocationCallbacks,
75    pDescriptorPool: *mut VkDescriptorPool,
76) -> VkResult {
77    if device.is_null() || pCreateInfo.is_null() || pDescriptorPool.is_null() {
78        return VkResult::ErrorInitializationFailed;
79    }
80    
81    if let Some(icd) = icd_loader::icd_for_device(device) {
82        if let Some(f) = icd.create_descriptor_pool { return f(device, pCreateInfo, pAllocator, pDescriptorPool); }
83    }
84    if let Some(icd) = super::forward::get_icd_if_enabled() {
85        if let Some(create_descriptor_pool) = icd.create_descriptor_pool { return create_descriptor_pool(device, pCreateInfo, pAllocator, pDescriptorPool); }
86    }
87    VkResult::ErrorInitializationFailed
88}
89
90/// Destroy descriptor pool
91// SAFETY: This function is called from C code. Caller must ensure:
92// 1. device is a valid VkDevice
93// 2. descriptorPool is a valid VkDescriptorPool, or VK_NULL_HANDLE
94// 3. pAllocator matches the allocator used in vkCreateDescriptorPool
95// 4. All descriptor sets allocated from this pool have been freed or will be freed
96// 5. No command buffers are using descriptor sets from this pool
97#[no_mangle]
98pub unsafe extern "C" fn vkDestroyDescriptorPool(
99    device: VkDevice,
100    descriptorPool: VkDescriptorPool,
101    pAllocator: *const VkAllocationCallbacks,
102) {
103    if device.is_null() || descriptorPool.is_null() {
104        return;
105    }
106    
107    if let Some(icd) = icd_loader::icd_for_device(device) {
108        if let Some(f) = icd.destroy_descriptor_pool { f(device, descriptorPool, pAllocator); }
109        return;
110    }
111    if let Some(icd) = super::forward::get_icd_if_enabled() {
112        if let Some(destroy_descriptor_pool) = icd.destroy_descriptor_pool { destroy_descriptor_pool(device, descriptorPool, pAllocator); }
113    }
114}
115
116/// Reset descriptor pool
117// SAFETY: This function is called from C code. Caller must ensure:
118// 1. device is a valid VkDevice
119// 2. descriptorPool is a valid VkDescriptorPool
120// 3. flags is a valid VkDescriptorPoolResetFlags value
121// 4. All descriptor sets allocated from this pool become invalid after reset
122// 5. No command buffers are currently using descriptor sets from this pool
123#[no_mangle]
124pub unsafe extern "C" fn vkResetDescriptorPool(
125    device: VkDevice,
126    descriptorPool: VkDescriptorPool,
127    flags: VkDescriptorPoolResetFlags,
128) -> VkResult {
129    if device.is_null() || descriptorPool.is_null() {
130        return VkResult::ErrorInitializationFailed;
131    }
132    
133    if let Some(icd) = icd_loader::icd_for_device(device) {
134        if let Some(f) = icd.reset_descriptor_pool { return f(device, descriptorPool, flags); }
135    }
136    if let Some(icd) = super::forward::get_icd_if_enabled() {
137        if let Some(reset_descriptor_pool) = icd.reset_descriptor_pool { return reset_descriptor_pool(device, descriptorPool, flags); }
138    }
139    VkResult::ErrorInitializationFailed
140}
141
142/// Allocate descriptor sets
143// SAFETY: This function is called from C code. Caller must ensure:
144// 1. device is a valid VkDevice
145// 2. pAllocateInfo points to a valid VkDescriptorSetAllocateInfo structure
146// 3. pDescriptorSets points to an array with space for descriptorSetCount handles
147// 4. The descriptor pool has sufficient space for the requested sets
148// 5. All descriptor set layouts in pAllocateInfo are valid
149// 6. The descriptor pool was not created with FREE_DESCRIPTOR_SET_BIT if individual freeing is needed
150#[no_mangle]
151pub unsafe extern "C" fn vkAllocateDescriptorSets(
152    device: VkDevice,
153    pAllocateInfo: *const VkDescriptorSetAllocateInfo,
154    pDescriptorSets: *mut VkDescriptorSet,
155) -> VkResult {
156    if device.is_null() || pAllocateInfo.is_null() || pDescriptorSets.is_null() {
157        return VkResult::ErrorInitializationFailed;
158    }
159    
160    if let Some(icd) = icd_loader::icd_for_device(device) {
161        if let Some(f) = icd.allocate_descriptor_sets { return f(device, pAllocateInfo, pDescriptorSets); }
162    }
163    if let Some(icd) = super::forward::get_icd_if_enabled() {
164        if let Some(allocate_descriptor_sets) = icd.allocate_descriptor_sets { return allocate_descriptor_sets(device, pAllocateInfo, pDescriptorSets); }
165    }
166    VkResult::ErrorInitializationFailed
167}
168
169/// Free descriptor sets
170// SAFETY: This function is called from C code. Caller must ensure:
171// 1. device is a valid VkDevice
172// 2. descriptorPool is a valid VkDescriptorPool
173// 3. descriptorSetCount > 0 and matches the array size
174// 4. pDescriptorSets points to an array of descriptorSetCount valid descriptor sets
175// 5. All descriptor sets were allocated from the specified pool
176// 6. The pool was created with VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT
177// 7. No command buffers are currently using these descriptor sets
178#[no_mangle]
179pub unsafe extern "C" fn vkFreeDescriptorSets(
180    device: VkDevice,
181    descriptorPool: VkDescriptorPool,
182    descriptorSetCount: u32,
183    pDescriptorSets: *const VkDescriptorSet,
184) -> VkResult {
185    if device.is_null() || descriptorPool.is_null() || pDescriptorSets.is_null() || descriptorSetCount == 0 {
186        return VkResult::ErrorInitializationFailed;
187    }
188    
189    if let Some(icd) = icd_loader::icd_for_device(device) {
190        if let Some(f) = icd.free_descriptor_sets { return f(device, descriptorPool, descriptorSetCount, pDescriptorSets); }
191    }
192    if let Some(icd) = super::forward::get_icd_if_enabled() {
193        if let Some(free_descriptor_sets) = icd.free_descriptor_sets { return free_descriptor_sets(device, descriptorPool, descriptorSetCount, pDescriptorSets); }
194    }
195    VkResult::ErrorInitializationFailed
196}
197
198/// Update descriptor sets
199// SAFETY: This function is called from C code. Caller must ensure:
200// 1. device is a valid VkDevice
201// 2. If descriptorWriteCount > 0, pDescriptorWrites points to valid write operations
202// 3. If descriptorCopyCount > 0, pDescriptorCopies points to valid copy operations
203// 4. All descriptor sets referenced in writes/copies are valid and not in use
204// 5. Buffer, image, and sampler resources referenced in writes are valid
205// 6. Descriptor types match the layout bindings
206// 7. No command buffers are currently using the descriptor sets being updated
207#[no_mangle]
208pub unsafe extern "C" fn vkUpdateDescriptorSets(
209    device: VkDevice,
210    descriptorWriteCount: u32,
211    pDescriptorWrites: *const VkWriteDescriptorSet,
212    descriptorCopyCount: u32,
213    pDescriptorCopies: *const VkCopyDescriptorSet,
214) {
215    if device.is_null() {
216        return;
217    }
218    
219    if let Some(icd) = icd_loader::icd_for_device(device) {
220        if let Some(f) = icd.update_descriptor_sets { f(device, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount, pDescriptorCopies); }
221        return;
222    }
223    if let Some(icd) = super::forward::get_icd_if_enabled() {
224        if let Some(update_descriptor_sets) = icd.update_descriptor_sets {
225            update_descriptor_sets(device, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount, pDescriptorCopies);
226        }
227    }
228}