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