Skip to main content

agpu/
command.rs

1//! Command encoding — wrappers for command encoder, render pass, and
2//! compute pass that keep the API within the agpu type system.
3
4use crate::resource::*;
5use crate::types::*;
6
7// ── GpuCommandEncoder ───────────────────────────────────────────────
8
9/// A command encoder — records GPU commands into a command buffer.
10pub struct GpuCommandEncoder {
11    inner: wgpu::CommandEncoder,
12}
13
14impl GpuCommandEncoder {
15    pub(crate) fn from_raw(inner: wgpu::CommandEncoder) -> Self {
16        Self { inner }
17    }
18
19    /// Begin a render pass.
20    pub fn begin_render_pass<'a>(
21        &'a mut self,
22        desc: &wgpu::RenderPassDescriptor<'a>,
23    ) -> GpuRenderPass<'a> {
24        let inner = self.inner.begin_render_pass(desc);
25        GpuRenderPass::from_raw(inner)
26    }
27
28    /// Begin a compute pass.
29    pub fn begin_compute_pass(
30        &mut self,
31        desc: &wgpu::ComputePassDescriptor<'_>,
32    ) -> GpuComputePass<'_> {
33        let inner = self.inner.begin_compute_pass(desc);
34        GpuComputePass::from_raw(inner)
35    }
36
37    /// Copy data between buffers.
38    pub fn copy_buffer_to_buffer(
39        &mut self,
40        source: &GpuBuffer,
41        source_offset: BufferAddress,
42        destination: &GpuBuffer,
43        destination_offset: BufferAddress,
44        size: BufferAddress,
45    ) {
46        self.inner.copy_buffer_to_buffer(
47            source.raw(),
48            source_offset,
49            destination.raw(),
50            destination_offset,
51            size,
52        );
53    }
54
55    /// Copy buffer data to a texture.
56    pub fn copy_buffer_to_texture(
57        &mut self,
58        source: wgpu::TexelCopyBufferInfo<'_>,
59        destination: wgpu::TexelCopyTextureInfo<'_>,
60        copy_size: Extent3d,
61    ) {
62        self.inner
63            .copy_buffer_to_texture(source, destination, copy_size);
64    }
65
66    /// Copy texture data to a buffer.
67    pub fn copy_texture_to_buffer(
68        &mut self,
69        source: wgpu::TexelCopyTextureInfo<'_>,
70        destination: wgpu::TexelCopyBufferInfo<'_>,
71        copy_size: Extent3d,
72    ) {
73        self.inner
74            .copy_texture_to_buffer(source, destination, copy_size);
75    }
76
77    /// Copy between textures.
78    pub fn copy_texture_to_texture(
79        &mut self,
80        source: wgpu::TexelCopyTextureInfo<'_>,
81        destination: wgpu::TexelCopyTextureInfo<'_>,
82        copy_size: Extent3d,
83    ) {
84        self.inner
85            .copy_texture_to_texture(source, destination, copy_size);
86    }
87
88    /// Finish recording and produce a command buffer for submission.
89    pub fn finish(self) -> GpuCommandBuffer {
90        GpuCommandBuffer {
91            inner: self.inner.finish(),
92        }
93    }
94
95    /// Access the underlying wgpu encoder.
96    pub fn raw(&self) -> &wgpu::CommandEncoder {
97        &self.inner
98    }
99
100    /// Access the underlying wgpu encoder mutably.
101    pub fn raw_mut(&mut self) -> &mut wgpu::CommandEncoder {
102        &mut self.inner
103    }
104}
105
106// ── GpuCommandBuffer ────────────────────────────────────────────────
107
108/// A finished command buffer ready for queue submission.
109pub struct GpuCommandBuffer {
110    pub(crate) inner: wgpu::CommandBuffer,
111}
112
113impl GpuCommandBuffer {
114    /// Consume and return the inner wgpu command buffer.
115    pub fn into_inner(self) -> wgpu::CommandBuffer {
116        self.inner
117    }
118    /// Consume and return the inner wgpu command buffer (alias).
119    pub fn raw(self) -> wgpu::CommandBuffer {
120        self.inner
121    }
122}
123
124// ── GpuRenderPass ───────────────────────────────────────────────────
125
126/// A render pass — encodes draw commands for the GPU.
127pub struct GpuRenderPass<'a> {
128    inner: wgpu::RenderPass<'a>,
129}
130
131impl<'a> GpuRenderPass<'a> {
132    pub(crate) fn from_raw(inner: wgpu::RenderPass<'a>) -> Self {
133        Self { inner }
134    }
135
136    /// Set the active render pipeline.
137    pub fn set_pipeline(&mut self, pipeline: &'a GpuRenderPipeline) {
138        self.inner.set_pipeline(pipeline.raw());
139    }
140
141    /// Set a bind group.
142    pub fn set_bind_group(&mut self, index: u32, bind_group: &'a GpuBindGroup, offsets: &[u32]) {
143        self.inner.set_bind_group(index, bind_group.raw(), offsets);
144    }
145
146    /// Set a vertex buffer.
147    pub fn set_vertex_buffer(&mut self, slot: u32, buffer: &'a GpuBuffer) {
148        self.inner.set_vertex_buffer(slot, buffer.raw().slice(..));
149    }
150
151    /// Set vertex buffer with a custom range.
152    pub fn set_vertex_buffer_range(&mut self, slot: u32, buffer_slice: wgpu::BufferSlice<'a>) {
153        self.inner.set_vertex_buffer(slot, buffer_slice);
154    }
155
156    /// Set the index buffer.
157    pub fn set_index_buffer(&mut self, buffer: &'a GpuBuffer, format: IndexFormat) {
158        self.inner.set_index_buffer(buffer.raw().slice(..), format);
159    }
160
161    /// Set index buffer with a custom range.
162    pub fn set_index_buffer_range(
163        &mut self,
164        buffer_slice: wgpu::BufferSlice<'a>,
165        format: IndexFormat,
166    ) {
167        self.inner.set_index_buffer(buffer_slice, format);
168    }
169
170    /// Draw primitives.
171    pub fn draw(&mut self, vertices: std::ops::Range<u32>, instances: std::ops::Range<u32>) {
172        self.inner.draw(vertices, instances);
173    }
174
175    /// Draw indexed primitives.
176    pub fn draw_indexed(
177        &mut self,
178        indices: std::ops::Range<u32>,
179        base_vertex: i32,
180        instances: std::ops::Range<u32>,
181    ) {
182        self.inner.draw_indexed(indices, base_vertex, instances);
183    }
184
185    /// Draw indirect (GPU-driven rendering).
186    pub fn draw_indirect(&mut self, buffer: &'a GpuBuffer, offset: BufferAddress) {
187        self.inner.draw_indirect(buffer.raw(), offset);
188    }
189
190    /// Draw indexed-indirect.
191    pub fn draw_indexed_indirect(&mut self, buffer: &'a GpuBuffer, offset: BufferAddress) {
192        self.inner.draw_indexed_indirect(buffer.raw(), offset);
193    }
194
195    /// Set the viewport.
196    pub fn set_viewport(&mut self, x: f32, y: f32, w: f32, h: f32, min_depth: f32, max_depth: f32) {
197        self.inner.set_viewport(x, y, w, h, min_depth, max_depth);
198    }
199
200    /// Set the scissor rectangle.
201    pub fn set_scissor_rect(&mut self, x: u32, y: u32, w: u32, h: u32) {
202        self.inner.set_scissor_rect(x, y, w, h);
203    }
204
205    /// Set the stencil reference value.
206    pub fn set_stencil_reference(&mut self, reference: u32) {
207        self.inner.set_stencil_reference(reference);
208    }
209
210    /// Set the blend constant.
211    pub fn set_blend_constant(&mut self, color: Color) {
212        self.inner.set_blend_constant(color);
213    }
214
215    /// Set push constants.
216    pub fn set_push_constants(&mut self, stages: ShaderStages, offset: u32, data: &[u8]) {
217        self.inner.set_push_constants(stages, offset, data);
218    }
219
220    /// Access the underlying wgpu render pass.
221    pub fn raw(&self) -> &wgpu::RenderPass<'a> {
222        &self.inner
223    }
224
225    /// Access the underlying wgpu render pass mutably.
226    pub fn raw_mut(&mut self) -> &mut wgpu::RenderPass<'a> {
227        &mut self.inner
228    }
229}
230
231// ── GpuComputePass ──────────────────────────────────────────────────
232
233/// A compute pass — encodes dispatch commands for GPGPU workloads.
234pub struct GpuComputePass<'a> {
235    inner: wgpu::ComputePass<'a>,
236}
237
238impl<'a> GpuComputePass<'a> {
239    pub(crate) fn from_raw(inner: wgpu::ComputePass<'a>) -> Self {
240        Self { inner }
241    }
242
243    /// Set the active compute pipeline.
244    pub fn set_pipeline(&mut self, pipeline: &'a GpuComputePipeline) {
245        self.inner.set_pipeline(pipeline.raw());
246    }
247
248    /// Set a bind group for the compute pipeline.
249    pub fn set_bind_group(&mut self, index: u32, bind_group: &'a GpuBindGroup, offsets: &[u32]) {
250        self.inner.set_bind_group(index, bind_group.raw(), offsets);
251    }
252
253    /// Dispatch compute work groups.
254    pub fn dispatch_workgroups(&mut self, x: u32, y: u32, z: u32) {
255        self.inner.dispatch_workgroups(x, y, z);
256    }
257
258    /// Dispatch compute work groups indirectly from a buffer.
259    pub fn dispatch_workgroups_indirect(&mut self, buffer: &'a GpuBuffer, offset: BufferAddress) {
260        self.inner
261            .dispatch_workgroups_indirect(buffer.raw(), offset);
262    }
263
264    /// Set push constants.
265    pub fn set_push_constants(&mut self, offset: u32, data: &[u8]) {
266        self.inner.set_push_constants(offset, data);
267    }
268
269    /// Access the underlying wgpu compute pass.
270    pub fn raw(&self) -> &wgpu::ComputePass<'a> {
271        &self.inner
272    }
273
274    /// Access the underlying wgpu compute pass mutably.
275    pub fn raw_mut(&mut self) -> &mut wgpu::ComputePass<'a> {
276        &mut self.inner
277    }
278}