spirv_tools_sys/
shared.rs

1use std::fmt;
2
3/// Certain target environments impose additional restrictions on SPIR-V, so it's
4/// often necessary to specify which one applies. `Universal_*` implies an
5/// environment-agnostic SPIR-V.
6///
7/// When an API method needs to derive a SPIR-V version from a target environment
8/// the method will choose the highest version of SPIR-V supported by the target
9/// environment. Examples:
10///
11/// ```
12///    SPV_ENV_VULKAN_1_0           ->  SPIR-V 1.0
13///    SPV_ENV_VULKAN_1_1           ->  SPIR-V 1.3
14///    SPV_ENV_VULKAN_1_1_SPIRV_1_4 ->  SPIR-V 1.4
15///    SPV_ENV_VULKAN_1_2           ->  SPIR-V 1.5
16/// ```
17///
18/// Consult the description of API entry points for specific rules.
19#[derive(Copy, Clone, Debug, PartialEq)]
20#[repr(C)]
21#[allow(non_camel_case_types, clippy::upper_case_acronyms)]
22pub enum TargetEnv {
23    /// SPIR-V 1.0 latest revision, no other restrictions.
24    Universal_1_0,
25    /// Vulkan 1.0 latest revision.
26    Vulkan_1_0,
27    /// SPIR-V 1.1 latest revision, no other restrictions.
28    Universal_1_1,
29    /// OpenCL Full Profile 2.1 latest revision.
30    OpenCL_2_1,
31    /// OpenCL Full Profile 2.2 latest revision.
32    OpenCL_2_2,
33    /// OpenGL 4.0 plus GL_ARB_gl_spirv, latest revisions.
34    OpenGL_4_0,
35    /// OpenGL 4.1 plus GL_ARB_gl_spirv, latest revisions.
36    OpenGL_4_1,
37    /// OpenGL 4.2 plus GL_ARB_gl_spirv, latest revisions.
38    OpenGL_4_2,
39    /// OpenGL 4.3 plus GL_ARB_gl_spirv, latest revisions.
40    OpenGL_4_3,
41    /// OpenGL 4.5 plus GL_ARB_gl_spirv, latest revisions.
42    OpenGL_4_5,
43    /// SPIR-V 1.2, latest revision, no other restrictions.
44    Universal_1_2,
45    /// OpenCL Full Profile 1.2 plus cl_khr_il_program, latest revision.
46    OpenCL_1_2,
47    /// OpenCL Embedded Profile 1.2 plus cl_khr_il_program, latest revision.
48    OpenCLEmbedded_1_2,
49    /// OpenCL Full Profile 2.0 plus cl_khr_il_program, latest revision.
50    OpenCL_2_0,
51    /// OpenCL Embedded Profile 2.0 plus cl_khr_il_program, latest revision.
52    OpenCLEmbedded_2_0,
53    /// OpenCL Embedded Profile 2.1 latest revision.
54    OpenCLEmbedded_2_1,
55    /// OpenCL Embedded Profile 2.2 latest revision.
56    OpenCLEmbedded_2_2,
57    /// SPIR-V 1.3 latest revision, no other restrictions.
58    Universal_1_3,
59    /// Vulkan 1.1 latest revision.
60    Vulkan_1_1,
61    /// Work in progress WebGPU 1.0.
62    WebGPU_0,
63    /// SPIR-V 1.4 latest revision, no other restrictions.
64    Universal_1_4,
65    /// Vulkan 1.1 with VK_KHR_spirv_1_4, i.e. SPIR-V 1.4 binary.
66    Vulkan_1_1_Spirv_1_4,
67    /// SPIR-V 1.5 latest revision, no other restrictions.
68    Universal_1_5,
69    /// Vulkan 1.2 latest revision.
70    Vulkan_1_2,
71}
72
73impl Default for TargetEnv {
74    fn default() -> Self {
75        // This is the default target environment for (AFAICT) all spirv-tools
76        Self::Universal_1_5
77    }
78}
79
80impl std::str::FromStr for TargetEnv {
81    type Err = SpirvResult;
82
83    fn from_str(s: &str) -> Result<Self, Self::Err> {
84        Ok(match s {
85            "vulkan1.1spv1.4" => Self::Vulkan_1_1_Spirv_1_4,
86            "vulkan1.0" => Self::Vulkan_1_0,
87            "vulkan1.1" => Self::Vulkan_1_1,
88            "vulkan1.2" => Self::Vulkan_1_2,
89            "spv1.0" => Self::Universal_1_0,
90            "spv1.1" => Self::Universal_1_1,
91            "spv1.2" => Self::Universal_1_2,
92            "spv1.3" => Self::Universal_1_3,
93            "spv1.4" => Self::Universal_1_4,
94            "spv1.5" => Self::Universal_1_5,
95            "opencl1.2embedded" => Self::OpenCLEmbedded_1_2,
96            "opencl1.2" => Self::OpenCL_1_2,
97            "opencl2.0embedded" => Self::OpenCLEmbedded_2_0,
98            "opencl2.0" => Self::OpenCL_2_0,
99            "opencl2.1embedded" => Self::OpenCLEmbedded_2_1,
100            "opencl2.1" => Self::OpenCL_2_1,
101            "opencl2.2embedded" => Self::OpenCLEmbedded_2_2,
102            "opencl2.2" => Self::OpenCL_2_2,
103            "opengl4.0" => Self::OpenGL_4_0,
104            "opengl4.1" => Self::OpenGL_4_1,
105            "opengl4.2" => Self::OpenGL_4_2,
106            "opengl4.3" => Self::OpenGL_4_3,
107            "opengl4.5" => Self::OpenGL_4_5,
108            "webgpu0" => Self::WebGPU_0,
109            _ => return Err(SpirvResult::InvalidValue),
110        })
111    }
112}
113
114impl fmt::Display for TargetEnv {
115    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
116        f.write_str(match self {
117            Self::Vulkan_1_1_Spirv_1_4 => "vulkan1.1spv1.4",
118            Self::Vulkan_1_0 => "vulkan1.0",
119            Self::Vulkan_1_1 => "vulkan1.1",
120            Self::Vulkan_1_2 => "vulkan1.2",
121            Self::Universal_1_0 => "spv1.0",
122            Self::Universal_1_1 => "spv1.1",
123            Self::Universal_1_2 => "spv1.2",
124            Self::Universal_1_3 => "spv1.3",
125            Self::Universal_1_4 => "spv1.4",
126            Self::Universal_1_5 => "spv1.5",
127            Self::OpenCLEmbedded_1_2 => "opencl1.2embedded",
128            Self::OpenCL_1_2 => "opencl1.2",
129            Self::OpenCLEmbedded_2_0 => "opencl2.0embedded",
130            Self::OpenCL_2_0 => "opencl2.0",
131            Self::OpenCLEmbedded_2_1 => "opencl2.1embedded",
132            Self::OpenCL_2_1 => "opencl2.1",
133            Self::OpenCLEmbedded_2_2 => "opencl2.2embedded",
134            Self::OpenCL_2_2 => "opencl2.2",
135            Self::OpenGL_4_0 => "opengl4.0",
136            Self::OpenGL_4_1 => "opengl4.1",
137            Self::OpenGL_4_2 => "opengl4.2",
138            Self::OpenGL_4_3 => "opengl4.3",
139            Self::OpenGL_4_5 => "opengl4.5",
140            Self::WebGPU_0 => "webgpu0",
141        })
142    }
143}
144
145#[derive(Copy, Clone, Debug, PartialEq)]
146#[repr(i32)] // SPV_FORCE_32_BIT_ENUM
147pub enum SpirvResult {
148    Success = 0,
149    Unsupported = 1,
150    EndOfStream = 2,
151    Warning = 3,
152    FailedMatch = 4,
153    /// Success, but signals early termination.
154    RequestedTermination = 5,
155    InternalError = -1,
156    OutOfMemory = -2,
157    InvalidPointer = -3,
158    InvalidBinary = -4,
159    InvalidText = -5,
160    InvalidTable = -6,
161    InvalidValue = -7,
162    InvalidDiagnostic = -8,
163    InvalidLookup = -9,
164    InvalidId = -10,
165    InvalidCfg = -11,
166    InvalidLayout = -12,
167    InvalidCapability = -13,
168    /// Indicates data rules validation failure.
169    InvalidData = -14,
170    MissingExtension = -15,
171    /// Indicates wrong SPIR-V version
172    WrongVersion = -16,
173}
174
175impl fmt::Display for SpirvResult {
176    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
177        #[allow(clippy::enum_glob_use)]
178        use SpirvResult::*;
179
180        match self {
181            Success => f.write_str("success"),
182            Unsupported => f.write_str("unsupported"),
183            EndOfStream => f.write_str("end of stream"),
184            Warning => f.write_str("warning"),
185            FailedMatch => f.write_str("failed match"),
186            RequestedTermination => f.write_str("requested termination"),
187            InternalError => f.write_str("internal error"),
188            OutOfMemory => f.write_str("out of memory"),
189            InvalidPointer => f.write_str("invalid pointer"),
190            InvalidBinary => f.write_str("invalid binary"),
191            InvalidText => f.write_str("invalid text"),
192            InvalidTable => f.write_str("invalid table"),
193            InvalidValue => f.write_str("invalid value"),
194            InvalidDiagnostic => f.write_str("invalid diagnostic"),
195            InvalidLookup => f.write_str("invalid lookup"),
196            InvalidId => f.write_str("invalid id"),
197            InvalidCfg => f.write_str("invalid cfg"),
198            InvalidLayout => f.write_str("invalid layout"),
199            InvalidCapability => f.write_str("invalid capability"),
200            InvalidData => f.write_str("invalid data"),
201            MissingExtension => f.write_str("missing extension"),
202            WrongVersion => f.write_str("wrong SPIR-V version"),
203        }
204    }
205}
206
207impl std::error::Error for SpirvResult {}
208
209#[repr(C)]
210pub struct Binary {
211    pub code: *const u32,
212    pub size: usize,
213}
214
215#[repr(C)]
216pub struct ToolContext {
217    _unused: [u8; 0],
218}
219
220extern "C" {
221    /// Creates a context object for most of the SPIRV-Tools API.
222    /// Returns null if env is invalid.
223    ///
224    /// See specific API calls for how the target environment is interpeted
225    /// (particularly assembly and validation).
226    #[link_name = "spvContextCreate"]
227    pub fn context_create(env: TargetEnv) -> *mut ToolContext;
228    /// Destroys the given context object.
229    #[link_name = "spvContextDestroy"]
230    pub fn context_destroy(opt: *mut ToolContext);
231
232    /// Frees a binary stream from memory. This is a no-op if binary is a null
233    /// pointer.
234    #[link_name = "spvBinaryDestroy"]
235    pub fn binary_destroy(binary: *mut Binary);
236}