1 // Copyright (c) 2017 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 std::error;
11 use std::fmt;
12
13 use crate::device::Device;
14
15 /// Checks whether the dispatch dimensions are supported by the device.
check_dispatch(device: &Device, dimensions: [u32; 3]) -> Result<(), CheckDispatchError>16 pub fn check_dispatch(device: &Device, dimensions: [u32; 3]) -> Result<(), CheckDispatchError> {
17 let max = device
18 .physical_device()
19 .properties()
20 .max_compute_work_group_count;
21
22 if dimensions[0] > max[0] || dimensions[1] > max[1] || dimensions[2] > max[2] {
23 return Err(CheckDispatchError::UnsupportedDimensions {
24 requested: dimensions,
25 max_supported: max,
26 });
27 }
28
29 Ok(())
30 }
31
32 /// Error that can happen when checking dispatch command validity.
33 #[derive(Debug, Copy, Clone)]
34 pub enum CheckDispatchError {
35 /// The dimensions are too large for the device's limits.
36 UnsupportedDimensions {
37 /// The requested dimensions.
38 requested: [u32; 3],
39 /// The actual supported dimensions.
40 max_supported: [u32; 3],
41 },
42 }
43
44 impl error::Error for CheckDispatchError {}
45
46 impl fmt::Display for CheckDispatchError {
47 #[inline]
fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error>48 fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
49 write!(
50 fmt,
51 "{}",
52 match *self {
53 CheckDispatchError::UnsupportedDimensions { .. } => {
54 "the dimensions are too large for the device's limits"
55 }
56 }
57 )
58 }
59 }
60
61 #[cfg(test)]
62 mod tests {
63 use crate::command_buffer::validity;
64
65 #[test]
max_checked()66 fn max_checked() {
67 let (device, _) = gfx_dev_and_queue!();
68
69 let attempted = [u32::MAX, u32::MAX, u32::MAX];
70
71 // Just in case the device is some kind of software implementation.
72 if device
73 .physical_device()
74 .properties()
75 .max_compute_work_group_count
76 == attempted
77 {
78 return;
79 }
80
81 match validity::check_dispatch(&device, attempted) {
82 Err(validity::CheckDispatchError::UnsupportedDimensions { requested, .. }) => {
83 assert_eq!(requested, attempted);
84 }
85 _ => panic!(),
86 }
87 }
88 }
89