Skip to main content

interstice_abi/host_calls/gpu/
mod.rs

1use serde::{Deserialize, Serialize};
2
3pub type GpuId = u32;
4
5#[derive(Serialize, Deserialize, Debug)]
6pub enum GpuCall {
7    // ----- Info -----
8    GetSurfaceFormat,
9    GetLimits,
10
11    // ----- Resources -----
12    CreateBuffer(CreateBuffer),
13    DestroyBuffer {
14        id: GpuId,
15    },
16    WriteBuffer(WriteBuffer),
17
18    CreateTexture(CreateTexture),
19    DestroyTexture {
20        id: GpuId,
21    },
22    WriteTexture(WriteTexture),
23    CreateTextureView(CreateTextureView),
24
25    CreateShaderModule(CreateShaderModule),
26
27    CreateBindGroupLayout(CreateBindGroupLayout),
28    CreateBindGroup(CreateBindGroup),
29    CreatePipelineLayout(CreatePipelineLayout),
30
31    CreateRenderPipeline(CreateRenderPipeline),
32    CreateComputePipeline(CreateComputePipeline),
33
34    // ----- Command Encoding -----
35    CreateCommandEncoder,
36    Submit {
37        encoder: GpuId,
38    },
39
40    // Render pass
41    BeginRenderPass(BeginRenderPass),
42    EndRenderPass {
43        pass: GpuId,
44    },
45
46    SetRenderPipeline {
47        pass: GpuId,
48        pipeline: GpuId,
49    },
50    SetBindGroup {
51        pass: GpuId,
52        index: u32,
53        bind_group: GpuId,
54    },
55
56    SetVertexBuffer(SetVertexBuffer),
57    SetIndexBuffer(SetIndexBuffer),
58
59    Draw(Draw),
60    DrawIndexed(DrawIndexed),
61
62    // Compute pass
63    BeginComputePass {
64        encoder: GpuId,
65    },
66    EndComputePass {
67        pass: GpuId,
68    },
69    SetComputePipeline {
70        pass: GpuId,
71        pipeline: GpuId,
72    },
73    Dispatch {
74        pass: GpuId,
75        x: u32,
76        y: u32,
77        z: u32,
78    },
79
80    // Copies
81    CopyBufferToBuffer(CopyBufferToBuffer),
82    CopyBufferToTexture(CopyBufferToTexture),
83    CopyTextureToBuffer(CopyTextureToBuffer),
84
85    // Surface
86    GetCurrentSurfaceTexture,
87    Present,
88    BeginFrame,
89}
90
91#[derive(Serialize, Deserialize, Debug)]
92pub enum GpuResponse {
93    None,
94    I64(i64),
95    TextureFormat(TextureFormat),
96    Err(String),
97}
98
99#[derive(Serialize, Deserialize, Debug)]
100pub struct CreateBuffer {
101    pub size: u64,
102    pub usage: BufferUsage, // your own bitflags enum
103    pub mapped_at_creation: bool,
104}
105
106#[derive(Serialize, Deserialize, Debug)]
107pub struct WriteBuffer {
108    pub buffer: GpuId,
109    pub offset: u64,
110    pub data: Vec<u8>,
111}
112
113#[derive(Serialize, Deserialize, Debug)]
114pub struct CreateTexture {
115    pub width: u32,
116    pub height: u32,
117    pub depth: u32,
118    pub mip_levels: u32,
119    pub sample_count: u32,
120    pub dimension: TextureDimension,
121    pub format: TextureFormat,
122    pub usage: TextureUsage,
123}
124
125#[derive(Serialize, Deserialize, Debug)]
126pub struct WriteTexture {
127    pub texture: GpuId,
128    pub data: Vec<u8>,
129    pub bytes_per_row: u32,
130    pub rows_per_image: u32,
131    pub width: u32,
132    pub height: u32,
133    pub depth: u32,
134}
135
136#[derive(Serialize, Deserialize, Debug)]
137pub struct CreateTextureView {
138    pub texture: GpuId,
139    pub format: Option<TextureFormat>,
140    pub dimension: Option<TextureViewDimension>,
141    pub base_mip_level: u32,
142    pub mip_level_count: Option<u32>,
143    pub base_array_layer: u32,
144    pub array_layer_count: Option<u32>,
145}
146
147#[derive(Serialize, Deserialize, Debug)]
148pub struct CreateShaderModule {
149    pub wgsl_source: String,
150}
151
152#[derive(Serialize, Deserialize, Debug)]
153pub struct CreateBindGroupLayout {
154    pub entries: Vec<BindGroupLayoutEntry>,
155}
156
157#[derive(Serialize, Deserialize, Debug)]
158pub struct CreateBindGroup {
159    pub layout: GpuId,
160    pub entries: Vec<BindGroupEntry>,
161}
162
163#[derive(Serialize, Deserialize, Debug)]
164pub struct CreatePipelineLayout {
165    pub bind_group_layouts: Vec<GpuId>,
166}
167
168#[derive(Serialize, Deserialize, Debug)]
169pub struct CreateRenderPipeline {
170    pub label: Option<String>,
171    pub layout: GpuId,
172    pub vertex: VertexState,
173    pub fragment: Option<FragmentState>,
174    pub primitive: PrimitiveState,
175    pub depth_stencil: Option<DepthStencilState>,
176    pub multisample: MultisampleState,
177    pub multiview: Option<u32>,
178}
179
180#[derive(Serialize, Deserialize, Debug)]
181pub struct VertexState {
182    pub module: GpuId,
183    pub entry_point: String,
184    pub buffers: Vec<VertexBufferLayout>,
185}
186
187#[derive(Serialize, Deserialize, Debug)]
188pub struct FragmentState {
189    pub module: GpuId,
190    pub entry_point: String,
191    pub targets: Vec<ColorTargetState>,
192}
193
194#[derive(Serialize, Deserialize, Debug)]
195pub struct BeginRenderPass {
196    pub encoder: GpuId,
197    pub color_attachments: Vec<RenderPassColorAttachment>,
198    pub depth_stencil: Option<RenderPassDepthStencilAttachment>,
199}
200
201#[derive(Serialize, Deserialize, Debug)]
202pub struct RenderPassColorAttachment {
203    pub view: GpuId,
204    pub resolve_target: Option<GpuId>,
205    pub load: LoadOp,
206    pub store: StoreOp,
207    pub clear_color: [f32; 4],
208}
209
210#[derive(Serialize, Deserialize, Debug)]
211pub struct SetVertexBuffer {
212    pub pass: GpuId,
213    pub slot: u32,
214    pub buffer: GpuId,
215    pub offset: u64,
216    pub size: Option<u64>,
217}
218
219#[derive(Serialize, Deserialize, Debug)]
220pub struct SetIndexBuffer {
221    pub pass: GpuId,
222    pub buffer: GpuId,
223    pub index_format: IndexFormat,
224    pub offset: u64,
225    pub size: Option<u64>,
226}
227
228#[derive(Serialize, Deserialize, Debug)]
229pub struct Draw {
230    pub pass: GpuId,
231    pub vertices: u32,
232    pub instances: u32,
233    pub first_vertex: u32,
234    pub first_instance: u32,
235}
236
237#[derive(Serialize, Deserialize, Debug)]
238pub struct DrawIndexed {
239    pub pass: GpuId,
240    pub indices: u32,
241    pub instances: u32,
242    pub first_index: u32,
243    pub base_vertex: i32,
244    pub first_instance: u32,
245}
246
247#[derive(Serialize, Deserialize, Debug)]
248pub struct CopyBufferToBuffer {
249    pub encoder: GpuId,
250    pub src: GpuId,
251    pub src_offset: u64,
252    pub dst: GpuId,
253    pub dst_offset: u64,
254    pub size: u64,
255}
256
257#[derive(Serialize, Deserialize, Debug)]
258pub struct CreateComputePipeline {
259    pub layout: GpuId,
260    pub module: GpuId,
261    pub entry_point: String,
262}
263
264#[derive(Serialize, Deserialize, Debug)]
265pub struct CopyBufferToTexture {
266    pub encoder: GpuId,
267    pub src_buffer: GpuId,
268    pub src_offset: u64,
269    pub bytes_per_row: u32,
270    pub rows_per_image: u32,
271
272    pub dst_texture: GpuId,
273    pub mip_level: u32,
274    pub origin: [u32; 3],
275
276    pub extent: [u32; 3],
277}
278
279#[derive(Serialize, Deserialize, Debug)]
280pub struct CopyTextureToBuffer {
281    pub encoder: GpuId,
282    pub src_texture: GpuId,
283    pub mip_level: u32,
284    pub origin: [u32; 3],
285
286    pub dst_buffer: GpuId,
287    pub dst_offset: u64,
288    pub bytes_per_row: u32,
289    pub rows_per_image: u32,
290
291    pub extent: [u32; 3],
292}
293
294bitflags::bitflags! {
295    #[derive(Serialize, Deserialize, Debug)]
296    pub struct BufferUsage: u32 {
297        const MAP_READ      = 1 << 0;
298        const MAP_WRITE     = 1 << 1;
299        const COPY_SRC      = 1 << 2;
300        const COPY_DST      = 1 << 3;
301        const INDEX         = 1 << 4;
302        const VERTEX        = 1 << 5;
303        const UNIFORM       = 1 << 6;
304        const STORAGE       = 1 << 7;
305        const INDIRECT      = 1 << 8;
306    }
307}
308
309bitflags::bitflags! {
310    #[derive(Serialize, Deserialize, Debug)]
311    pub struct TextureUsage: u32 {
312        const COPY_SRC          = 1 << 0;
313        const COPY_DST          = 1 << 1;
314        const TEXTURE_BINDING   = 1 << 2;
315        const STORAGE_BINDING   = 1 << 3;
316        const RENDER_ATTACHMENT = 1 << 4;
317    }
318}
319
320#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
321pub enum TextureDimension {
322    D1,
323    D2,
324    D3,
325}
326
327#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
328pub enum TextureViewDimension {
329    D1,
330    D2,
331    D2Array,
332    Cube,
333    CubeArray,
334    D3,
335}
336
337#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
338pub enum TextureFormat {
339    Rgba8Unorm,
340    Rgba8UnormSrgb,
341    Bgra8Unorm,
342    Bgra8UnormSrgb,
343    Depth24Plus,
344    Depth32Float,
345}
346
347#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
348pub enum IndexFormat {
349    Uint16,
350    Uint32,
351}
352
353#[derive(Serialize, Deserialize, Debug)]
354pub struct BindGroupLayoutEntry {
355    pub binding: u32,
356    pub visibility: ShaderStage,
357    pub ty: BindingType,
358}
359
360bitflags::bitflags! {
361    #[derive(Serialize, Deserialize, Debug)]
362    pub struct ShaderStage: u32 {
363        const VERTEX   = 1 << 0;
364        const FRAGMENT = 1 << 1;
365        const COMPUTE  = 1 << 2;
366    }
367}
368
369#[derive(Serialize, Deserialize, Debug)]
370pub enum BindingType {
371    UniformBuffer,
372    StorageBuffer {
373        read_only: bool,
374    },
375    Sampler {
376        comparison: bool,
377    },
378    Texture {
379        sample_type: TextureSampleType,
380        view_dimension: TextureViewDimension,
381        multisampled: bool,
382    },
383    StorageTexture {
384        format: TextureFormat,
385    },
386}
387
388#[derive(Serialize, Deserialize, Debug)]
389pub enum TextureSampleType {
390    Float { filterable: bool },
391    Depth,
392    Sint,
393    Uint,
394}
395
396#[derive(Serialize, Deserialize, Debug)]
397pub struct BindGroupEntry {
398    pub binding: u32,
399    pub resource: BindingResource,
400}
401
402#[derive(Serialize, Deserialize, Debug)]
403pub enum BindingResource {
404    Buffer {
405        buffer: GpuId,
406        offset: u64,
407        size: Option<u64>,
408    },
409    TextureView(GpuId),
410    Sampler(GpuId),
411}
412
413#[derive(Serialize, Deserialize, Debug, Clone)]
414pub struct PrimitiveState {
415    pub topology: PrimitiveTopology,
416    pub cull_mode: Option<CullMode>,
417    pub front_face: FrontFace,
418}
419
420#[derive(Serialize, Deserialize, Debug, Clone)]
421pub enum PrimitiveTopology {
422    TriangleList,
423    TriangleStrip,
424    LineList,
425}
426
427#[derive(Serialize, Deserialize, Debug, Clone)]
428pub enum CullMode {
429    Front,
430    Back,
431}
432
433#[derive(Serialize, Deserialize, Debug, Clone)]
434pub enum FrontFace {
435    Ccw,
436    Cw,
437}
438
439#[derive(Serialize, Deserialize, Debug)]
440pub struct DepthStencilState {
441    pub format: TextureFormat,
442    pub depth_write_enabled: bool,
443    pub depth_compare: CompareFunction,
444    pub stencil: StencilState,
445    pub bias: DepthBiasState,
446}
447
448#[derive(Serialize, Deserialize, Debug)]
449pub struct StencilState {
450    /// Front face mode.
451    pub front: StencilFaceState,
452    /// Back face mode.
453    pub back: StencilFaceState,
454    /// Stencil values are AND'd with this mask when reading and writing from the stencil buffer. Only low 8 bits are used.
455    pub read_mask: u32,
456    /// Stencil values are AND'd with this mask when writing to the stencil buffer. Only low 8 bits are used.
457    pub write_mask: u32,
458}
459
460#[derive(Serialize, Deserialize, Debug)]
461pub struct StencilFaceState {
462    /// Comparison function that determines if the fail_op or pass_op is used on the stencil buffer.
463    pub compare: CompareFunction,
464    /// Operation that is performed when stencil test fails.
465    pub fail_op: StencilOperation,
466    /// Operation that is performed when depth test fails but stencil test succeeds.
467    pub depth_fail_op: StencilOperation,
468    /// Operation that is performed when stencil test success.
469    pub pass_op: StencilOperation,
470}
471
472#[derive(Serialize, Deserialize, Debug)]
473pub enum StencilOperation {
474    /// Keep stencil value unchanged.
475    Keep = 0,
476    /// Set stencil value to zero.
477    Zero = 1,
478    /// Replace stencil value with value provided in most recent call to
479    /// [`RenderPass::set_stencil_reference`][RPssr].
480    ///
481    Replace = 2,
482    /// Bitwise inverts stencil value.
483    Invert = 3,
484    /// Increments stencil value by one, clamping on overflow.
485    IncrementClamp = 4,
486    /// Decrements stencil value by one, clamping on underflow.
487    DecrementClamp = 5,
488    /// Increments stencil value by one, wrapping on overflow.
489    IncrementWrap = 6,
490    /// Decrements stencil value by one, wrapping on underflow.
491    DecrementWrap = 7,
492}
493
494#[derive(Serialize, Deserialize, Debug)]
495pub struct DepthBiasState {
496    /// Constant depth biasing factor, in basic units of the depth format.
497    pub constant: i32,
498    /// Slope depth biasing factor.
499    pub slope_scale: f32,
500    /// Depth bias clamp value (absolute).
501    pub clamp: f32,
502}
503
504#[derive(Serialize, Deserialize, Debug)]
505pub enum CompareFunction {
506    Less,
507    LessEqual,
508    Greater,
509    Always,
510}
511
512#[derive(Serialize, Deserialize, Debug)]
513pub struct MultisampleState {
514    pub count: u32,
515    pub mask: u64,
516    pub alpha_to_coverage_enabled: bool,
517}
518
519#[derive(Serialize, Deserialize, Debug)]
520pub struct VertexBufferLayout {
521    pub array_stride: u64,
522    pub step_mode: VertexStepMode,
523    pub attributes: Vec<VertexAttribute>,
524}
525
526#[derive(Serialize, Deserialize, Debug)]
527pub enum VertexStepMode {
528    Vertex,
529    Instance,
530}
531
532#[derive(Serialize, Deserialize, Debug)]
533pub struct VertexAttribute {
534    pub format: VertexFormat,
535    pub offset: u64,
536    pub shader_location: u32,
537}
538
539#[derive(Serialize, Deserialize, Debug)]
540pub struct ColorTargetState {
541    pub format: TextureFormat,
542    pub blend: Option<BlendState>,
543    pub write_mask: ColorWrites,
544}
545
546#[derive(Serialize, Deserialize, Debug)]
547pub struct RenderPassDepthStencilAttachment {
548    pub view: GpuId,
549    pub depth_load: LoadOp,
550    pub depth_store: StoreOp,
551    pub depth_clear: f32,
552}
553
554#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
555pub enum LoadOp {
556    Load,
557    Clear,
558}
559
560#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
561pub enum StoreOp {
562    Store,
563    Discard,
564}
565
566#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
567pub enum VertexFormat {
568    Float32,
569    Float32x2,
570    Float32x3,
571    Float32x4,
572    Uint32,
573    Uint32x2,
574    Uint32x3,
575    Uint32x4,
576}
577
578#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
579pub struct BlendState {
580    pub color: BlendComponent,
581    pub alpha: BlendComponent,
582}
583
584#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
585pub struct BlendComponent {
586    pub src_factor: BlendFactor,
587    pub dst_factor: BlendFactor,
588    pub operation: BlendOperation,
589}
590
591#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
592pub enum BlendFactor {
593    Zero,
594    One,
595    Src,
596    OneMinusSrc,
597    SrcAlpha,
598    OneMinusSrcAlpha,
599    DstAlpha,
600    OneMinusDstAlpha,
601}
602
603#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
604pub enum BlendOperation {
605    Add,
606    Subtract,
607    ReverseSubtract,
608}
609
610bitflags::bitflags! {
611    #[derive(Serialize, Deserialize, Debug)]
612    pub struct ColorWrites: u32 {
613        const RED   = 1 << 0;
614        const GREEN = 1 << 1;
615        const BLUE  = 1 << 2;
616        const ALPHA = 1 << 3;
617        const ALL   = Self::RED.bits() | Self::GREEN.bits() | Self::BLUE.bits() | Self::ALPHA.bits();
618    }
619}