spirv_tools/opt/
compiled.rs1use crate::error;
2use spirv_tools_sys::opt;
3
4pub struct Options {
5 pub(crate) inner: *mut opt::OptimizerOptions,
6}
7
8impl From<super::Options> for Options {
9 fn from(o: super::Options) -> Self {
10 unsafe {
11 let inner = opt::optimizer_options_create();
12
13 if let Some(vopts) = o.validator_options {
14 let vopts = crate::val::compiled::Options::from(vopts);
15
16 opt::optimizer_options_run_validator(inner, true);
17
18 opt::optimizer_options_set_validator_options(inner, vopts.inner);
21 }
22
23 if let Some(max_bound) = o.max_id_bound {
24 opt::optimizer_options_set_max_id_bound(inner, max_bound);
25 }
26
27 if o.preserve_bindings {
28 opt::optimizer_options_preserve_bindings(inner, true);
29 }
30
31 if o.preserve_spec_constants {
32 opt::optimizer_options_preserve_spec_constants(inner, true);
33 }
34
35 Self { inner }
36 }
37 }
38}
39
40impl Drop for Options {
41 #[inline]
42 fn drop(&mut self) {
43 unsafe { opt::optimizer_options_destroy(self.inner) }
44 }
45}
46
47pub struct CompiledOptimizer {
48 inner: *mut opt::Optimizer,
49}
50
51use super::Optimizer;
52
53impl Optimizer for CompiledOptimizer {
54 fn with_env(target: crate::TargetEnv) -> Self {
55 Self {
56 inner: unsafe { opt::optimizer_create(target) },
57 }
58 }
59
60 fn optimize<MC: error::MessageCallback>(
61 &self,
62 input: impl AsRef<[u32]>,
63 msg_callback: &mut MC,
64 options: Option<super::Options>,
65 ) -> Result<crate::binary::Binary, crate::Error> {
66 unsafe {
67 struct Ctx<'a> {
68 cb: &'a mut dyn error::MessageCallback,
69 }
70
71 let mut ctx = Ctx { cb: msg_callback };
72
73 let cb_ctx: *mut std::ffi::c_void = (&mut ctx as *mut Ctx<'_>).cast();
74
75 extern "C" fn callback(
76 level: spirv_tools_sys::diagnostics::MessageLevel,
77 source: *const std::os::raw::c_char,
78 source_pos: *const spirv_tools_sys::diagnostics::Position,
79 msg: *const std::os::raw::c_char,
80 ctx: *mut std::ffi::c_void,
81 ) {
82 unsafe {
83 let ctx: &mut Ctx<'_> = &mut *(ctx.cast::<Ctx<'_>>());
84
85 let msg = error::Message::from_parts(level, source, source_pos, msg);
86
87 ctx.cb.on_message(msg);
88 }
89 }
90
91 let mut binary = std::ptr::null_mut();
92
93 let options = options.map(Options::from);
94
95 let options = match &options {
96 Some(opts) => opts.inner,
97 None => std::ptr::null(),
98 };
99
100 let input = input.as_ref();
101
102 let res = opt::optimizer_run(
103 self.inner,
104 input.as_ptr(),
105 input.len(),
106 &mut binary,
107 callback,
108 cb_ctx,
109 options,
110 );
111
112 match res {
113 spirv_tools_sys::shared::SpirvResult::Success => {
114 if binary.is_null() {
115 return Err(error::Error {
116 inner: spirv_tools_sys::shared::SpirvResult::InternalError,
117 diagnostic: Some(crate::error::Diagnostic {
118 line: 0,
119 column: 0,
120 index: 0,
121 message: "spirv optimizer indicated success but did not return a valid binary".to_owned(),
122 notes: String::new(),
123 is_text: false,
124 }),
125 });
126 }
127
128 Ok(crate::binary::Binary::External(
129 crate::binary::external::ExternalBinary::new(binary),
130 ))
131 }
132 other => Err(error::Error {
133 inner: other,
134 diagnostic: None,
135 }),
136 }
137 }
138 }
139
140 #[inline]
142 fn register_pass(&mut self, pass: super::Passes) -> &mut Self {
143 unsafe { opt::optimizer_register_pass(self.inner, pass) }
144 self
145 }
146
147 #[inline]
151 fn register_performance_passes(&mut self) -> &mut Self {
152 unsafe { opt::optimizer_register_performance_passes(self.inner) }
153 self
154 }
155
156 #[inline]
160 fn register_size_passes(&mut self) -> &mut Self {
161 unsafe { opt::optimizer_register_size_passes(self.inner) }
162 self
163 }
164
165 #[inline]
192 fn register_hlsl_legalization_passes(&mut self) -> &mut Self {
193 unsafe { opt::optimizer_register_hlsl_legalization_passes(self.inner) }
194 self
195 }
196}
197
198impl Default for CompiledOptimizer {
199 fn default() -> Self {
200 Self::with_env(crate::TargetEnv::default())
201 }
202}
203
204impl Drop for CompiledOptimizer {
205 #[inline]
206 fn drop(&mut self) {
207 unsafe { opt::optimizer_destroy(self.inner) }
208 }
209}