1 // Copyright (c) 2016 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 #![cfg(test)]
11 
12 /// Creates an instance or returns if initialization fails.
13 macro_rules! instance {
14     () => {{
15         use crate::{instance::Instance, VulkanLibrary};
16 
17         let library = match VulkanLibrary::new() {
18             Ok(x) => x,
19             Err(_) => return,
20         };
21 
22         match Instance::new(library, Default::default()) {
23             Ok(x) => x,
24             Err(_) => return,
25         }
26     }};
27 }
28 
29 /// Creates a device and a queue for graphics operations.
30 macro_rules! gfx_dev_and_queue {
31     ($($feature:ident),*) => ({
32         use crate::device::physical::PhysicalDeviceType;
33         use crate::device::{Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo};
34         use crate::device::Features;
35 
36         let instance = instance!();
37         let enabled_extensions = DeviceExtensions::empty();
38         let enabled_features = Features {
39             $(
40                 $feature: true,
41             )*
42             .. Features::empty()
43         };
44 
45         let select = match instance.enumerate_physical_devices() {
46             Ok(x) => x,
47             Err(_) => return,
48         }
49             .filter(|p| {
50                 p.supported_extensions().contains(&enabled_extensions) &&
51                 p.supported_features().contains(&enabled_features)
52             })
53             .filter_map(|p| {
54                 p.queue_family_properties().iter()
55                     .position(|q| q.queue_flags.intersects(crate::device::QueueFlags::GRAPHICS))
56                     .map(|i| (p, i as u32))
57             })
58             .min_by_key(|(p, _)| {
59                 match p.properties().device_type {
60                     PhysicalDeviceType::DiscreteGpu => 0,
61                     PhysicalDeviceType::IntegratedGpu => 1,
62                     PhysicalDeviceType::VirtualGpu => 2,
63                     PhysicalDeviceType::Cpu => 3,
64                     PhysicalDeviceType::Other => 4,
65                 }
66             });
67 
68         let (physical_device, queue_family_index) = match select {
69             Some(x) => x,
70             None => return,
71         };
72 
73         let (device, mut queues) = match Device::new(
74             physical_device,
75             DeviceCreateInfo {
76                 queue_create_infos: vec![QueueCreateInfo {
77                     queue_family_index,
78                     ..Default::default()
79                 }],
80                 enabled_extensions,
81                 enabled_features,
82                 ..Default::default()
83             }
84         ) {
85             Ok(r) => r,
86             Err(_) => return,
87         };
88 
89         (device, queues.next().unwrap())
90     });
91 }
92 
93 macro_rules! assert_should_panic {
94     ($msg:expr, $code:block) => {{
95         let res = ::std::panic::catch_unwind(::std::panic::AssertUnwindSafe(|| $code));
96 
97         match res {
98             Ok(_) => panic!("Test expected to panic but didn't"),
99             Err(err) => {
100                 if let Some(msg) = err.downcast_ref::<String>() {
101                     assert!(msg.contains($msg));
102                 } else if let Some(&msg) = err.downcast_ref::<&str>() {
103                     assert!(msg.contains($msg));
104                 } else {
105                     panic!("Couldn't decipher the panic message of the test")
106                 }
107             }
108         }
109     }};
110 
111     ($code:block) => {{
112         let res = ::std::panic::catch_unwind(::std::panic::AssertUnwindSafe(|| $code));
113 
114         match res {
115             Ok(_) => panic!("Test expected to panic but didn't"),
116             Err(_) => {}
117         }
118     }};
119 }
120