1use std::cmp::min;
2
3use crate::{
4 command::FamilyId,
5 core::DeviceId,
6 memory::{DynamicConfig, HeapsConfig, LinearConfig},
7};
8
9#[derive(Clone, Debug, Default)]
25#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
26pub struct Config<D = BasicDevicesConfigure, H = BasicHeapsConfigure, Q = OneGraphicsQueue> {
27 pub devices: D,
29
30 pub heaps: H,
32
33 pub queues: Q,
35}
36
37pub unsafe trait QueuesConfigure {
44 type Priorities: AsRef<[f32]>;
46
47 type Families: IntoIterator<Item = (FamilyId, Self::Priorities)>;
49
50 fn configure(
52 &self,
53 device: DeviceId,
54 families: &[impl rendy_core::hal::queue::QueueFamily],
55 ) -> Self::Families;
56}
57
58#[derive(Clone, Copy, Debug, Default)]
68#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
69pub struct OneGraphicsQueue;
70
71unsafe impl QueuesConfigure for OneGraphicsQueue {
72 type Priorities = [f32; 1];
73 type Families = Option<(FamilyId, [f32; 1])>;
74 fn configure(
75 &self,
76 device: DeviceId,
77 families: &[impl rendy_core::hal::queue::QueueFamily],
78 ) -> Option<(FamilyId, [f32; 1])> {
79 families
80 .iter()
81 .find(|f| f.queue_type().supports_graphics() && f.max_queues() > 0)
82 .map(|f| {
83 (
84 FamilyId {
85 device,
86 index: f.id().0,
87 },
88 [1.0],
89 )
90 })
91 }
92}
93
94#[derive(Clone, Debug)]
98#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
99pub struct SavedQueueConfig(Vec<(usize, Vec<f32>)>);
100
101unsafe impl QueuesConfigure for SavedQueueConfig {
102 type Priorities = Vec<f32>;
103 type Families = Vec<(FamilyId, Vec<f32>)>;
104 fn configure(
105 &self,
106 device: DeviceId,
107 _: &[impl rendy_core::hal::queue::QueueFamily],
108 ) -> Vec<(FamilyId, Vec<f32>)> {
109 self.0
111 .iter()
112 .map(|(id, vec)| (FamilyId { device, index: *id }, vec.clone()))
113 .collect()
114 }
115}
116
117pub unsafe trait HeapsConfigure {
125 type Types: IntoIterator<Item = (rendy_core::hal::memory::Properties, u32, HeapsConfig)>;
127
128 type Heaps: IntoIterator<Item = u64>;
130
131 fn configure(
133 &self,
134 properties: &rendy_core::hal::adapter::MemoryProperties,
135 ) -> (Self::Types, Self::Heaps);
136}
137
138#[derive(Clone, Copy, Debug, Default)]
147#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
148pub struct BasicHeapsConfigure;
149
150unsafe impl HeapsConfigure for BasicHeapsConfigure {
151 type Types = Vec<(rendy_core::hal::memory::Properties, u32, HeapsConfig)>;
152 type Heaps = Vec<u64>;
153
154 fn configure(
155 &self,
156 properties: &rendy_core::hal::adapter::MemoryProperties,
157 ) -> (Self::Types, Self::Heaps) {
158 let _1mb = 1024 * 1024;
159 let _32mb = 32 * _1mb;
160 let _128mb = 128 * _1mb;
161
162 let types = properties
163 .memory_types
164 .iter()
165 .map(|mt| {
166 let config = HeapsConfig {
167 linear: if mt
168 .properties
169 .contains(rendy_core::hal::memory::Properties::CPU_VISIBLE)
170 {
171 Some(LinearConfig {
172 linear_size: min(_128mb, properties.memory_heaps[mt.heap_index] / 16),
173 })
174 } else {
175 None
176 },
177 dynamic: Some(DynamicConfig {
178 block_size_granularity: 256.min(
179 (properties.memory_heaps[mt.heap_index] / 4096).next_power_of_two(),
180 ),
181 min_device_allocation: _1mb
182 .min(properties.memory_heaps[mt.heap_index] / 1048)
183 .next_power_of_two(),
184 max_chunk_size: _32mb.min(
185 (properties.memory_heaps[mt.heap_index] / 128).next_power_of_two(),
186 ),
187 }),
188 };
189
190 (mt.properties, mt.heap_index as u32, config)
191 })
192 .collect();
193
194 let heaps = properties.memory_heaps.iter().cloned().collect();
195
196 (types, heaps)
197 }
198}
199
200#[derive(Clone, Debug)]
204#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
205pub struct SavedHeapsConfig {
206 types: Vec<(rendy_core::hal::memory::Properties, u32, HeapsConfig)>,
207 heaps: Vec<u64>,
208}
209
210unsafe impl HeapsConfigure for SavedHeapsConfig {
211 type Types = Vec<(rendy_core::hal::memory::Properties, u32, HeapsConfig)>;
212 type Heaps = Vec<u64>;
213
214 fn configure(
215 &self,
216 _properties: &rendy_core::hal::adapter::MemoryProperties,
217 ) -> (Self::Types, Self::Heaps) {
218 (self.types.clone(), self.heaps.clone())
219 }
220}
221
222pub trait DevicesConfigure {
225 fn pick<B>(&self, adapters: &[rendy_core::hal::adapter::Adapter<B>]) -> usize
232 where
233 B: rendy_core::hal::Backend;
234}
235
236#[derive(Clone, Copy, Debug, Default)]
247#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
248pub struct BasicDevicesConfigure;
249
250impl DevicesConfigure for BasicDevicesConfigure {
251 fn pick<B>(&self, adapters: &[rendy_core::hal::adapter::Adapter<B>]) -> usize
252 where
253 B: rendy_core::hal::Backend,
254 {
255 adapters
256 .iter()
257 .enumerate()
258 .min_by_key(|(_, adapter)| match adapter.info.device_type {
259 rendy_core::hal::adapter::DeviceType::DiscreteGpu => 0,
260 rendy_core::hal::adapter::DeviceType::IntegratedGpu => 1,
261 rendy_core::hal::adapter::DeviceType::VirtualGpu => 2,
262 rendy_core::hal::adapter::DeviceType::Cpu => 3,
263 _ => 4,
264 })
265 .expect("No adapters present")
266 .0
267 }
268}