oxicuda_driver/ffi_descriptors.rs
1//! Texture, array, and resource descriptor types for the CUDA Driver API.
2//!
3//! CUDA array handles, array/resource descriptors, texture descriptors,
4//! resource views, and related enums for texture object creation.
5
6use std::ffi::c_void;
7use std::fmt;
8
9use super::CUdeviceptr;
10
11// =========================================================================
12// CUarray / CUmipmappedArray — opaque CUDA array handles
13// =========================================================================
14
15/// Opaque handle to a CUDA array (1-D, 2-D, or 3-D texture memory).
16///
17/// Allocated by `cuArrayCreate_v2` / `cuArray3DCreate_v2` and freed by
18/// `cuArrayDestroy`. Arrays can be bound to texture objects via
19/// [`CUDA_RESOURCE_DESC`].
20#[repr(transparent)]
21#[derive(Clone, Copy, PartialEq, Eq, Hash)]
22pub struct CUarray(pub *mut c_void);
23
24// SAFETY: CUDA handles are thread-safe when used with proper
25// synchronisation via the driver API.
26unsafe impl Send for CUarray {}
27unsafe impl Sync for CUarray {}
28
29impl fmt::Debug for CUarray {
30 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31 write!(f, "CUarray({:p})", self.0)
32 }
33}
34
35impl Default for CUarray {
36 fn default() -> Self {
37 Self(std::ptr::null_mut())
38 }
39}
40
41impl CUarray {
42 /// Returns `true` if the handle is null (uninitialised).
43 #[inline]
44 pub fn is_null(self) -> bool {
45 self.0.is_null()
46 }
47}
48
49/// Opaque handle to a CUDA mipmapped array (Mip-mapped texture memory).
50///
51/// Allocated by `cuMipmappedArrayCreate` and freed by
52/// `cuMipmappedArrayDestroy`.
53#[repr(transparent)]
54#[derive(Clone, Copy, PartialEq, Eq, Hash)]
55pub struct CUmipmappedArray(pub *mut c_void);
56
57// SAFETY: CUDA handles are thread-safe when used with proper
58// synchronisation via the driver API.
59unsafe impl Send for CUmipmappedArray {}
60unsafe impl Sync for CUmipmappedArray {}
61
62impl fmt::Debug for CUmipmappedArray {
63 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64 write!(f, "CUmipmappedArray({:p})", self.0)
65 }
66}
67
68impl Default for CUmipmappedArray {
69 fn default() -> Self {
70 Self(std::ptr::null_mut())
71 }
72}
73
74impl CUmipmappedArray {
75 /// Returns `true` if the handle is null (uninitialised).
76 #[inline]
77 pub fn is_null(self) -> bool {
78 self.0.is_null()
79 }
80}
81
82// =========================================================================
83// CUarray_format — channel element format for CUDA arrays
84// =========================================================================
85
86/// Element format for CUDA arrays. Mirrors `CUarray_format_enum` in the
87/// CUDA driver API header.
88#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
89#[repr(u32)]
90#[non_exhaustive]
91#[allow(non_camel_case_types)]
92pub enum CUarray_format {
93 /// 8-bit unsigned integer channel.
94 UnsignedInt8 = 0x01,
95 /// 16-bit unsigned integer channel.
96 UnsignedInt16 = 0x02,
97 /// 32-bit unsigned integer channel.
98 UnsignedInt32 = 0x03,
99 /// 8-bit signed integer channel.
100 SignedInt8 = 0x08,
101 /// 16-bit signed integer channel.
102 SignedInt16 = 0x09,
103 /// 32-bit signed integer channel.
104 SignedInt32 = 0x0a,
105 /// 16-bit IEEE 754 half-precision float channel.
106 Half = 0x10,
107 /// 32-bit IEEE 754 single-precision float channel.
108 Float = 0x20,
109 /// NV12 planar YUV format (special 2-plane layout).
110 Nv12 = 0xb0,
111 /// 8-bit unsigned normalized integer (1 channel).
112 UnormInt8X1 = 0xc0,
113 /// 8-bit unsigned normalized integer (2 channels).
114 UnormInt8X2 = 0xc1,
115 /// 8-bit unsigned normalized integer (4 channels).
116 UnormInt8X4 = 0xc2,
117 /// 16-bit unsigned normalized integer (1 channel).
118 UnormInt16X1 = 0xc3,
119 /// 16-bit unsigned normalized integer (2 channels).
120 UnormInt16X2 = 0xc4,
121 /// 16-bit unsigned normalized integer (4 channels).
122 UnormInt16X4 = 0xc5,
123 /// 8-bit signed normalized integer (1 channel).
124 SnormInt8X1 = 0xc6,
125 /// 8-bit signed normalized integer (2 channels).
126 SnormInt8X2 = 0xc7,
127 /// 8-bit signed normalized integer (4 channels).
128 SnormInt8X4 = 0xc8,
129 /// 16-bit signed normalized integer (1 channel).
130 SnormInt16X1 = 0xc9,
131 /// 16-bit signed normalized integer (2 channels).
132 SnormInt16X2 = 0xca,
133 /// 16-bit signed normalized integer (4 channels).
134 SnormInt16X4 = 0xcb,
135 /// BC1 compressed (DXT1) unsigned.
136 Bc1Unorm = 0x91,
137 /// BC1 compressed (DXT1) unsigned, sRGB.
138 Bc1UnormSrgb = 0x92,
139 /// BC2 compressed (DXT3) unsigned.
140 Bc2Unorm = 0x93,
141 /// BC2 compressed (DXT3) unsigned, sRGB.
142 Bc2UnormSrgb = 0x94,
143 /// BC3 compressed (DXT5) unsigned.
144 Bc3Unorm = 0x95,
145 /// BC3 compressed (DXT5) unsigned, sRGB.
146 Bc3UnormSrgb = 0x96,
147 /// BC4 unsigned.
148 Bc4Unorm = 0x97,
149 /// BC4 signed.
150 Bc4Snorm = 0x98,
151 /// BC5 unsigned.
152 Bc5Unorm = 0x99,
153 /// BC5 signed.
154 Bc5Snorm = 0x9a,
155 /// BC6H unsigned 16-bit float.
156 Bc6hUf16 = 0x9b,
157 /// BC6H signed 16-bit float.
158 Bc6hSf16 = 0x9c,
159 /// BC7 unsigned.
160 Bc7Unorm = 0x9d,
161 /// BC7 unsigned, sRGB.
162 Bc7UnormSrgb = 0x9e,
163}
164
165// =========================================================================
166// CUresourcetype — resource type for texture/surface objects
167// =========================================================================
168
169/// Resource type discriminant for [`CUDA_RESOURCE_DESC`].
170#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
171#[repr(u32)]
172#[non_exhaustive]
173pub enum CUresourcetype {
174 /// CUDA array resource.
175 Array = 0x00,
176 /// CUDA mipmapped array resource.
177 MipmappedArray = 0x01,
178 /// Linear memory resource (1-D, no filtering beyond point).
179 Linear = 0x02,
180 /// Pitched 2-D linear memory resource.
181 Pitch2d = 0x03,
182}
183
184// =========================================================================
185// CUaddress_mode — texture coordinate wrapping mode
186// =========================================================================
187
188/// Texture coordinate address-wrap mode for [`CUDA_TEXTURE_DESC`].
189#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
190#[repr(u32)]
191#[allow(non_camel_case_types)]
192pub enum CUaddress_mode {
193 /// Wrap (tiles) — coordinates outside [0, dim) wrap around.
194 Wrap = 0,
195 /// Clamp — coordinates are clamped to [0, dim-1].
196 Clamp = 1,
197 /// Mirror — coordinates are mirrored across array boundaries.
198 Mirror = 2,
199 /// Border — out-of-range coordinates return the border color.
200 Border = 3,
201}
202
203// =========================================================================
204// CUfilter_mode — texture / mipmap filtering mode
205// =========================================================================
206
207/// Texture / mipmap sampling filter mode for [`CUDA_TEXTURE_DESC`].
208#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
209#[repr(u32)]
210#[allow(non_camel_case_types)]
211pub enum CUfilter_mode {
212 /// Nearest-neighbor (point) sampling.
213 Point = 0,
214 /// Bilinear (linear) filtering.
215 Linear = 1,
216}
217
218// =========================================================================
219// CUresourceViewFormat — re-interpretation format for resource views
220// =========================================================================
221
222/// Format used to re-interpret a CUDA array in a resource view.
223///
224/// Mirrors `CUresourceViewFormat_enum` in the CUDA driver API header.
225#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
226#[repr(u32)]
227#[non_exhaustive]
228pub enum CUresourceViewFormat {
229 /// No re-interpretation (use the array's own format).
230 None = 0x00,
231 /// Re-interpret as 1×8-bit unsigned integer.
232 Uint1x8 = 0x01,
233 /// Re-interpret as 2×8-bit unsigned integer.
234 Uint2x8 = 0x02,
235 /// Re-interpret as 4×8-bit unsigned integer.
236 Uint4x8 = 0x03,
237 /// Re-interpret as 1×8-bit signed integer.
238 Sint1x8 = 0x04,
239 /// Re-interpret as 2×8-bit signed integer.
240 Sint2x8 = 0x05,
241 /// Re-interpret as 4×8-bit signed integer.
242 Sint4x8 = 0x06,
243 /// Re-interpret as 1×16-bit unsigned integer.
244 Uint1x16 = 0x07,
245 /// Re-interpret as 2×16-bit unsigned integer.
246 Uint2x16 = 0x08,
247 /// Re-interpret as 4×16-bit unsigned integer.
248 Uint4x16 = 0x09,
249 /// Re-interpret as 1×16-bit signed integer.
250 Sint1x16 = 0x0a,
251 /// Re-interpret as 2×16-bit signed integer.
252 Sint2x16 = 0x0b,
253 /// Re-interpret as 4×16-bit signed integer.
254 Sint4x16 = 0x0c,
255 /// Re-interpret as 1×32-bit unsigned integer.
256 Uint1x32 = 0x0d,
257 /// Re-interpret as 2×32-bit unsigned integer.
258 Uint2x32 = 0x0e,
259 /// Re-interpret as 4×32-bit unsigned integer.
260 Uint4x32 = 0x0f,
261 /// Re-interpret as 1×32-bit signed integer.
262 Sint1x32 = 0x10,
263 /// Re-interpret as 2×32-bit signed integer.
264 Sint2x32 = 0x11,
265 /// Re-interpret as 4×32-bit signed integer.
266 Sint4x32 = 0x12,
267 /// Re-interpret as 1×16-bit float.
268 Float1x16 = 0x13,
269 /// Re-interpret as 2×16-bit float.
270 Float2x16 = 0x14,
271 /// Re-interpret as 4×16-bit float.
272 Float4x16 = 0x15,
273 /// Re-interpret as 1×32-bit float.
274 Float1x32 = 0x16,
275 /// Re-interpret as 2×32-bit float.
276 Float2x32 = 0x17,
277 /// Re-interpret as 4×32-bit float.
278 Float4x32 = 0x18,
279 /// BC1 unsigned normal compressed.
280 UnsignedBc1 = 0x19,
281 /// BC2 unsigned normal compressed.
282 UnsignedBc2 = 0x1a,
283 /// BC3 unsigned normal compressed.
284 UnsignedBc3 = 0x1b,
285 /// BC4 unsigned normal compressed.
286 UnsignedBc4 = 0x1c,
287 /// BC4 signed normal compressed.
288 SignedBc4 = 0x1d,
289 /// BC5 unsigned normal compressed.
290 UnsignedBc5 = 0x1e,
291 /// BC5 signed normal compressed.
292 SignedBc5 = 0x1f,
293 /// BC6H unsigned half-float.
294 UnsignedBc6h = 0x20,
295 /// BC6H signed half-float.
296 SignedBc6h = 0x21,
297 /// BC7 unsigned.
298 UnsignedBc7 = 0x22,
299 /// NV12 planar YUV.
300 Nv12 = 0x23,
301}
302
303// =========================================================================
304// CUDA_ARRAY_DESCRIPTOR — descriptor for 1-D and 2-D CUDA arrays
305// =========================================================================
306
307/// Descriptor passed to `cuArrayCreate_v2` / `cuArrayGetDescriptor_v2`.
308///
309/// Mirrors `CUDA_ARRAY_DESCRIPTOR_v2` in the CUDA driver API.
310#[derive(Debug, Clone, Copy, PartialEq, Eq)]
311#[repr(C)]
312pub struct CUDA_ARRAY_DESCRIPTOR {
313 /// Width of the array in elements.
314 pub width: usize,
315 /// Height of the array in elements (0 for 1-D arrays).
316 pub height: usize,
317 /// Element format (data type of each channel).
318 pub format: CUarray_format,
319 /// Number of channels (1, 2, or 4).
320 pub num_channels: u32,
321}
322
323// =========================================================================
324// CUDA_ARRAY3D_DESCRIPTOR — descriptor for 3-D CUDA arrays
325// =========================================================================
326
327/// Descriptor passed to `cuArray3DCreate_v2` / `cuArray3DGetDescriptor_v2`.
328///
329/// Mirrors `CUDA_ARRAY3D_DESCRIPTOR_v2` in the CUDA driver API. The `flags`
330/// field accepts constants such as `CUDA_ARRAY3D_LAYERED` (0x01),
331/// `CUDA_ARRAY3D_SURFACE_LDST` (0x02), `CUDA_ARRAY3D_CUBEMAP` (0x04), and
332/// `CUDA_ARRAY3D_TEXTURE_GATHER` (0x08).
333#[derive(Debug, Clone, Copy, PartialEq, Eq)]
334#[repr(C)]
335pub struct CUDA_ARRAY3D_DESCRIPTOR {
336 /// Width of the array in elements.
337 pub width: usize,
338 /// Height of the array in elements (0 for 1-D arrays).
339 pub height: usize,
340 /// Depth of the array in elements (0 for 1-D and 2-D arrays).
341 pub depth: usize,
342 /// Element format.
343 pub format: CUarray_format,
344 /// Number of channels (1, 2, or 4).
345 pub num_channels: u32,
346 /// Creation flags (see [`CUDA_ARRAY3D_LAYERED`] etc.).
347 pub flags: u32,
348}
349
350/// Flag: allocate a layered CUDA array (`CUDA_ARRAY3D_LAYERED`).
351pub const CUDA_ARRAY3D_LAYERED: u32 = 0x01;
352/// Flag: array usable as a surface load/store target (`CUDA_ARRAY3D_SURFACE_LDST`).
353pub const CUDA_ARRAY3D_SURFACE_LDST: u32 = 0x02;
354/// Flag: allocate a cubemap array (`CUDA_ARRAY3D_CUBEMAP`).
355pub const CUDA_ARRAY3D_CUBEMAP: u32 = 0x04;
356/// Flag: array usable with `cudaTextureGather` (`CUDA_ARRAY3D_TEXTURE_GATHER`).
357pub const CUDA_ARRAY3D_TEXTURE_GATHER: u32 = 0x08;
358
359// =========================================================================
360// CUDA_RESOURCE_DESC — resource descriptor union for tex/surf objects
361// =========================================================================
362
363/// Inner data for an `Array` resource (variant of [`CudaResourceDescRes`]).
364#[derive(Clone, Copy)]
365#[repr(C)]
366pub struct CudaResourceDescArray {
367 /// CUDA array handle.
368 pub h_array: CUarray,
369}
370
371/// Inner data for a `MipmappedArray` resource.
372#[derive(Clone, Copy)]
373#[repr(C)]
374pub struct CudaResourceDescMipmap {
375 /// Mipmapped array handle.
376 pub h_mipmapped_array: CUmipmappedArray,
377}
378
379/// Inner data for a `Linear` (1-D linear memory) resource.
380#[derive(Clone, Copy)]
381#[repr(C)]
382pub struct CudaResourceDescLinear {
383 /// Device pointer to the linear region.
384 pub dev_ptr: CUdeviceptr,
385 /// Channel element format.
386 pub format: CUarray_format,
387 /// Number of channels.
388 pub num_channels: u32,
389 /// Total size in bytes.
390 pub size_in_bytes: usize,
391}
392
393/// Inner data for a `Pitch2D` (2-D pitched linear memory) resource.
394#[derive(Clone, Copy)]
395#[repr(C)]
396pub struct CudaResourceDescPitch2d {
397 /// Device pointer to the pitched region (first row).
398 pub dev_ptr: CUdeviceptr,
399 /// Channel element format.
400 pub format: CUarray_format,
401 /// Number of channels.
402 pub num_channels: u32,
403 /// Width of the array in elements.
404 pub width_in_elements: usize,
405 /// Height of the array in elements.
406 pub height: usize,
407 /// Row pitch in bytes (stride between rows).
408 pub pitch_in_bytes: usize,
409}
410
411/// Union of resource descriptors for [`CUDA_RESOURCE_DESC`].
412///
413/// # Safety
414///
415/// Callers must only read the field whose discriminant matches the
416/// `res_type` field of the enclosing [`CUDA_RESOURCE_DESC`].
417#[repr(C)]
418pub union CudaResourceDescRes {
419 /// Array resource.
420 pub array: CudaResourceDescArray,
421 /// Mipmapped array resource.
422 pub mipmap: CudaResourceDescMipmap,
423 /// 1-D linear memory resource.
424 pub linear: CudaResourceDescLinear,
425 /// 2-D pitched linear memory resource.
426 pub pitch2d: CudaResourceDescPitch2d,
427 /// Padding: ensures the union is 128 bytes (32 × i32), matching the ABI.
428 pub reserved: [i32; 32],
429}
430
431/// Resource descriptor passed to `cuTexObjectCreate` / `cuSurfObjectCreate`.
432///
433/// Mirrors `CUDA_RESOURCE_DESC` in the CUDA driver API header.
434#[repr(C)]
435pub struct CUDA_RESOURCE_DESC {
436 /// Identifies which union field inside `res` is valid.
437 pub res_type: CUresourcetype,
438 /// Resource payload — interpret via `res_type`.
439 pub res: CudaResourceDescRes,
440 /// Reserved flags (must be zero).
441 pub flags: u32,
442}
443
444// =========================================================================
445// CUDA_TEXTURE_DESC — texture object sampling parameters
446// =========================================================================
447
448/// Texture object descriptor passed to `cuTexObjectCreate`.
449///
450/// Mirrors `CUDA_TEXTURE_DESC` in the CUDA driver API. All fields that the
451/// caller does not set explicitly should be zeroed.
452///
453/// # Layout
454///
455/// The struct is `#[repr(C)]` and contains 64 bytes of reserved padding so
456/// that it matches the binary ABI expected by the driver.
457#[derive(Clone, Copy)]
458#[repr(C)]
459pub struct CUDA_TEXTURE_DESC {
460 /// Address mode for each coordinate dimension (`[U, V, W]`).
461 pub address_mode: [CUaddress_mode; 3],
462 /// Texture filter mode (point or linear).
463 pub filter_mode: CUfilter_mode,
464 /// Flags: bit 0 = `CU_TRSF_READ_AS_INTEGER`, bit 1 = `CU_TRSF_NORMALIZED_COORDINATES`,
465 /// bit 2 = `CU_TRSF_SRGB`, bit 3 = `CU_TRSF_DISABLE_TRILINEAR_OPTIMIZATION`.
466 pub flags: u32,
467 /// Maximum anisotropy ratio (1–16; 1 disables anisotropy).
468 pub max_anisotropy: u32,
469 /// Mipmap filter mode.
470 pub mipmap_filter_mode: CUfilter_mode,
471 /// Mipmap level-of-detail bias.
472 pub mipmap_level_bias: f32,
473 /// Minimum mipmap LOD clamp value.
474 pub min_mipmap_level_clamp: f32,
475 /// Maximum mipmap LOD clamp value.
476 pub max_mipmap_level_clamp: f32,
477 /// Border color (RGBA, applied when address mode is `Border`).
478 pub border_color: [f32; 4],
479 /// Reserved: must be zero.
480 pub reserved: [i32; 12],
481}
482
483/// Flag: texture reads return raw integers (no type conversion).
484pub const CU_TRSF_READ_AS_INTEGER: u32 = 0x01;
485/// Flag: texture coordinates are normalized to [0, 1).
486pub const CU_TRSF_NORMALIZED_COORDINATES: u32 = 0x02;
487/// Flag: sRGB gamma encoding is applied during sampling.
488pub const CU_TRSF_SRGB: u32 = 0x10;
489/// Flag: disable hardware trilinear optimisation.
490pub const CU_TRSF_DISABLE_TRILINEAR_OPTIMIZATION: u32 = 0x20;
491
492// =========================================================================
493// CUDA_RESOURCE_VIEW_DESC — optional re-interpretation of array resources
494// =========================================================================
495
496/// Optional resource view descriptor for `cuTexObjectCreate`.
497///
498/// Allows the caller to specify a sub-region, a different channel
499/// interpretation format, or a mipmap range for a [`CUDA_RESOURCE_DESC`] that
500/// wraps a CUDA array. Pass a null pointer to `cuTexObjectCreate` to skip the
501/// view override.
502///
503/// Mirrors `CUDA_RESOURCE_VIEW_DESC` in the CUDA driver API.
504#[derive(Clone, Copy)]
505#[repr(C)]
506pub struct CUDA_RESOURCE_VIEW_DESC {
507 /// Format to use for the resource view (re-interpretation).
508 pub format: CUresourceViewFormat,
509 /// Width of the view in elements.
510 pub width: usize,
511 /// Height of the view in elements.
512 pub height: usize,
513 /// Depth of the view in elements.
514 pub depth: usize,
515 /// First mipmap level included in the view.
516 pub first_mipmap_level: u32,
517 /// Last mipmap level included in the view.
518 pub last_mipmap_level: u32,
519 /// First array layer in a layered resource.
520 pub first_layer: u32,
521 /// Last array layer in a layered resource.
522 pub last_layer: u32,
523 /// Reserved: must be zero.
524 pub reserved: [u32; 16],
525}