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