Skip to main content

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}