dacite/khr_display/
display.rs

1// Copyright (c) 2017, Dennis Hamester <dennis.hamester@startmail.com>
2//
3// Permission to use, copy, modify, and/or distribute this software for any
4// purpose with or without fee is hereby granted, provided that the above
5// copyright notice and this permission notice appear in all copies.
6//
7// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
8// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
9// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
10// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
11// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
12// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
13// PERFORMANCE OF THIS SOFTWARE.
14
15use FromNativeObject;
16use TryDestroyError;
17use TryDestroyErrorKind;
18use VulkanObject;
19use core::allocator_helper::AllocatorHelper;
20use core;
21use khr_display::{self, DisplayModeKhr};
22use std::cmp::Ordering;
23use std::hash::{Hash, Hasher};
24use std::ptr;
25use vks;
26
27/// See [`VkDisplayKHR`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkDisplayKHR)
28#[derive(Debug, Clone)]
29pub struct DisplayKhr {
30    pub(crate) handle: vks::khr_display::VkDisplayKHR,
31    physical_device: core::PhysicalDevice,
32}
33
34unsafe impl Send for DisplayKhr { }
35
36unsafe impl Sync for DisplayKhr { }
37
38impl PartialEq for DisplayKhr {
39    #[inline]
40    fn eq(&self, other: &Self) -> bool {
41        self.handle == other.handle
42    }
43}
44
45impl Eq for DisplayKhr { }
46
47impl PartialOrd for DisplayKhr {
48    #[inline]
49    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
50        self.handle.partial_cmp(&other.handle)
51    }
52}
53
54impl Ord for DisplayKhr {
55    #[inline]
56    fn cmp(&self, other: &Self) -> Ordering {
57        self.handle.cmp(&other.handle)
58    }
59}
60
61impl Hash for DisplayKhr {
62    #[inline]
63    fn hash<H: Hasher>(&self, state: &mut H) {
64        self.handle.hash(state);
65    }
66}
67
68impl VulkanObject for DisplayKhr {
69    type NativeVulkanObject = vks::khr_display::VkDisplayKHR;
70
71    #[inline]
72    fn id(&self) -> u64 {
73        self.handle
74    }
75
76    #[inline]
77    fn as_native_vulkan_object(&self) -> Self::NativeVulkanObject {
78        self.handle
79    }
80
81    fn try_destroy(self) -> Result<(), TryDestroyError<Self>> {
82        Err(TryDestroyError::new(self, TryDestroyErrorKind::Unsupported))
83    }
84}
85
86impl FromNativeObject for DisplayKhr {
87    type Parameters = core::PhysicalDevice;
88
89    unsafe fn from_native_object(object: Self::NativeVulkanObject, params: Self::Parameters) -> Self {
90        DisplayKhr::new(object, params)
91    }
92}
93
94impl DisplayKhr {
95    pub(crate) fn new(display: vks::khr_display::VkDisplayKHR, physical_device: core::PhysicalDevice) -> Self {
96        DisplayKhr {
97            handle: display,
98            physical_device: physical_device,
99        }
100    }
101
102    #[inline]
103    pub(crate) fn loader(&self) -> &vks::InstanceProcAddrLoader {
104        self.physical_device.loader()
105    }
106
107    #[inline]
108    pub(crate) fn physical_device_handle(&self) -> vks::core::VkPhysicalDevice {
109        self.physical_device.handle
110    }
111
112    #[inline]
113    pub(crate) fn instance(&self) -> &core::Instance {
114        &self.physical_device.instance
115    }
116
117    /// See [`vkGetDisplayModePropertiesKHR`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkGetDisplayModePropertiesKHR)
118    pub fn get_display_mode_properties_khr(&self) -> Result<Vec<khr_display::DisplayModePropertiesKhr>, core::Error> {
119        let mut len = 0;
120        let res = unsafe {
121            self.loader().khr_display.vkGetDisplayModePropertiesKHR(self.physical_device_handle(), self.handle, &mut len, ptr::null_mut())
122        };
123
124        if res != vks::core::VK_SUCCESS {
125            return Err(res.into());
126        }
127
128        let mut properties = Vec::with_capacity(len as usize);
129        let res = unsafe {
130            properties.set_len(len as usize);
131            self.loader().khr_display.vkGetDisplayModePropertiesKHR(self.physical_device_handle(), self.handle, &mut len, properties.as_mut_ptr())
132        };
133
134        if res == vks::core::VK_SUCCESS {
135            Ok(properties.iter().map(|p| khr_display::DisplayModePropertiesKhr::from_vks(p, self.clone())).collect())
136        }
137        else {
138            Err(res.into())
139        }
140    }
141
142    /// See [`vkCreateDisplayModeKHR`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkCreateDisplayModeKHR)
143    pub fn create_display_mode_khr(&self, create_info: &khr_display::DisplayModeCreateInfoKhr, allocator: Option<Box<core::Allocator>>) -> Result<DisplayModeKhr, core::Error> {
144        let allocator_helper = allocator.map(AllocatorHelper::new);
145        let allocation_callbacks = allocator_helper.as_ref().map_or(ptr::null(), AllocatorHelper::callbacks);
146        let create_info_wrapper = khr_display::VkDisplayModeCreateInfoKHRWrapper::new(create_info, true);
147
148        let mut display_mode = Default::default();
149        let res = unsafe {
150            self.loader().khr_display.vkCreateDisplayModeKHR(self.physical_device_handle(), self.handle, &create_info_wrapper.vks_struct, allocation_callbacks, &mut display_mode)
151        };
152
153        if res == vks::core::VK_SUCCESS {
154            if let Some(allocator_helper) = allocator_helper {
155                self.instance().add_display_mode_allocator(allocator_helper);
156            }
157
158            Ok(DisplayModeKhr::new(display_mode, self.clone()))
159        }
160        else {
161            Err(res.into())
162        }
163    }
164}