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