1use std::fmt;
2
3#[derive(Copy, Clone, Debug, PartialEq)]
20#[repr(C)]
21#[allow(non_camel_case_types, clippy::upper_case_acronyms)]
22pub enum TargetEnv {
23 Universal_1_0,
25 Vulkan_1_0,
27 Universal_1_1,
29 OpenCL_2_1,
31 OpenCL_2_2,
33 OpenGL_4_0,
35 OpenGL_4_1,
37 OpenGL_4_2,
39 OpenGL_4_3,
41 OpenGL_4_5,
43 Universal_1_2,
45 OpenCL_1_2,
47 OpenCLEmbedded_1_2,
49 OpenCL_2_0,
51 OpenCLEmbedded_2_0,
53 OpenCLEmbedded_2_1,
55 OpenCLEmbedded_2_2,
57 Universal_1_3,
59 Vulkan_1_1,
61 WebGPU_0,
63 Universal_1_4,
65 Vulkan_1_1_Spirv_1_4,
67 Universal_1_5,
69 Vulkan_1_2,
71 Universal_1_6,
73 Vulkan_1_3,
75 Vulkan_1_4,
77}
78
79impl TargetEnv {
80 pub fn spirv_version(&self) -> (u8, u8) {
85 #[allow(clippy::match_same_arms)]
86 match self {
87 TargetEnv::Universal_1_0 => (1, 0),
88 TargetEnv::Universal_1_1 => (1, 1),
89 TargetEnv::Universal_1_2 => (1, 2),
90 TargetEnv::Universal_1_3 => (1, 3),
91 TargetEnv::Universal_1_4 => (1, 4),
92 TargetEnv::Universal_1_5 => (1, 5),
93 TargetEnv::Universal_1_6 => (1, 6),
94
95 TargetEnv::OpenGL_4_0 => (1, 0),
96 TargetEnv::OpenGL_4_1 => (1, 0),
97 TargetEnv::OpenGL_4_2 => (1, 0),
98 TargetEnv::OpenGL_4_3 => (1, 0),
99 TargetEnv::OpenGL_4_5 => (1, 0),
100
101 TargetEnv::OpenCL_1_2 => (1, 0),
102 TargetEnv::OpenCL_2_0 => (1, 0),
103 TargetEnv::OpenCL_2_1 => (1, 0),
104 TargetEnv::OpenCL_2_2 => (1, 2),
105 TargetEnv::OpenCLEmbedded_1_2 => (1, 0),
106 TargetEnv::OpenCLEmbedded_2_0 => (1, 0),
107 TargetEnv::OpenCLEmbedded_2_1 => (1, 0),
108 TargetEnv::OpenCLEmbedded_2_2 => (1, 2),
109
110 TargetEnv::Vulkan_1_0 => (1, 0),
111 TargetEnv::Vulkan_1_1 => (1, 3),
112 TargetEnv::WebGPU_0 => (1, 3),
113 TargetEnv::Vulkan_1_1_Spirv_1_4 => (1, 4),
114 TargetEnv::Vulkan_1_2 => (1, 5),
115 TargetEnv::Vulkan_1_3 => (1, 6),
116 TargetEnv::Vulkan_1_4 => (1, 6),
117 }
118 }
119}
120
121impl Default for TargetEnv {
122 fn default() -> Self {
123 Self::Universal_1_5
125 }
126}
127
128impl std::str::FromStr for TargetEnv {
129 type Err = SpirvResult;
130
131 fn from_str(s: &str) -> Result<Self, Self::Err> {
132 Ok(match s {
133 "vulkan1.1spv1.4" => Self::Vulkan_1_1_Spirv_1_4,
134 "vulkan1.0" => Self::Vulkan_1_0,
135 "vulkan1.1" => Self::Vulkan_1_1,
136 "vulkan1.2" => Self::Vulkan_1_2,
137 "vulkan1.3" => Self::Vulkan_1_3,
138 "vulkan1.4" => Self::Vulkan_1_4,
139 "spv1.0" => Self::Universal_1_0,
140 "spv1.1" => Self::Universal_1_1,
141 "spv1.2" => Self::Universal_1_2,
142 "spv1.3" => Self::Universal_1_3,
143 "spv1.4" => Self::Universal_1_4,
144 "spv1.5" => Self::Universal_1_5,
145 "spv1.6" => Self::Universal_1_6,
146 "opencl1.2embedded" => Self::OpenCLEmbedded_1_2,
147 "opencl1.2" => Self::OpenCL_1_2,
148 "opencl2.0embedded" => Self::OpenCLEmbedded_2_0,
149 "opencl2.0" => Self::OpenCL_2_0,
150 "opencl2.1embedded" => Self::OpenCLEmbedded_2_1,
151 "opencl2.1" => Self::OpenCL_2_1,
152 "opencl2.2embedded" => Self::OpenCLEmbedded_2_2,
153 "opencl2.2" => Self::OpenCL_2_2,
154 "opengl4.0" => Self::OpenGL_4_0,
155 "opengl4.1" => Self::OpenGL_4_1,
156 "opengl4.2" => Self::OpenGL_4_2,
157 "opengl4.3" => Self::OpenGL_4_3,
158 "opengl4.5" => Self::OpenGL_4_5,
159 "webgpu0" => Self::WebGPU_0,
160 _ => return Err(SpirvResult::InvalidValue),
161 })
162 }
163}
164
165impl fmt::Display for TargetEnv {
166 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
167 f.write_str(match self {
168 Self::Vulkan_1_1_Spirv_1_4 => "vulkan1.1spv1.4",
169 Self::Vulkan_1_0 => "vulkan1.0",
170 Self::Vulkan_1_1 => "vulkan1.1",
171 Self::Vulkan_1_2 => "vulkan1.2",
172 Self::Vulkan_1_3 => "vulkan1.3",
173 Self::Vulkan_1_4 => "vulkan1.4",
174 Self::Universal_1_0 => "spv1.0",
175 Self::Universal_1_1 => "spv1.1",
176 Self::Universal_1_2 => "spv1.2",
177 Self::Universal_1_3 => "spv1.3",
178 Self::Universal_1_4 => "spv1.4",
179 Self::Universal_1_5 => "spv1.5",
180 Self::Universal_1_6 => "spv1.6",
181 Self::OpenCLEmbedded_1_2 => "opencl1.2embedded",
182 Self::OpenCL_1_2 => "opencl1.2",
183 Self::OpenCLEmbedded_2_0 => "opencl2.0embedded",
184 Self::OpenCL_2_0 => "opencl2.0",
185 Self::OpenCLEmbedded_2_1 => "opencl2.1embedded",
186 Self::OpenCL_2_1 => "opencl2.1",
187 Self::OpenCLEmbedded_2_2 => "opencl2.2embedded",
188 Self::OpenCL_2_2 => "opencl2.2",
189 Self::OpenGL_4_0 => "opengl4.0",
190 Self::OpenGL_4_1 => "opengl4.1",
191 Self::OpenGL_4_2 => "opengl4.2",
192 Self::OpenGL_4_3 => "opengl4.3",
193 Self::OpenGL_4_5 => "opengl4.5",
194 Self::WebGPU_0 => "webgpu0",
195 })
196 }
197}
198
199#[derive(Copy, Clone, Debug, PartialEq)]
200#[repr(i32)] pub enum SpirvResult {
202 Success = 0,
203 Unsupported = 1,
204 EndOfStream = 2,
205 Warning = 3,
206 FailedMatch = 4,
207 RequestedTermination = 5,
209 InternalError = -1,
210 OutOfMemory = -2,
211 InvalidPointer = -3,
212 InvalidBinary = -4,
213 InvalidText = -5,
214 InvalidTable = -6,
215 InvalidValue = -7,
216 InvalidDiagnostic = -8,
217 InvalidLookup = -9,
218 InvalidId = -10,
219 InvalidCfg = -11,
220 InvalidLayout = -12,
221 InvalidCapability = -13,
222 InvalidData = -14,
224 MissingExtension = -15,
225 WrongVersion = -16,
227}
228
229impl fmt::Display for SpirvResult {
230 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
231 #[allow(clippy::enum_glob_use)]
232 use SpirvResult::*;
233
234 match self {
235 Success => f.write_str("success"),
236 Unsupported => f.write_str("unsupported"),
237 EndOfStream => f.write_str("end of stream"),
238 Warning => f.write_str("warning"),
239 FailedMatch => f.write_str("failed match"),
240 RequestedTermination => f.write_str("requested termination"),
241 InternalError => f.write_str("internal error"),
242 OutOfMemory => f.write_str("out of memory"),
243 InvalidPointer => f.write_str("invalid pointer"),
244 InvalidBinary => f.write_str("invalid binary"),
245 InvalidText => f.write_str("invalid text"),
246 InvalidTable => f.write_str("invalid table"),
247 InvalidValue => f.write_str("invalid value"),
248 InvalidDiagnostic => f.write_str("invalid diagnostic"),
249 InvalidLookup => f.write_str("invalid lookup"),
250 InvalidId => f.write_str("invalid id"),
251 InvalidCfg => f.write_str("invalid cfg"),
252 InvalidLayout => f.write_str("invalid layout"),
253 InvalidCapability => f.write_str("invalid capability"),
254 InvalidData => f.write_str("invalid data"),
255 MissingExtension => f.write_str("missing extension"),
256 WrongVersion => f.write_str("wrong SPIR-V version"),
257 }
258 }
259}
260
261impl std::error::Error for SpirvResult {}
262
263#[repr(C)]
264pub struct Binary {
265 pub code: *const u32,
266 pub size: usize,
267}
268
269#[repr(C)]
270pub struct ToolContext {
271 _unused: [u8; 0],
272}
273
274extern "C" {
275 #[link_name = "spvContextCreate"]
281 pub fn context_create(env: TargetEnv) -> *mut ToolContext;
282 #[link_name = "spvContextDestroy"]
284 pub fn context_destroy(opt: *mut ToolContext);
285
286 #[link_name = "spvBinaryDestroy"]
289 pub fn binary_destroy(binary: *mut Binary);
290}