1 // Copyright (c) 2022 The vulkano developers 2 // Licensed under the Apache License, Version 2.0 3 // <LICENSE-APACHE or 4 // https://www.apache.org/licenses/LICENSE-2.0> or the MIT 5 // license <LICENSE-MIT or https://opensource.org/licenses/MIT>, 6 // at your option. All files in the project carrying such 7 // notice may not be copied, modified, or distributed except 8 // according to those terms. 9 10 use super::{CommandBufferBuilder, DebugUtilsError}; 11 use crate::{ 12 command_buffer::allocator::CommandBufferAllocator, 13 device::{DeviceOwned, QueueFlags}, 14 instance::debug::DebugUtilsLabel, 15 RequiresOneOf, VulkanObject, 16 }; 17 use std::ffi::CString; 18 19 impl<L, A> CommandBufferBuilder<L, A> 20 where 21 A: CommandBufferAllocator, 22 { 23 /// Opens a command buffer debug label region. 24 #[inline] begin_debug_utils_label( &mut self, label_info: DebugUtilsLabel, ) -> Result<&mut Self, DebugUtilsError>25 pub fn begin_debug_utils_label( 26 &mut self, 27 label_info: DebugUtilsLabel, 28 ) -> Result<&mut Self, DebugUtilsError> { 29 self.validate_begin_debug_utils_label(&label_info)?; 30 31 unsafe { Ok(self.begin_debug_utils_label_unchecked(label_info)) } 32 } 33 validate_begin_debug_utils_label( &self, _label_info: &DebugUtilsLabel, ) -> Result<(), DebugUtilsError>34 fn validate_begin_debug_utils_label( 35 &self, 36 _label_info: &DebugUtilsLabel, 37 ) -> Result<(), DebugUtilsError> { 38 if !self 39 .device() 40 .instance() 41 .enabled_extensions() 42 .ext_debug_utils 43 { 44 return Err(DebugUtilsError::RequirementNotMet { 45 required_for: "`CommandBufferBuilder::begin_debug_utils_label`", 46 requires_one_of: RequiresOneOf { 47 instance_extensions: &["ext_debug_utils"], 48 ..Default::default() 49 }, 50 }); 51 } 52 53 let queue_family_properties = self.queue_family_properties(); 54 55 // VUID-vkCmdBeginDebugUtilsLabelEXT-commandBuffer-cmdpool 56 if !queue_family_properties 57 .queue_flags 58 .intersects(QueueFlags::GRAPHICS | QueueFlags::COMPUTE) 59 { 60 return Err(DebugUtilsError::NotSupportedByQueueFamily); 61 } 62 63 Ok(()) 64 } 65 66 #[cfg_attr(not(feature = "document_unchecked"), doc(hidden))] begin_debug_utils_label_unchecked( &mut self, label_info: DebugUtilsLabel, ) -> &mut Self67 pub unsafe fn begin_debug_utils_label_unchecked( 68 &mut self, 69 label_info: DebugUtilsLabel, 70 ) -> &mut Self { 71 let DebugUtilsLabel { 72 label_name, 73 color, 74 _ne: _, 75 } = label_info; 76 77 let label_name_vk = CString::new(label_name.as_str()).unwrap(); 78 let label_info = ash::vk::DebugUtilsLabelEXT { 79 p_label_name: label_name_vk.as_ptr(), 80 color, 81 ..Default::default() 82 }; 83 84 let fns = self.device().instance().fns(); 85 (fns.ext_debug_utils.cmd_begin_debug_utils_label_ext)(self.handle(), &label_info); 86 87 self.next_command_index += 1; 88 self 89 } 90 91 /// Closes a command buffer debug label region. 92 /// 93 /// # Safety 94 /// 95 /// - When submitting the command buffer, there must be an outstanding command buffer label 96 /// region begun with `begin_debug_utils_label` in the queue, either within this command 97 /// buffer or a previously submitted one. 98 #[inline] end_debug_utils_label(&mut self) -> Result<&mut Self, DebugUtilsError>99 pub unsafe fn end_debug_utils_label(&mut self) -> Result<&mut Self, DebugUtilsError> { 100 self.validate_end_debug_utils_label()?; 101 102 Ok(self.end_debug_utils_label_unchecked()) 103 } 104 validate_end_debug_utils_label(&self) -> Result<(), DebugUtilsError>105 fn validate_end_debug_utils_label(&self) -> Result<(), DebugUtilsError> { 106 if !self 107 .device() 108 .instance() 109 .enabled_extensions() 110 .ext_debug_utils 111 { 112 return Err(DebugUtilsError::RequirementNotMet { 113 required_for: "`CommandBufferBuilder::end_debug_utils_label`", 114 requires_one_of: RequiresOneOf { 115 instance_extensions: &["ext_debug_utils"], 116 ..Default::default() 117 }, 118 }); 119 } 120 121 let queue_family_properties = self.queue_family_properties(); 122 123 // VUID-vkCmdEndDebugUtilsLabelEXT-commandBuffer-cmdpool 124 if !queue_family_properties 125 .queue_flags 126 .intersects(QueueFlags::GRAPHICS | QueueFlags::COMPUTE) 127 { 128 return Err(DebugUtilsError::NotSupportedByQueueFamily); 129 } 130 131 // VUID-vkCmdEndDebugUtilsLabelEXT-commandBuffer-01912 132 // TODO: not checked, so unsafe for now 133 134 // VUID-vkCmdEndDebugUtilsLabelEXT-commandBuffer-01913 135 // TODO: not checked, so unsafe for now 136 137 Ok(()) 138 } 139 140 #[cfg_attr(not(feature = "document_unchecked"), doc(hidden))] end_debug_utils_label_unchecked(&mut self) -> &mut Self141 pub unsafe fn end_debug_utils_label_unchecked(&mut self) -> &mut Self { 142 let fns = self.device().instance().fns(); 143 (fns.ext_debug_utils.cmd_end_debug_utils_label_ext)(self.handle()); 144 145 self.next_command_index += 1; 146 self 147 } 148 149 /// Inserts a command buffer debug label. 150 #[inline] insert_debug_utils_label( &mut self, label_info: DebugUtilsLabel, ) -> Result<&mut Self, DebugUtilsError>151 pub fn insert_debug_utils_label( 152 &mut self, 153 label_info: DebugUtilsLabel, 154 ) -> Result<&mut Self, DebugUtilsError> { 155 self.validate_insert_debug_utils_label(&label_info)?; 156 157 unsafe { Ok(self.insert_debug_utils_label_unchecked(label_info)) } 158 } 159 validate_insert_debug_utils_label( &self, _label_info: &DebugUtilsLabel, ) -> Result<(), DebugUtilsError>160 fn validate_insert_debug_utils_label( 161 &self, 162 _label_info: &DebugUtilsLabel, 163 ) -> Result<(), DebugUtilsError> { 164 if !self 165 .device() 166 .instance() 167 .enabled_extensions() 168 .ext_debug_utils 169 { 170 return Err(DebugUtilsError::RequirementNotMet { 171 required_for: "`CommandBufferBuilder::insert_debug_utils_label`", 172 requires_one_of: RequiresOneOf { 173 instance_extensions: &["ext_debug_utils"], 174 ..Default::default() 175 }, 176 }); 177 } 178 179 let queue_family_properties = self.queue_family_properties(); 180 181 // VUID-vkCmdInsertDebugUtilsLabelEXT-commandBuffer-cmdpool 182 if !queue_family_properties 183 .queue_flags 184 .intersects(QueueFlags::GRAPHICS | QueueFlags::COMPUTE) 185 { 186 return Err(DebugUtilsError::NotSupportedByQueueFamily); 187 } 188 189 Ok(()) 190 } 191 192 #[cfg_attr(not(feature = "document_unchecked"), doc(hidden))] insert_debug_utils_label_unchecked( &mut self, label_info: DebugUtilsLabel, ) -> &mut Self193 pub unsafe fn insert_debug_utils_label_unchecked( 194 &mut self, 195 label_info: DebugUtilsLabel, 196 ) -> &mut Self { 197 let DebugUtilsLabel { 198 label_name, 199 color, 200 _ne: _, 201 } = label_info; 202 203 let label_name_vk = CString::new(label_name.as_str()).unwrap(); 204 let label_info = ash::vk::DebugUtilsLabelEXT { 205 p_label_name: label_name_vk.as_ptr(), 206 color, 207 ..Default::default() 208 }; 209 210 let fns = self.device().instance().fns(); 211 (fns.ext_debug_utils.cmd_insert_debug_utils_label_ext)(self.handle(), &label_info); 212 213 self.next_command_index += 1; 214 self 215 } 216 } 217