|
1 | | -use std::borrow::Borrow; |
2 | | - |
3 | 1 | /// ColorFormat for the surface. |
4 | 2 | pub use gfx_hal::format::Format as ColorFormat; |
5 | | -use gfx_hal::{ |
6 | | - queue::Queue, |
7 | | - window::{ |
8 | | - PresentationSurface, |
9 | | - Surface as _, |
10 | | - }, |
| 3 | +use gfx_hal::window::{ |
| 4 | + PresentationSurface, |
| 5 | + Surface as _, |
11 | 6 | }; |
| 7 | +#[cfg(test)] |
| 8 | +use mockall::automock; |
12 | 9 |
|
13 | 10 | use super::{ |
14 | | - gpu::{ |
15 | | - internal::primary_queue_for, |
16 | | - Gpu, |
17 | | - }, |
| 11 | + gpu::Gpu, |
18 | 12 | Instance, |
19 | 13 | }; |
20 | 14 |
|
21 | | -/// Internal Surface functions. |
22 | | -pub mod internal { |
23 | | - use std::{ |
24 | | - borrow::Borrow, |
25 | | - fmt::Debug, |
26 | | - }; |
27 | | - |
28 | | - use gfx_hal::window::{ |
29 | | - PresentationSurface, |
30 | | - Surface as _, |
31 | | - }; |
32 | | - |
33 | | - /// Checks the queue family if the current Surface can support the GPU. |
34 | | - pub fn can_support_queue_family<RenderBackend: gfx_hal::Backend>( |
35 | | - surface: &super::Surface<RenderBackend>, |
36 | | - queue_family: &RenderBackend::QueueFamily, |
37 | | - ) -> bool { |
38 | | - return surface.gfx_hal_surface.supports_queue_family(queue_family); |
39 | | - } |
40 | | - |
41 | | - /// Get the supported gfx_hal color formats for a given format. |
42 | | - pub fn get_supported_formats<RenderBackend: gfx_hal::Backend>( |
43 | | - surface: &super::Surface<RenderBackend>, |
44 | | - physical_device: &RenderBackend::PhysicalDevice, |
45 | | - ) -> Vec<gfx_hal::format::Format> { |
46 | | - return surface |
47 | | - .gfx_hal_surface |
48 | | - .supported_formats(physical_device) |
49 | | - .unwrap_or(vec![]); |
50 | | - } |
51 | | - |
52 | | - /// Helper function to retrieve the first supported format given a physical |
53 | | - /// GPU device. |
54 | | - pub fn get_first_supported_format<RenderBackend: gfx_hal::Backend>( |
55 | | - surface: &super::Surface<RenderBackend>, |
56 | | - physical_device: &RenderBackend::PhysicalDevice, |
57 | | - ) -> gfx_hal::format::Format { |
58 | | - let supported_formats = get_supported_formats(&surface, physical_device); |
59 | | - |
60 | | - let default_format = *supported_formats |
61 | | - .get(0) |
62 | | - .unwrap_or(&gfx_hal::format::Format::Rgba8Srgb); |
63 | | - |
64 | | - return supported_formats |
65 | | - .into_iter() |
66 | | - .find(|format| -> bool { |
67 | | - format.base_format().1 == gfx_hal::format::ChannelType::Srgb |
68 | | - }) |
69 | | - .unwrap_or(default_format); |
70 | | - } |
71 | | - |
72 | | - /// Acquires a surface image for attaching to a framebuffer. |
73 | | - pub fn take_surface_image_for<RenderBackend: gfx_hal::Backend>( |
74 | | - surface: &mut super::Surface<RenderBackend>, |
75 | | - ) -> Option<<RenderBackend::Surface as PresentationSurface<RenderBackend>>::SwapchainImage>{ |
76 | | - return surface.image.take(); |
77 | | - } |
78 | | - |
79 | | - /// Acquires a surface image for attaching to a framebuffer. |
80 | | - pub fn borrow_surface_image_for<RenderBackend: gfx_hal::Backend>( |
81 | | - surface: &super::Surface<RenderBackend>, |
82 | | - ) -> Option<&<RenderBackend::Surface as PresentationSurface<RenderBackend>>::SwapchainImage>{ |
83 | | - return surface.image.as_ref(); |
84 | | - } |
85 | | - |
86 | | - /// FrameBuffer Attachment |
87 | | - pub fn frame_buffer_attachment_from<RenderBackend: gfx_hal::Backend>( |
88 | | - surface: &super::Surface<RenderBackend>, |
89 | | - ) -> Option<gfx_hal::image::FramebufferAttachment> { |
90 | | - return surface.frame_buffer_attachment.clone(); |
91 | | - } |
92 | | - |
93 | | - pub fn surface_for<RenderBackend: gfx_hal::Backend>( |
94 | | - surface: &mut super::Surface<RenderBackend>, |
95 | | - ) -> &mut RenderBackend::Surface { |
96 | | - return &mut surface.gfx_hal_surface; |
97 | | - } |
98 | | - |
99 | | - /// Borrow the surface and take the image. This internal function is used for |
100 | | - /// rendering and composes surface_for + take image. |
101 | | - pub fn borrow_surface_and_take_image<RenderBackend: gfx_hal::Backend>( |
102 | | - surface: &mut super::Surface<RenderBackend>, |
103 | | - ) -> (&mut RenderBackend::Surface, <RenderBackend::Surface as PresentationSurface<RenderBackend>>::SwapchainImage){ |
104 | | - return ( |
105 | | - &mut surface.gfx_hal_surface, |
106 | | - surface.image.take().expect(""), |
107 | | - ); |
108 | | - } |
109 | | -} |
110 | | - |
111 | | -#[derive(Debug, Clone)] |
112 | 15 | /// The API to use for building surfaces from a graphical instance. |
| 16 | +#[derive(Debug, Clone)] |
113 | 17 | pub struct SurfaceBuilder { |
114 | 18 | name: Option<String>, |
115 | 19 | } |
116 | 20 |
|
| 21 | +#[cfg_attr(test, automock)] |
117 | 22 | impl SurfaceBuilder { |
118 | 23 | pub fn new() -> Self { |
119 | 24 | return Self { name: None }; |
@@ -290,3 +195,102 @@ impl SwapchainBuilder { |
290 | 195 | }; |
291 | 196 | } |
292 | 197 | } |
| 198 | + |
| 199 | +#[cfg(test)] |
| 200 | +mod tests { |
| 201 | + use super::*; |
| 202 | + |
| 203 | + #[test] |
| 204 | + fn test_surface_builder() { |
| 205 | + let surface_builder = SurfaceBuilder::new(); |
| 206 | + assert_eq!(surface_builder.name, None); |
| 207 | + |
| 208 | + let surface_builder = SurfaceBuilder::new().with_name("TestSurface"); |
| 209 | + assert_eq!(surface_builder.name, Some("TestSurface".to_string())); |
| 210 | + } |
| 211 | +} |
| 212 | + |
| 213 | +/// Internal functions to work with the gfx-hal surface components |
| 214 | +pub mod internal { |
| 215 | + use gfx_hal::window::{ |
| 216 | + PresentationSurface, |
| 217 | + Surface as _, |
| 218 | + }; |
| 219 | + |
| 220 | + /// Checks the queue family if the current Surface can support the GPU. |
| 221 | + pub fn can_support_queue_family<RenderBackend: gfx_hal::Backend>( |
| 222 | + surface: &super::Surface<RenderBackend>, |
| 223 | + queue_family: &RenderBackend::QueueFamily, |
| 224 | + ) -> bool { |
| 225 | + return surface.gfx_hal_surface.supports_queue_family(queue_family); |
| 226 | + } |
| 227 | + |
| 228 | + /// Get the supported gfx_hal color formats for a given format. |
| 229 | + pub fn get_supported_formats<RenderBackend: gfx_hal::Backend>( |
| 230 | + surface: &super::Surface<RenderBackend>, |
| 231 | + physical_device: &RenderBackend::PhysicalDevice, |
| 232 | + ) -> Vec<gfx_hal::format::Format> { |
| 233 | + return surface |
| 234 | + .gfx_hal_surface |
| 235 | + .supported_formats(physical_device) |
| 236 | + .unwrap_or(vec![]); |
| 237 | + } |
| 238 | + |
| 239 | + /// Helper function to retrieve the first supported format given a physical |
| 240 | + /// GPU device. |
| 241 | + pub fn get_first_supported_format<RenderBackend: gfx_hal::Backend>( |
| 242 | + surface: &super::Surface<RenderBackend>, |
| 243 | + physical_device: &RenderBackend::PhysicalDevice, |
| 244 | + ) -> gfx_hal::format::Format { |
| 245 | + let supported_formats = get_supported_formats(&surface, physical_device); |
| 246 | + |
| 247 | + let default_format = *supported_formats |
| 248 | + .get(0) |
| 249 | + .unwrap_or(&gfx_hal::format::Format::Rgba8Srgb); |
| 250 | + |
| 251 | + return supported_formats |
| 252 | + .into_iter() |
| 253 | + .find(|format| -> bool { |
| 254 | + format.base_format().1 == gfx_hal::format::ChannelType::Srgb |
| 255 | + }) |
| 256 | + .unwrap_or(default_format); |
| 257 | + } |
| 258 | + |
| 259 | + /// Acquires a surface image for attaching to a framebuffer. |
| 260 | + pub fn take_surface_image_for<RenderBackend: gfx_hal::Backend>( |
| 261 | + surface: &mut super::Surface<RenderBackend>, |
| 262 | + ) -> Option<<RenderBackend::Surface as PresentationSurface<RenderBackend>>::SwapchainImage>{ |
| 263 | + return surface.image.take(); |
| 264 | + } |
| 265 | + |
| 266 | + /// Acquires a surface image for attaching to a framebuffer. |
| 267 | + pub fn borrow_surface_image_for<RenderBackend: gfx_hal::Backend>( |
| 268 | + surface: &super::Surface<RenderBackend>, |
| 269 | + ) -> Option<&<RenderBackend::Surface as PresentationSurface<RenderBackend>>::SwapchainImage>{ |
| 270 | + return surface.image.as_ref(); |
| 271 | + } |
| 272 | + |
| 273 | + /// FrameBuffer Attachment |
| 274 | + pub fn frame_buffer_attachment_from<RenderBackend: gfx_hal::Backend>( |
| 275 | + surface: &super::Surface<RenderBackend>, |
| 276 | + ) -> Option<gfx_hal::image::FramebufferAttachment> { |
| 277 | + return surface.frame_buffer_attachment.clone(); |
| 278 | + } |
| 279 | + |
| 280 | + pub fn surface_for<RenderBackend: gfx_hal::Backend>( |
| 281 | + surface: &mut super::Surface<RenderBackend>, |
| 282 | + ) -> &mut RenderBackend::Surface { |
| 283 | + return &mut surface.gfx_hal_surface; |
| 284 | + } |
| 285 | + |
| 286 | + /// Borrow the surface and take the image. This internal function is used for |
| 287 | + /// rendering and composes surface_for + take image. |
| 288 | + pub fn borrow_surface_and_take_image<RenderBackend: gfx_hal::Backend>( |
| 289 | + surface: &mut super::Surface<RenderBackend>, |
| 290 | + ) -> (&mut RenderBackend::Surface, <RenderBackend::Surface as PresentationSurface<RenderBackend>>::SwapchainImage){ |
| 291 | + return ( |
| 292 | + &mut surface.gfx_hal_surface, |
| 293 | + surface.image.take().expect(""), |
| 294 | + ); |
| 295 | + } |
| 296 | +} |
0 commit comments