1use crate::*;
2use derives::{bitflags_newtype, implements};
3
4use super::ffi_helper::opt_pointer;
5
6#[derive(VkHandle, VkObject, InstanceChild)]
8#[VkObject(type = VkSurfaceKHR::OBJECT_TYPE)]
9pub struct SurfaceObject<Instance: crate::Instance>(pub(crate) VkSurfaceKHR, #[parent] pub(crate) Instance);
10unsafe impl<Instance: crate::Instance + Sync> Sync for SurfaceObject<Instance> {}
11unsafe impl<Instance: crate::Instance + Send> Send for SurfaceObject<Instance> {}
12#[implements]
13impl<Instance: crate::Instance> Drop for SurfaceObject<Instance> {
14 #[inline(always)]
15 fn drop(&mut self) {
16 unsafe {
17 crate::vkfn::destroy_surface_khr(self.1.native_ptr(), self.0, core::ptr::null());
18 }
19 }
20}
21impl<Instance: crate::Instance> Surface for SurfaceObject<Instance> {}
22impl<Instance: crate::Instance> SurfaceObject<Instance> {
23 #[implements]
24 #[inline(always)]
25 pub unsafe fn new<
26 PhysicalDevice: crate::PhysicalDevice + crate::InstanceChildTransferrable<ConcreteInstance = Instance>,
27 >(
28 pd: PhysicalDevice,
29 create_info: &(impl SurfaceCreateInfo + ?Sized),
30 ) -> crate::Result<Self> {
31 Ok(Self(
32 unsafe { create_info.execute(pd.instance(), None)? },
33 pd.transfer_instance(),
34 ))
35 }
36}
37impl<Instance: crate::Instance + Clone> SurfaceObject<&'_ Instance> {
38 #[inline(always)]
40 pub fn clone_parent(self) -> SurfaceObject<Instance> {
41 let r = SurfaceObject(self.0, self.1.clone());
42 core::mem::forget(self);
43
44 r
45 }
46}
47
48pub trait Surface: VkHandle<Handle = VkSurfaceKHR> + InstanceChild {}
49DerefContainerBracketImpl!(for Surface {});
50
51pub trait TransferSurfaceObject {
52 type ConcreteSurface: crate::Surface;
53
54 fn transfer_surface(self) -> Self::ConcreteSurface;
55}
56impl<Parent: VulkanStructureProvider + TransferSurfaceObject, T> TransferSurfaceObject for Extends<Parent, T> {
57 type ConcreteSurface = Parent::ConcreteSurface;
58
59 #[inline(always)]
60 fn transfer_surface(self) -> Self::ConcreteSurface {
61 self.0.transfer_surface()
62 }
63}
64
65#[repr(i32)]
67#[derive(Debug, Clone, PartialEq, Eq, Copy)]
68pub enum PresentMode {
69 Immediate = VK_PRESENT_MODE_IMMEDIATE_KHR,
72 Mailbox = VK_PRESENT_MODE_MAILBOX_KHR,
77 FIFO = VK_PRESENT_MODE_FIFO_KHR,
82 FIFORelaxed = VK_PRESENT_MODE_FIFO_RELAXED_KHR,
86}
87
88#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
90#[bitflags_newtype]
91pub struct SurfaceTransformFlags(pub(crate) VkSurfaceTransformFlagsKHR);
92impl SurfaceTransformFlags {
93 pub const IDENTITY: Self = Self(VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR);
95 pub const ROTATE_90: Self = Self(VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR);
97 pub const ROTATE_180: Self = Self(VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR);
99 pub const ROTATE_270: Self = Self(VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR);
101 pub const HORIZONTAL_MIRROR: Self = Self(VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR);
103 pub const HORIZONTAL_MIRROR_ROTATE_90: Self = Self(VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR);
105 pub const HORIZONTAL_MIRROR_ROTATE_180: Self = Self(VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR);
107 pub const HORIZONTAL_MIRROR_ROTATE_270: Self = Self(VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR);
109 pub const INHERIT: Self = Self(VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR);
111}
112
113#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
115#[bitflags_newtype]
116pub struct CompositeAlphaFlags(VkCompositeAlphaFlagsKHR);
117impl CompositeAlphaFlags {
118 pub const OPAQUE: Self = Self(VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR);
120 pub const PRE_MULTIPLIED: Self = Self(VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR);
123 pub const POST_MULTIPLIED: Self = Self(VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR);
127 pub const INHERIT: Self = Self(VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR);
130}
131
132pub type SurfaceCapabilities = VkSurfaceCapabilitiesKHR;
134impl SurfaceCapabilities {
135 pub const fn supported_transforms(&self) -> SurfaceTransformFlags {
137 SurfaceTransformFlags(self.supportedTransforms)
138 }
139
140 pub const fn current_transform(&self) -> SurfaceTransformFlags {
142 SurfaceTransformFlags(self.currentTransform)
143 }
144
145 pub const fn supported_composite_alpha(&self) -> CompositeAlphaFlags {
147 CompositeAlphaFlags(self.supportedCompositeAlpha)
148 }
149
150 pub const fn supported_usage_flags(&self) -> ImageUsageFlags {
152 unsafe { core::mem::transmute(self.supportedUsageFlags) }
153 }
154}
155
156pub type SurfaceFormat = VkSurfaceFormatKHR;
157
158pub trait SurfaceCreateInfo {
159 #[implements]
160 unsafe fn execute(
161 &self,
162 instance: &(impl VkHandle<Handle = VkInstance> + ?Sized),
163 allocation_callbacks: Option<&VkAllocationCallbacks>,
164 ) -> crate::Result<VkSurfaceKHR>;
165}
166
167#[cfg(feature = "VK_KHR_xlib_surface")]
168pub type XlibSurfaceCreateInfo = VkXlibSurfaceCreateInfoKHR;
169#[cfg(feature = "VK_KHR_xlib_surface")]
170impl XlibSurfaceCreateInfo {
171 pub const unsafe fn new(display: *mut x11::xlib::Display, window: x11::xlib::Window) -> Self {
174 Self {
175 sType: Self::TYPE,
176 pNext: core::ptr::null(),
177 flags: 0,
178 dpy: display,
179 window,
180 }
181 }
182}
183#[cfg(feature = "VK_KHR_xlib_surface")]
184impl SurfaceCreateInfo for XlibSurfaceCreateInfo {
185 #[implements]
186 #[inline(always)]
187 unsafe fn execute(
188 &self,
189 instance: &(impl VkHandle<Handle = VkInstance> + ?Sized),
190 allocation_callbacks: Option<&VkAllocationCallbacks>,
191 ) -> crate::Result<VkSurfaceKHR> {
192 let mut h = core::mem::MaybeUninit::uninit();
193
194 unsafe {
195 crate::vkfn::create_xlib_surface_khr(
196 instance.native_ptr(),
197 self,
198 opt_pointer(allocation_callbacks),
199 h.as_mut_ptr(),
200 )
201 .into_result()?;
202 }
203
204 Ok(unsafe { h.assume_init() })
205 }
206}
207
208#[cfg(feature = "VK_KHR_xcb_surface")]
209pub type XcbSurfaceCreateInfo = VkXcbSurfaceCreateInfoKHR;
210#[cfg(feature = "VK_KHR_xcb_surface")]
211impl XcbSurfaceCreateInfo {
212 pub const unsafe fn new(connection: *mut xcb::ffi::xcb_connection_t, window: xcb::x::Window) -> Self {
215 Self {
216 sType: Self::TYPE,
217 pNext: core::ptr::null(),
218 flags: 0,
219 connection,
220 window,
221 }
222 }
223}
224#[cfg(feature = "VK_KHR_xcb_surface")]
225impl SurfaceCreateInfo for XcbSurfaceCreateInfo {
226 #[implements]
227 #[inline(always)]
228 unsafe fn execute(
229 &self,
230 instance: &(impl VkHandle<Handle = VkInstance> + ?Sized),
231 allocation_callbacks: Option<&VkAllocationCallbacks>,
232 ) -> crate::Result<VkSurfaceKHR> {
233 let mut h = core::mem::MaybeUninit::uninit();
234
235 unsafe {
236 crate::vkfn::create_xcb_surface_khr(
237 instance.native_ptr(),
238 self,
239 opt_pointer(allocation_callbacks),
240 h.as_mut_ptr(),
241 )
242 .into_result()?;
243 }
244
245 Ok(unsafe { h.assume_init() })
246 }
247}
248
249#[cfg(feature = "VK_KHR_wayland_surface")]
250pub type WaylandSurfaceCreateInfo = VkWaylandSurfaceCreateInfoKHR;
251#[cfg(feature = "VK_KHR_wayland_surface")]
252impl WaylandSurfaceCreateInfo {
253 pub const unsafe fn new(display: *mut core::ffi::c_void, surface: *mut core::ffi::c_void) -> Self {
256 Self {
257 sType: Self::TYPE,
258 pNext: core::ptr::null(),
259 flags: 0,
260 display,
261 surface,
262 }
263 }
264}
265#[cfg(feature = "VK_KHR_wayland_surface")]
266impl SurfaceCreateInfo for WaylandSurfaceCreateInfo {
267 #[implements]
268 #[inline(always)]
269 unsafe fn execute(
270 &self,
271 instance: &(impl VkHandle<Handle = VkInstance> + ?Sized),
272 allocation_callbacks: Option<&VkAllocationCallbacks>,
273 ) -> crate::Result<VkSurfaceKHR> {
274 let mut h = core::mem::MaybeUninit::uninit();
275
276 unsafe {
277 crate::vkfn::create_wayland_surface_khr(
278 instance.native_ptr(),
279 self,
280 opt_pointer(allocation_callbacks),
281 h.as_mut_ptr(),
282 )
283 .into_result()?;
284 }
285
286 Ok(unsafe { h.assume_init() })
287 }
288}
289
290#[cfg(feature = "VK_KHR_android_surface")]
291pub type AndroidSurfaceCreateInfo = VkAndroidSurfaceCreateInfoKHR;
292#[cfg(feature = "VK_KHR_android_surface")]
293impl AndroidSurfaceCreateInfo {
294 pub const unsafe fn new(window: *mut android::ANativeWindow) -> Self {
297 Self {
298 sType: Self::TYPE,
299 pNext: core::ptr::null(),
300 flags: 0,
301 window,
302 }
303 }
304}
305#[cfg(feature = "VK_KHR_android_surface")]
306impl SurfaceCreateInfo for AndroidSurfaceCreateInfo {
307 #[implements]
308 #[inline(always)]
309 unsafe fn execute(
310 &self,
311 instance: &(impl VkHandle<Handle = VkInstance> + ?Sized),
312 allocation_callbacks: Option<&VkAllocationCallbacks>,
313 ) -> crate::Result<VkSurfaceKHR> {
314 let mut h = core::mem::MaybeUninit::uninit();
315
316 unsafe {
317 crate::vkfn::create_android_surface_khr(
318 instance.native_ptr(),
319 self,
320 opt_pointer(allocation_callbacks),
321 h.as_mut_ptr(),
322 )
323 .into_result()?;
324 }
325
326 Ok(unsafe { h.assume_init() })
327 }
328}
329
330#[cfg(feature = "VK_KHR_win32_surface")]
331pub type Win32SurfaceCreateInfo = VkWin32SurfaceCreateInfoKHR;
332#[cfg(feature = "VK_KHR_win32_surface")]
333impl Win32SurfaceCreateInfo {
334 pub const fn new(hinstance: windows::Win32::Foundation::HINSTANCE, hwnd: windows::Win32::Foundation::HWND) -> Self {
335 Self {
336 sType: Self::TYPE,
337 pNext: core::ptr::null(),
338 flags: 0,
339 hinstance,
340 hwnd,
341 }
342 }
343}
344#[cfg(feature = "VK_KHR_win32_surface")]
345impl SurfaceCreateInfo for Win32SurfaceCreateInfo {
346 #[implements]
347 #[inline(always)]
348 unsafe fn execute(
349 &self,
350 instance: &(impl VkHandle<Handle = VkInstance> + ?Sized),
351 allocation_callbacks: Option<&VkAllocationCallbacks>,
352 ) -> crate::Result<VkSurfaceKHR> {
353 let mut h = core::mem::MaybeUninit::uninit();
354
355 unsafe {
356 crate::vkfn::create_win32_surface_khr(
357 instance.native_ptr(),
358 self,
359 opt_pointer(allocation_callbacks),
360 h.as_mut_ptr(),
361 )
362 .into_result()?;
363 }
364
365 Ok(unsafe { h.assume_init() })
366 }
367}
368
369#[cfg(feature = "VK_EXT_metal_surface")]
370pub type MetalSurfaceCreateInfo = VkMetalSurfaceCreateInfoEXT;
371#[cfg(feature = "VK_EXT_metal_surface")]
372impl MetalSurfaceCreateInfo {
373 pub const unsafe fn new(layer: *const core::ffi::c_void) -> Self {
376 Self {
377 sType: Self::TYPE,
378 pNext: core::ptr::null(),
379 flags: 0,
380 pLayer: layer,
381 }
382 }
383}
384#[cfg(feature = "VK_EXT_metal_surface")]
385impl SurfaceCreateInfo for MetalSurfaceCreateInfo {
386 #[implements]
387 #[inline(always)]
388 unsafe fn execute(
389 &self,
390 instance: &(impl VkHandle<Handle = VkInstance> + ?Sized),
391 allocation_callbacks: Option<&VkAllocationCallbacks>,
392 ) -> crate::Result<VkSurfaceKHR> {
393 let mut h = core::mem::MaybeUninit::uninit();
394
395 unsafe {
396 crate::vkfn::create_metal_surface_ext(
397 instance.native_ptr(),
398 self,
399 opt_pointer(allocation_callbacks),
400 h.as_mut_ptr(),
401 )
402 .into_result()?;
403 }
404
405 Ok(unsafe { h.assume_init() })
406 }
407}
408
409#[cfg(feature = "VK_KHR_display")]
410impl VkDisplaySurfaceCreateInfoKHR {
411 pub const fn new(
412 mode: &super::DisplayMode,
413 plane_index: u32,
414 plane_stack_index: u32,
415 transform: SurfaceTransformFlags,
416 global_alpha: f32,
417 alpha_mode: super::DisplayPlaneAlpha,
418 extent: VkExtent2D,
419 ) -> Self {
420 Self {
421 sType: Self::TYPE,
422 pNext: core::ptr::null(),
423 flags: 0,
424 displayMode: mode.0,
425 planeIndex: plane_index,
426 planeStackIndex: plane_stack_index,
427 transform: transform.bits(),
428 globalAlpha: global_alpha,
429 alphaMode: alpha_mode as _,
430 imageExtent: extent,
431 }
432 }
433}