You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

94 lines
1.9KB

  1. use crate::render::{Device, Instance, PhysicalDevice, Surface};
  2. use ash::{
  3. version::{DeviceV1_0, InstanceV1_0},
  4. vk,
  5. };
  6. use std::rc::Rc;
  7. pub type QueueIndex = u32;
  8. pub struct QueueFamilyInfo {
  9. pub gfx_index: QueueIndex,
  10. pub srf_index: QueueIndex,
  11. }
  12. pub struct Queue {
  13. handle: vk::Queue,
  14. pub device: Rc<Device>,
  15. pub index: QueueIndex,
  16. }
  17. #[derive(Debug)]
  18. pub enum ErrQueueFamilyCollect {
  19. NoGfxQueue,
  20. NoSrfQueue,
  21. }
  22. impl QueueFamilyInfo {
  23. pub fn collect(
  24. instance: &Instance,
  25. surface: &Surface,
  26. phys_device: &PhysicalDevice,
  27. ) -> Result<Self, ErrQueueFamilyCollect> {
  28. let mut gfx_index = None;
  29. let mut srf_index = None;
  30. let queues = unsafe {
  31. instance.get_physical_device_queue_family_properties(**phys_device)
  32. };
  33. for (i, queue) in queues.iter().enumerate() {
  34. let i = i as u32;
  35. let surface_support = unsafe {
  36. instance.surface_ext.get_physical_device_surface_support(
  37. **phys_device,
  38. i,
  39. **surface,
  40. )
  41. };
  42. if queue.queue_flags.contains(vk::QueueFlags::GRAPHICS) {
  43. gfx_index = Some(i);
  44. }
  45. if surface_support {
  46. srf_index = Some(i);
  47. }
  48. }
  49. Ok(Self {
  50. gfx_index: gfx_index.ok_or(ErrQueueFamilyCollect::NoGfxQueue)?,
  51. srf_index: srf_index.ok_or(ErrQueueFamilyCollect::NoSrfQueue)?,
  52. })
  53. }
  54. }
  55. impl Queue {
  56. pub fn get(device: Rc<Device>, index: u32) -> Rc<Self> {
  57. let handle = unsafe { device.get_device_queue(index, 0) };
  58. Rc::new(Self { handle, device, index })
  59. }
  60. }
  61. impl std::ops::Deref for Queue {
  62. type Target = vk::Queue;
  63. fn deref(&self) -> &Self::Target {
  64. &self.handle
  65. }
  66. }
  67. impl std::fmt::Display for ErrQueueFamilyCollect {
  68. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  69. match self {
  70. Self::NoGfxQueue => f.write_str("Graphics queue not available"),
  71. Self::NoSrfQueue => f.write_str("Surface queue not available"),
  72. }
  73. }
  74. }
  75. impl std::error::Error for ErrQueueFamilyCollect {}
  76. // EOF