1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
//! Lift Direct3D Shader Model 4 and 5 programs (DXBC) to an [`iridia::Program`], any stage, and read their reflection
//! and signatures into the `iridia_interface` vocabulary.
//!
//! The container and token stream are read by [`dxbc_reader`] and [`dxcontainer`]; this crate maps what they read.
//! [`lift`] turns a compiled vertex, pixel, hull, domain, geometry or compute program into a `naga::Module` with its
//! interface, which can then be validated and written as WGSL ([`iridia::emit::wgsl`]) or handed to any naga backend.
//! A register is four raw 32-bit lanes and each instruction reinterprets them as the type it implies; Direct3D's
//! results where they differ from naga's (division by zero, float to integer conversion, `min`/`max` and `saturate`
//! with NaN) are written out as operations and stated in [`iridia::D3dModes`]. What the lifter does not carry is
//! refused, naming the instruction word and the reason; a malformed program is an `Err`, never a panic.
//!
//! The reflection functions read a container's RDEF and signature chunks without lifting its program:
//! [`reflection`] (everything), [`signatures`] (for a container whose RDEF was stripped, as some engines ship them) and
//! [`resource_reflection`] (the resources alone).
//!
//! # Example
//!
//! ```
//! let container = include_bytes!("../tests/fixtures/modes.dxbc"); // `fxc /T ps_5_0` output
//! let program = iridia_dxbc::lift(container)?;
//!
//! assert_eq!(program.stage, iridia::Stage::Pixel);
//! assert_eq!(program.provenance.target, "ps_5_0");
//! // the constant buffer `C : register(b0)` of the HLSL, with the names the container's reflection gives its fields
//! let iridia::ResourceKind::ConstantBuffer { layout } = &program.interface.resources[0].kind else {
//! unreachable!("the only resource is a constant buffer");
//! };
//! let fields: Vec<_> = layout.constants.iter().map(|c| (c.name.as_str(), c.offset)).collect();
//! assert_eq!(fields, [("f", 0), ("u", 16), ("i", 32)]);
//!
//! let wgsl = iridia::emit::wgsl(&program)?;
//! assert!(wgsl.contains("@fragment"));
//!
//! // a refusal names where and why
//! let refusal = iridia_dxbc::lift(&container[..40]).unwrap_err();
//! assert_eq!(refusal.bytecode, "DXBC");
//! # Ok::<(), Box<dyn std::error::Error>>(())
//! ```
//!
//! The container's digest is not verified: this reader does not authenticate shaders.
// Run the examples in the README as doc tests.
;
pub use ;
pub use ;
/// A DXBC program or container refused or unreadable: the word it is at and why ([`iridia::Refusal`]).
pub type Error = Refusal;
/// The result of every function in this crate: `Ok` or a refusal that names the word of the shader code it is at.
pub type Result<T> = Result;
pub
/// What the reader could not read, as a refusal of the program at the same word.
pub
/// The parts of a DXBC container, an error of the container as one of the program (the word it is at).
pub