anvilkit_render/renderer/device.rs
1//! # GPU 设备和适配器管理
2//!
3//! 提供 wgpu 设备、适配器和实例的创建和管理功能。
4
5use std::sync::Arc;
6use wgpu::{
7 Instance, Adapter, Device, Queue, Surface,
8 DeviceDescriptor, Features, Limits, PowerPreference, RequestAdapterOptions,
9 InstanceDescriptor, Backends, TextureFormat,
10};
11use winit::window::Window;
12use log::{info, debug};
13
14use anvilkit_core::error::{AnvilKitError, Result};
15
16/// GPU 渲染设备
17///
18/// 封装 wgpu 的实例、适配器、设备和队列,提供统一的 GPU 资源管理。
19///
20/// # 设计理念
21///
22/// - **自动选择**: 自动选择最佳的 GPU 适配器
23/// - **特性检测**: 检测和启用可用的 GPU 特性
24/// - **错误处理**: 完善的错误处理和回退机制
25/// - **跨平台**: 支持多种图形后端
26///
27/// # 示例
28///
29/// ```rust,no_run
30/// use anvilkit_render::renderer::RenderDevice;
31/// use std::sync::Arc;
32/// use winit::window::Window;
33///
34/// # async fn example() -> anvilkit_core::error::Result<()> {
35/// // 创建窗口(示例)
36/// // let window = Arc::new(window);
37///
38/// // 创建渲染设备
39/// // let device = RenderDevice::new(&window).await?;
40///
41/// // 获取设备和队列
42/// // let wgpu_device = device.device();
43/// // let queue = device.queue();
44/// # Ok(())
45/// # }
46/// ```
47pub struct RenderDevice {
48 /// wgpu 实例
49 instance: Instance,
50 /// GPU 适配器
51 adapter: Adapter,
52 /// GPU 设备
53 device: Device,
54 /// 命令队列
55 queue: Queue,
56 /// 支持的特性
57 features: Features,
58 /// 设备限制
59 limits: Limits,
60}
61
62impl RenderDevice {
63 /// 创建新的渲染设备
64 ///
65 /// # 参数
66 ///
67 /// - `window`: 窗口实例,用于创建兼容的表面
68 ///
69 /// # 返回
70 ///
71 /// 成功时返回 RenderDevice 实例,失败时返回错误
72 ///
73 /// # 示例
74 ///
75 /// ```rust,no_run
76 /// use anvilkit_render::renderer::RenderDevice;
77 /// use std::sync::Arc;
78 /// use winit::window::Window;
79 ///
80 /// # async fn example() -> anvilkit_core::error::Result<()> {
81 /// // let window = Arc::new(window);
82 /// // let device = RenderDevice::new(&window).await?;
83 /// # Ok(())
84 /// # }
85 /// ```
86 pub async fn new(window: &Arc<Window>) -> Result<Self> {
87 info!("初始化 GPU 渲染设备");
88
89 // 创建 wgpu 实例
90 let instance = Self::create_instance()?;
91
92 // 创建表面
93 let surface = Self::create_surface(&instance, window)?;
94
95 // 请求适配器
96 let adapter = Self::request_adapter(&instance, &surface).await?;
97
98 // 请求设备和队列
99 let (device, queue) = Self::request_device(&adapter).await?;
100
101 let features = adapter.features();
102 let limits = adapter.limits();
103
104 info!("GPU 渲染设备初始化完成");
105 info!("适配器信息: {:?}", adapter.get_info());
106 info!("支持的特性: {:?}", features);
107
108 Ok(Self {
109 instance,
110 adapter,
111 device,
112 queue,
113 features,
114 limits,
115 })
116 }
117
118 /// 创建 wgpu 实例
119 ///
120 /// # 返回
121 ///
122 /// 成功时返回 Instance,失败时返回错误
123 fn create_instance() -> Result<Instance> {
124 debug!("创建 wgpu 实例");
125
126 let instance = Instance::new(InstanceDescriptor {
127 backends: Backends::all(),
128 ..Default::default()
129 });
130
131 Ok(instance)
132 }
133
134 /// 创建窗口表面
135 ///
136 /// # 参数
137 ///
138 /// - `instance`: wgpu 实例
139 /// - `window`: 窗口实例
140 ///
141 /// # 返回
142 ///
143 /// 成功时返回 Surface,失败时返回错误
144 fn create_surface<'w>(instance: &Instance, window: &'w Arc<Window>) -> Result<Surface<'w>> {
145 debug!("创建窗口表面");
146
147 let surface = instance.create_surface(window.clone())
148 .map_err(|e| AnvilKitError::render(format!("创建表面失败: {}", e)))?;
149
150 Ok(surface)
151 }
152
153 /// 请求 GPU 适配器
154 ///
155 /// # 参数
156 ///
157 /// - `instance`: wgpu 实例
158 /// - `surface`: 窗口表面
159 ///
160 /// # 返回
161 ///
162 /// 成功时返回 Adapter,失败时返回错误
163 async fn request_adapter(instance: &Instance, surface: &Surface<'_>) -> Result<Adapter> {
164 debug!("请求 GPU 适配器");
165
166 let adapter = instance.request_adapter(&RequestAdapterOptions {
167 power_preference: PowerPreference::HighPerformance,
168 compatible_surface: Some(surface),
169 force_fallback_adapter: false,
170 }).await
171 .ok_or_else(|| AnvilKitError::render("未找到兼容的 GPU 适配器".to_string()))?;
172
173 let info = adapter.get_info();
174 info!("选择的 GPU 适配器: {} ({:?})", info.name, info.backend);
175
176 Ok(adapter)
177 }
178
179 /// 请求 GPU 设备和队列
180 ///
181 /// # 参数
182 ///
183 /// - `adapter`: GPU 适配器
184 ///
185 /// # 返回
186 ///
187 /// 成功时返回 (Device, Queue),失败时返回错误
188 async fn request_device(adapter: &Adapter) -> Result<(Device, Queue)> {
189 debug!("请求 GPU 设备和队列");
190
191 let (device, queue) = adapter.request_device(
192 &DeviceDescriptor {
193 label: Some("AnvilKit Render Device"),
194 required_features: Features::empty(),
195 required_limits: Limits::default(),
196 },
197 None, // 不使用跟踪路径
198 ).await
199 .map_err(|e| AnvilKitError::render(format!("创建设备失败: {}", e)))?;
200
201 info!("GPU 设备和队列创建成功");
202
203 Ok((device, queue))
204 }
205
206 /// 获取 wgpu 实例
207 ///
208 /// # 返回
209 ///
210 /// 返回 wgpu 实例的引用
211 ///
212 /// # 示例
213 ///
214 /// ```rust,no_run
215 /// # use anvilkit_render::renderer::RenderDevice;
216 /// # async fn example(device: &RenderDevice) {
217 /// let instance = device.instance();
218 /// # }
219 /// ```
220 pub fn instance(&self) -> &Instance {
221 &self.instance
222 }
223
224 /// 获取 GPU 适配器
225 ///
226 /// # 返回
227 ///
228 /// 返回 GPU 适配器的引用
229 ///
230 /// # 示例
231 ///
232 /// ```rust,no_run
233 /// # use anvilkit_render::renderer::RenderDevice;
234 /// # async fn example(device: &RenderDevice) {
235 /// let adapter = device.adapter();
236 /// let info = adapter.get_info();
237 /// println!("GPU: {}", info.name);
238 /// # }
239 /// ```
240 pub fn adapter(&self) -> &Adapter {
241 &self.adapter
242 }
243
244 /// 获取 GPU 设备
245 ///
246 /// # 返回
247 ///
248 /// 返回 GPU 设备的引用
249 ///
250 /// # 示例
251 ///
252 /// ```rust,no_run
253 /// # use anvilkit_render::renderer::RenderDevice;
254 /// # async fn example(device: &RenderDevice) {
255 /// let wgpu_device = device.device();
256 /// // 使用设备创建资源
257 /// # }
258 /// ```
259 pub fn device(&self) -> &Device {
260 &self.device
261 }
262
263 /// 获取命令队列
264 ///
265 /// # 返回
266 ///
267 /// 返回命令队列的引用
268 ///
269 /// # 示例
270 ///
271 /// ```rust,no_run
272 /// # use anvilkit_render::renderer::RenderDevice;
273 /// # async fn example(device: &RenderDevice) {
274 /// let queue = device.queue();
275 /// // 使用队列提交命令
276 /// # }
277 /// ```
278 pub fn queue(&self) -> &Queue {
279 &self.queue
280 }
281
282 /// 获取支持的特性
283 ///
284 /// # 返回
285 ///
286 /// 返回 GPU 支持的特性集合
287 ///
288 /// # 示例
289 ///
290 /// ```rust,no_run
291 /// # use anvilkit_render::renderer::RenderDevice;
292 /// # use wgpu::Features;
293 /// # async fn example(device: &RenderDevice) {
294 /// let features = device.features();
295 /// if features.contains(Features::TIMESTAMP_QUERY) {
296 /// println!("支持时间戳查询");
297 /// }
298 /// # }
299 /// ```
300 pub fn features(&self) -> Features {
301 self.features
302 }
303
304 /// 获取设备限制
305 ///
306 /// # 返回
307 ///
308 /// 返回 GPU 设备的限制参数
309 ///
310 /// # 示例
311 ///
312 /// ```rust,no_run
313 /// # use anvilkit_render::renderer::RenderDevice;
314 /// # async fn example(device: &RenderDevice) {
315 /// let limits = device.limits();
316 /// println!("最大纹理大小: {}", limits.max_texture_dimension_2d);
317 /// # }
318 /// ```
319 pub fn limits(&self) -> &Limits {
320 &self.limits
321 }
322
323 /// 检查是否支持指定特性
324 ///
325 /// # 参数
326 ///
327 /// - `feature`: 要检查的特性
328 ///
329 /// # 返回
330 ///
331 /// 如果支持指定特性则返回 true
332 ///
333 /// # 示例
334 ///
335 /// ```rust,no_run
336 /// # use anvilkit_render::renderer::RenderDevice;
337 /// # use wgpu::Features;
338 /// # async fn example(device: &RenderDevice) {
339 /// if device.supports_feature(Features::MULTI_DRAW_INDIRECT) {
340 /// println!("支持多重间接绘制");
341 /// }
342 /// # }
343 /// ```
344 pub fn supports_feature(&self, feature: Features) -> bool {
345 self.features.contains(feature)
346 }
347
348 /// 获取首选的表面纹理格式
349 ///
350 /// # 参数
351 ///
352 /// - `surface`: 窗口表面
353 ///
354 /// # 返回
355 ///
356 /// 返回首选的纹理格式
357 ///
358 /// # 示例
359 ///
360 /// ```rust,no_run
361 /// # use anvilkit_render::renderer::RenderDevice;
362 /// # use wgpu::Surface;
363 /// # async fn example(device: &RenderDevice, surface: &Surface<'_>) {
364 /// let format = device.get_preferred_format(surface);
365 /// println!("首选格式: {:?}", format);
366 /// # }
367 /// ```
368 pub fn get_preferred_format(&self, surface: &Surface<'_>) -> TextureFormat {
369 surface.get_capabilities(&self.adapter).formats[0]
370 }
371}
372
373#[cfg(test)]
374mod tests {
375 use super::*;
376
377 #[test]
378 fn test_instance_creation() {
379 // 测试实例创建
380 let instance = RenderDevice::create_instance();
381 assert!(instance.is_ok());
382 }
383
384 #[test]
385 fn test_feature_support() {
386 // 创建一个模拟的设备用于测试
387 let features = Features::empty();
388
389 // 测试特性检查逻辑
390 assert!(!features.contains(Features::TIMESTAMP_QUERY));
391 assert!(features.is_empty());
392 }
393
394 #[test]
395 fn test_instance_backends() {
396 let instance = Instance::new(InstanceDescriptor {
397 backends: Backends::all(),
398 ..Default::default()
399 });
400 // Instance should be created successfully
401 let _ = instance;
402 }
403
404 #[test]
405 fn test_device_limits_defaults() {
406 let limits = Limits::default();
407 assert!(limits.max_texture_dimension_2d > 0);
408 assert!(limits.max_bind_groups > 0);
409 }
410}