astrelis_render/extension.rs
1//! Extension traits for low-level wgpu access.
2//!
3//! This module provides traits that allow accessing the underlying wgpu types
4//! from the Astrelis wrapper types. Use these when you need raw wgpu access
5//! for advanced use cases not covered by the high-level API.
6//!
7//! # Example
8//!
9//! ```ignore
10//! use astrelis_render::{GraphicsContext, AsWgpu};
11//!
12//! let ctx = GraphicsContext::new_owned_sync().expect("Failed to create graphics context");
13//!
14//! // Access raw wgpu device via inherent methods
15//! let device: &wgpu::Device = ctx.device();
16//! let queue: &wgpu::Queue = ctx.queue();
17//!
18//! // Create custom wgpu resources
19//! let buffer = device.create_buffer(&wgpu::BufferDescriptor {
20//! label: Some("Custom Buffer"),
21//! size: 1024,
22//! usage: wgpu::BufferUsages::UNIFORM,
23//! mapped_at_creation: false,
24//! });
25//! ```
26
27use std::sync::Arc;
28
29use crate::{ComputePass, Framebuffer, GraphicsContext, RenderPass, WindowContext};
30
31// =============================================================================
32// Core Extension Traits
33// =============================================================================
34
35/// Access the underlying wgpu type (immutable).
36///
37/// Implement this trait to expose the underlying wgpu type for advanced access.
38pub trait AsWgpu {
39 /// The underlying wgpu type.
40 type WgpuType;
41
42 /// Get a reference to the underlying wgpu type.
43 fn as_wgpu(&self) -> &Self::WgpuType;
44}
45
46/// Access the underlying wgpu type (mutable).
47///
48/// Implement this trait to expose mutable access to the underlying wgpu type.
49pub trait AsWgpuMut: AsWgpu {
50 /// Get a mutable reference to the underlying wgpu type.
51 fn as_wgpu_mut(&mut self) -> &mut Self::WgpuType;
52}
53
54/// Consume and return the underlying wgpu type.
55///
56/// Implement this trait when ownership of the wgpu type can be transferred.
57pub trait IntoWgpu {
58 /// The underlying wgpu type.
59 type WgpuType;
60
61 /// Consume self and return the underlying wgpu type.
62 fn into_wgpu(self) -> Self::WgpuType;
63}
64
65// =============================================================================
66// AsWgpu Implementations
67// =============================================================================
68
69impl AsWgpu for GraphicsContext {
70 type WgpuType = wgpu::Device;
71
72 fn as_wgpu(&self) -> &Self::WgpuType {
73 self.device()
74 }
75}
76
77impl AsWgpu for Arc<GraphicsContext> {
78 type WgpuType = wgpu::Device;
79
80 fn as_wgpu(&self) -> &Self::WgpuType {
81 self.device()
82 }
83}
84
85// Note: Frame no longer implements AsWgpu for CommandEncoder because each RenderPass
86// now owns its own encoder. Use `frame.create_encoder()` to get an encoder, or
87// access via RenderPass::encoder()/encoder_mut().
88
89impl<'a> AsWgpu for RenderPass<'a> {
90 type WgpuType = wgpu::RenderPass<'static>;
91
92 fn as_wgpu(&self) -> &Self::WgpuType {
93 self.wgpu_pass_ref()
94 }
95}
96
97impl<'a> AsWgpuMut for RenderPass<'a> {
98 fn as_wgpu_mut(&mut self) -> &mut Self::WgpuType {
99 self.wgpu_pass()
100 }
101}
102
103impl<'a> AsWgpu for ComputePass<'a> {
104 type WgpuType = wgpu::ComputePass<'static>;
105
106 fn as_wgpu(&self) -> &Self::WgpuType {
107 self.wgpu_pass_ref()
108 }
109}
110
111impl<'a> AsWgpuMut for ComputePass<'a> {
112 fn as_wgpu_mut(&mut self) -> &mut Self::WgpuType {
113 self.wgpu_pass()
114 }
115}
116
117impl AsWgpu for Framebuffer {
118 type WgpuType = wgpu::Texture;
119
120 fn as_wgpu(&self) -> &Self::WgpuType {
121 self.color_texture()
122 }
123}
124
125impl AsWgpu for WindowContext {
126 type WgpuType = wgpu::Surface<'static>;
127
128 fn as_wgpu(&self) -> &Self::WgpuType {
129 &self.surface
130 }
131}
132
133#[cfg(test)]
134mod tests {
135 use super::*;
136
137 // Note: These tests require a GPU context, so they're integration tests.
138 // Here we just test that the traits compile correctly.
139
140 #[test]
141 fn test_trait_object_safety() {
142 // Ensure the core traits can be used as trait objects where applicable
143 fn _takes_as_wgpu<T: AsWgpu>(_: &T) {}
144 fn _takes_as_wgpu_mut<T: AsWgpuMut>(_: &mut T) {}
145 fn _takes_into_wgpu<T: IntoWgpu>(_: T) {}
146 }
147}