1#![allow(deprecated)]
16#![allow(clippy::missing_safety_doc)]
17
18use core::marker::PhantomData;
19
20pub use cl3::memory::*;
21
22use super::context::Context;
23
24use super::Result;
25#[cfg(any(feature = "cl_intel_dx9_media_sharing", feature = "dynamic"))]
26#[allow(unused_imports)]
27use cl3::dx9_media_sharing;
28#[allow(unused_imports)]
29use cl3::egl;
30#[allow(unused_imports)]
31use cl3::ext;
32use cl3::gl;
33use cl3::memory;
34use cl3::sampler;
35
36#[allow(unused_imports)]
37use cl3::types::{
38 cl_addressing_mode, cl_bool, cl_filter_mode, cl_sampler, cl_sampler_info, cl_sampler_properties,
39};
40
41use libc::{c_void, intptr_t, size_t};
42use std::mem;
43
44pub trait ClMem {
45 fn get(&self) -> cl_mem;
46
47 fn get_mut(&mut self) -> cl_mem;
48
49 fn mem_type(&self) -> Result<cl_mem_object_type> {
50 Ok(memory::get_mem_object_info(self.get(), CL_MEM_TYPE)?.into())
51 }
52
53 fn flags(&self) -> Result<cl_mem_flags> {
54 Ok(memory::get_mem_object_info(self.get(), CL_MEM_FLAGS)?.into())
55 }
56
57 fn size(&self) -> Result<size_t> {
58 Ok(memory::get_mem_object_info(self.get(), CL_MEM_SIZE)?.into())
59 }
60
61 fn host_ptr(&self) -> Result<intptr_t> {
62 Ok(memory::get_mem_object_info(self.get(), CL_MEM_HOST_PTR)?.into())
63 }
64
65 fn map_count(&self) -> Result<cl_uint> {
66 Ok(memory::get_mem_object_info(self.get(), CL_MEM_MAP_COUNT)?.into())
67 }
68
69 fn reference_count(&self) -> Result<cl_uint> {
70 Ok(memory::get_mem_object_info(self.get(), CL_MEM_REFERENCE_COUNT)?.into())
71 }
72
73 fn context(&self) -> Result<cl_context> {
74 Ok(intptr_t::from(memory::get_mem_object_info(self.get(), CL_MEM_CONTEXT)?) as cl_context)
75 }
76
77 fn associated_memobject(&self) -> Result<cl_mem> {
78 Ok(intptr_t::from(memory::get_mem_object_info(
79 self.get(),
80 CL_MEM_ASSOCIATED_MEMOBJECT,
81 )?) as cl_mem)
82 }
83
84 fn offset(&self) -> Result<size_t> {
85 Ok(memory::get_mem_object_info(self.get(), CL_MEM_OFFSET)?.into())
86 }
87
88 fn uses_svm_pointer(&self) -> Result<cl_uint> {
89 Ok(memory::get_mem_object_info(self.get(), CL_MEM_USES_SVM_POINTER)?.into())
90 }
91
92 fn properties(&self) -> Result<Vec<cl_ulong>> {
94 Ok(memory::get_mem_object_info(self.get(), CL_MEM_PROPERTIES)?.into())
95 }
96
97 fn get_mem_data(&self, param_name: cl_mem_info) -> Result<Vec<u8>> {
100 Ok(get_mem_object_data(self.get(), param_name)?)
101 }
102
103 fn gl_object_info(&self) -> Result<(gl::cl_GLuint, gl::cl_GLuint)> {
108 Ok(gl::get_gl_object_info(self.get())?)
109 }
110}
111
112#[derive(Debug)]
116pub struct Buffer<T> {
117 buffer: cl_mem,
118 #[doc(hidden)]
119 _type: PhantomData<T>,
120}
121
122impl<T> From<Buffer<T>> for cl_mem {
123 fn from(value: Buffer<T>) -> Self {
124 value.buffer
125 }
126}
127
128impl<T> ClMem for Buffer<T> {
129 fn get(&self) -> cl_mem {
130 self.buffer
131 }
132
133 fn get_mut(&mut self) -> cl_mem {
134 self.buffer
135 }
136}
137
138impl<T> Drop for Buffer<T> {
139 fn drop(&mut self) {
140 unsafe { memory::release_mem_object(self.get()).expect("Error: clReleaseMemObject") };
141 }
142}
143
144unsafe impl<T: Send> Send for Buffer<T> {}
145unsafe impl<T: Sync> Sync for Buffer<T> {}
146
147impl<T> Buffer<T> {
148 pub const fn new(buffer: cl_mem) -> Self {
149 Self {
150 buffer,
151 _type: PhantomData,
152 }
153 }
154
155 pub unsafe fn create(
168 context: &Context,
169 flags: cl_mem_flags,
170 count: size_t,
171 host_ptr: *mut c_void,
172 ) -> Result<Self> {
173 unsafe {
174 let buffer =
175 memory::create_buffer(context.get(), flags, count * mem::size_of::<T>(), host_ptr)?;
176 Ok(Self::new(buffer))
177 }
178 }
179
180 #[cfg(any(feature = "CL_VERSION_3_0", feature = "dynamic"))]
196 pub unsafe fn create_with_properties(
197 context: &Context,
198 properties: *const cl_mem_properties,
199 flags: cl_mem_flags,
200 count: size_t,
201 host_ptr: *mut c_void,
202 ) -> Result<Self> {
203 unsafe {
204 let buffer = memory::create_buffer_with_properties(
205 context.get(),
206 properties,
207 flags,
208 count * mem::size_of::<T>(),
209 host_ptr,
210 )?;
211 Ok(Self::new(buffer))
212 }
213 }
214
215 pub unsafe fn create_from_gl_buffer(
226 context: &Context,
227 flags: cl_mem_flags,
228 bufobj: gl::cl_GLuint,
229 ) -> Result<Self> {
230 unsafe {
231 let buffer = gl::create_from_gl_buffer(context.get(), flags, bufobj)?;
232 Ok(Self::new(buffer))
233 }
234 }
235
236 #[cfg(any(
237 feature = "cl_intel_create_buffer_with_properties",
238 feature = "dynamic"
239 ))]
240 pub unsafe fn create_with_properties_intel(
241 context: &Context,
242 properties: *const ext::cl_mem_properties_intel,
243 flags: cl_mem_flags,
244 count: size_t,
245 host_ptr: *mut c_void,
246 ) -> Result<Self> {
247 unsafe {
248 let buffer = ext::create_buffer_with_properties_intel(
249 context.get(),
250 properties,
251 flags,
252 count * mem::size_of::<T>(),
253 host_ptr,
254 )?;
255 Ok(Self::new(buffer))
256 }
257 }
258
259 pub unsafe fn create_sub_buffer(
272 &self,
273 flags: cl_mem_flags,
274 origin: usize,
275 count: usize,
276 ) -> Result<Self> {
277 unsafe {
278 let buffer_create_info = cl_buffer_region {
279 origin: origin * std::mem::size_of::<T>(),
280 size: count * std::mem::size_of::<T>(),
281 };
282 let buffer = memory::create_sub_buffer(
283 self.buffer,
284 flags,
285 CL_BUFFER_CREATE_TYPE_REGION,
286 &buffer_create_info as *const _ as *const c_void,
287 )?;
288 Ok(Self::new(buffer))
289 }
290 }
291}
292
293#[derive(Debug)]
299pub struct Image {
300 image: cl_mem,
301}
302
303impl From<Image> for cl_mem {
304 fn from(value: Image) -> Self {
305 value.image
306 }
307}
308
309impl ClMem for Image {
310 fn get(&self) -> cl_mem {
311 self.image
312 }
313
314 fn get_mut(&mut self) -> cl_mem {
315 self.image
316 }
317}
318
319impl Drop for Image {
320 fn drop(&mut self) {
321 unsafe { memory::release_mem_object(self.get()).expect("Error: clReleaseMemObject") };
322 }
323}
324
325unsafe impl Send for Image {}
326
327impl Image {
328 pub const fn new(image: cl_mem) -> Self {
329 Self { image }
330 }
331
332 #[cfg(any(feature = "CL_VERSION_1_2", feature = "dynamic"))]
348 pub unsafe fn create(
349 context: &Context,
350 flags: cl_mem_flags,
351 image_format: *const cl_image_format,
352 image_desc: *const cl_image_desc,
353 host_ptr: *mut c_void,
354 ) -> Result<Self> {
355 unsafe {
356 let image =
357 memory::create_image(context.get(), flags, image_format, image_desc, host_ptr)?;
358 Ok(Self::new(image))
359 }
360 }
361
362 #[cfg(any(feature = "CL_VERSION_3_0", feature = "dynamic"))]
381 pub unsafe fn create_with_properties(
382 context: &Context,
383 properties: *const cl_mem_properties,
384 flags: cl_mem_flags,
385 image_format: *const cl_image_format,
386 image_desc: *const cl_image_desc,
387 host_ptr: *mut c_void,
388 ) -> Result<Self> {
389 unsafe {
390 let image = memory::create_image_with_properties(
391 context.get(),
392 properties,
393 flags,
394 image_format,
395 image_desc,
396 host_ptr,
397 )?;
398 Ok(Self::new(image))
399 }
400 }
401
402 pub unsafe fn create_from_gl_texture(
419 context: &Context,
420 flags: cl_mem_flags,
421 texture_target: gl::cl_GLenum,
422 miplevel: gl::cl_GLint,
423 texture: gl::cl_GLuint,
424 ) -> Result<Self> {
425 unsafe {
426 let image = gl::create_from_gl_texture(
427 context.get(),
428 flags,
429 texture_target,
430 miplevel,
431 texture,
432 )?;
433 Ok(Self::new(image))
434 }
435 }
436
437 pub unsafe fn create_from_gl_render_buffer(
448 context: &Context,
449 flags: cl_mem_flags,
450 renderbuffer: gl::cl_GLuint,
451 ) -> Result<Self> {
452 unsafe {
453 let image = gl::create_from_gl_render_buffer(context.get(), flags, renderbuffer)?;
454 Ok(Self::new(image))
455 }
456 }
457
458 #[cfg(any(feature = "cl_khr_egl_image", feature = "dynamic"))]
471 #[inline]
472 pub unsafe fn create_from_egl_image(
473 context: &Context,
474 display: egl::CLeglDisplayKHR,
475 image: egl::CLeglImageKHR,
476 flags: cl_mem_flags,
477 properties: &[egl::cl_egl_image_properties_khr],
478 ) -> Result<Self> {
479 unsafe {
480 let image = egl::create_from_egl_image(
481 context.get(),
482 display,
483 image,
484 flags,
485 properties.as_ptr(),
486 )?;
487 Ok(Self::new(image))
488 }
489 }
490
491 #[cfg(any(feature = "cl_intel_dx9_media_sharing", feature = "dynamic"))]
492 #[inline]
493 pub unsafe fn create_from_dx9_media_surface_intel(
494 context: &Context,
495 flags: cl_mem_flags,
496 resource: dx9_media_sharing::IDirect3DSurface9_ptr,
497 shared_handle: dx9_media_sharing::HANDLE,
498 plane: cl_uint,
499 ) -> Result<Self> {
500 unsafe {
501 let image = dx9_media_sharing::create_from_dx9_media_surface_intel(
502 context.get(),
503 flags,
504 resource,
505 shared_handle,
506 plane,
507 )?;
508 Ok(Self::new(image))
509 }
510 }
511
512 pub fn format(&self) -> Result<Vec<cl_image_format>> {
513 Ok(memory::get_image_info(self.image, CL_IMAGE_FORMAT)?.into())
514 }
515
516 pub fn element_size(&self) -> Result<size_t> {
517 Ok(memory::get_image_info(self.image, CL_IMAGE_ELEMENT_SIZE)?.into())
518 }
519
520 pub fn row_pitch(&self) -> Result<size_t> {
521 Ok(memory::get_image_info(self.image, CL_IMAGE_ROW_PITCH)?.into())
522 }
523
524 pub fn slice_pitch(&self) -> Result<size_t> {
525 Ok(memory::get_image_info(self.image, CL_IMAGE_SLICE_PITCH)?.into())
526 }
527
528 pub fn width(&self) -> Result<size_t> {
529 Ok(memory::get_image_info(self.image, CL_IMAGE_WIDTH)?.into())
530 }
531
532 pub fn height(&self) -> Result<size_t> {
533 Ok(memory::get_image_info(self.image, CL_IMAGE_HEIGHT)?.into())
534 }
535
536 pub fn depth(&self) -> Result<size_t> {
537 Ok(memory::get_image_info(self.image, CL_IMAGE_DEPTH)?.into())
538 }
539 pub fn array_size(&self) -> Result<size_t> {
540 Ok(memory::get_image_info(self.image, CL_IMAGE_ARRAY_SIZE)?.into())
541 }
542
543 pub fn buffer(&self) -> Result<cl_mem> {
544 Ok(intptr_t::from(memory::get_image_info(self.image, CL_IMAGE_BUFFER)?) as cl_mem)
545 }
546
547 pub fn num_mip_levels(&self) -> Result<cl_uint> {
548 Ok(memory::get_image_info(self.image, CL_IMAGE_NUM_MIP_LEVELS)?.into())
549 }
550
551 pub fn num_samples(&self) -> Result<cl_uint> {
552 Ok(memory::get_image_info(self.image, CL_IMAGE_NUM_SAMPLES)?.into())
553 }
554
555 pub fn get_data(&self, param_name: cl_image_info) -> Result<Vec<u8>> {
558 Ok(get_image_data(self.image, param_name)?)
559 }
560
561 pub fn gl_texture_target(&self) -> Result<cl_uint> {
563 Ok(gl::get_gl_texture_info(self.image, gl::CL_GL_TEXTURE_TARGET)?.into())
564 }
565
566 pub fn gl_mipmap_level(&self) -> Result<cl_int> {
568 Ok(gl::get_gl_texture_info(self.image, gl::CL_GL_MIPMAP_LEVEL)?.into())
569 }
570
571 pub fn gl_num_samples(&self) -> Result<cl_int> {
573 Ok(gl::get_gl_texture_info(self.image, gl::CL_GL_NUM_SAMPLES)?.into())
574 }
575
576 pub fn get_gl_texture_data(&self, param_name: gl::cl_gl_texture_info) -> Result<Vec<u8>> {
578 Ok(gl::get_gl_texture_data(self.image, param_name)?)
579 }
580}
581
582#[derive(Debug)]
587pub struct Sampler {
588 sampler: cl_sampler,
589}
590
591impl From<Sampler> for cl_sampler {
592 fn from(value: Sampler) -> Self {
593 value.sampler
594 }
595}
596
597impl Drop for Sampler {
598 fn drop(&mut self) {
599 unsafe { sampler::release_sampler(self.sampler).expect("Error: clReleaseSampler") };
600 }
601}
602
603unsafe impl Send for Sampler {}
604
605impl Sampler {
606 pub const fn new(sampler: cl_sampler) -> Self {
607 Self { sampler }
608 }
609
610 #[cfg_attr(
611 any(
612 feature = "CL_VERSION_2_0",
613 feature = "CL_VERSION_2_1",
614 feature = "CL_VERSION_2_2",
615 feature = "CL_VERSION_3_0"
616 ),
617 deprecated(
618 since = "0.1.0",
619 note = "From CL_VERSION_2_0 use create_sampler_with_properties"
620 )
621 )]
622 pub fn create(
623 context: &Context,
624 normalize_coords: cl_bool,
625 addressing_mode: cl_addressing_mode,
626 filter_mode: cl_filter_mode,
627 ) -> Result<Self> {
628 let sampler = sampler::create_sampler(
629 context.get(),
630 normalize_coords,
631 addressing_mode,
632 filter_mode,
633 )?;
634 Ok(Self::new(sampler))
635 }
636
637 #[cfg(any(feature = "CL_VERSION_2_0", feature = "dynamic"))]
638 pub fn create_with_properties(
639 context: &Context,
640 properties: *const cl_sampler_properties,
641 ) -> Result<Self> {
642 let sampler = sampler::create_sampler_with_properties(context.get(), properties)?;
643 Ok(Self::new(sampler))
644 }
645
646 pub const fn get(&self) -> cl_sampler {
647 self.sampler
648 }
649
650 pub fn reference_count(&self) -> Result<cl_uint> {
651 Ok(sampler::get_sampler_info(self.get(), sampler::CL_SAMPLER_REFERENCE_COUNT)?.into())
652 }
653
654 pub fn context(&self) -> Result<cl_context> {
655 Ok(intptr_t::from(sampler::get_sampler_info(
656 self.get(),
657 sampler::CL_SAMPLER_CONTEXT,
658 )?) as cl_context)
659 }
660
661 pub fn normalized_coords(&self) -> Result<bool> {
662 Ok(cl_uint::from(sampler::get_sampler_info(
663 self.get(),
664 sampler::CL_SAMPLER_NORMALIZED_COORDS,
665 )?) != CL_FALSE)
666 }
667
668 pub fn addressing_mode(&self) -> Result<cl_addressing_mode> {
669 Ok(sampler::get_sampler_info(self.get(), sampler::CL_SAMPLER_ADDRESSING_MODE)?.into())
670 }
671
672 pub fn filter_mode(&self) -> Result<cl_filter_mode> {
673 Ok(sampler::get_sampler_info(self.get(), sampler::CL_SAMPLER_FILTER_MODE)?.into())
674 }
675
676 pub fn sampler_properties(&self) -> Result<Vec<intptr_t>> {
677 Ok(sampler::get_sampler_info(self.get(), sampler::CL_SAMPLER_PROPERTIES)?.into())
678 }
679
680 pub fn get_data(&self, param_name: cl_sampler_info) -> Result<Vec<u8>> {
683 Ok(sampler::get_sampler_data(self.get(), param_name)?)
684 }
685}
686
687#[cfg(any(feature = "CL_VERSION_2_0", feature = "dynamic"))]
692#[derive(Debug)]
693pub struct Pipe {
694 pipe: cl_mem,
695}
696
697#[cfg(any(feature = "CL_VERSION_2_0", feature = "dynamic"))]
698impl From<cl_mem> for Pipe {
699 fn from(pipe: cl_mem) -> Self {
700 Self { pipe }
701 }
702}
703
704#[cfg(any(feature = "CL_VERSION_2_0", feature = "dynamic"))]
705impl From<Pipe> for cl_mem {
706 fn from(value: Pipe) -> Self {
707 value.pipe as Self
708 }
709}
710
711#[cfg(any(feature = "CL_VERSION_2_0", feature = "dynamic"))]
712impl ClMem for Pipe {
713 fn get(&self) -> cl_mem {
714 self.pipe
715 }
716
717 fn get_mut(&mut self) -> cl_mem {
718 self.pipe
719 }
720}
721
722#[cfg(any(feature = "CL_VERSION_2_0", feature = "dynamic"))]
723impl Drop for Pipe {
724 fn drop(&mut self) {
725 unsafe { memory::release_mem_object(self.get()).expect("Error: clReleaseMemObject") };
726 }
727}
728
729#[cfg(any(feature = "CL_VERSION_2_0", feature = "dynamic"))]
730impl Pipe {
731 pub const fn new(pipe: cl_mem) -> Self {
732 Self { pipe }
733 }
734
735 pub unsafe fn create(
736 context: &Context,
737 flags: cl_mem_flags,
738 pipe_packet_size: cl_uint,
739 pipe_max_packets: cl_uint,
740 ) -> Result<Self> {
741 unsafe {
742 let pipe =
743 memory::create_pipe(context.get(), flags, pipe_packet_size, pipe_max_packets)?;
744 Ok(Self::new(pipe))
745 }
746 }
747
748 pub fn pipe_packet_size(&self) -> Result<cl_uint> {
749 Ok(memory::get_pipe_info(self.get(), CL_PIPE_PACKET_SIZE)?.into())
750 }
751
752 pub fn pipe_max_packets(&self) -> Result<cl_uint> {
753 Ok(memory::get_pipe_info(self.get(), CL_PIPE_MAX_PACKETS)?.into())
754 }
755
756 pub fn pipe_properties(&self) -> Result<Vec<intptr_t>> {
757 Ok(memory::get_pipe_info(self.get(), CL_PIPE_PROPERTIES)?.into())
758 }
759
760 pub fn get_data(&self, param_name: cl_pipe_info) -> Result<Vec<u8>> {
763 Ok(memory::get_pipe_data(self.get(), param_name)?)
764 }
765}
766
767#[cfg(test)]
768mod tests {
769 use super::*;
770 use crate::context::Context;
771 use crate::device::{CL_DEVICE_TYPE_GPU, Device};
772 use crate::platform::get_platforms;
773 use crate::types::cl_float;
774 use std::ptr;
775
776 #[test]
777 fn test_memory_buffer() {
778 let platforms = get_platforms().unwrap();
779 assert!(0 < platforms.len());
780
781 let platform = &platforms[0];
783
784 let devices = platform.get_devices(CL_DEVICE_TYPE_GPU).unwrap();
785 assert!(0 < devices.len());
786
787 let device = Device::new(devices[0]);
789 let context = Context::from_device(&device).unwrap();
790
791 const ARRAY_SIZE: usize = 1024;
792
793 let buffer = unsafe {
794 Buffer::<cl_float>::create(&context, CL_MEM_WRITE_ONLY, ARRAY_SIZE, ptr::null_mut())
795 .unwrap()
796 };
797
798 let value = buffer.mem_type().unwrap();
799 println!("buffer.mem_type(): {}", value);
800 assert_eq!(CL_MEM_OBJECT_BUFFER, value);
801
802 let value = buffer.flags().unwrap();
803 println!("buffer.flags(): {}", value);
804 assert_eq!(CL_MEM_WRITE_ONLY, value);
805
806 let value = buffer.size().unwrap();
807 println!("buffer.size(): {}", value);
808 assert_eq!(ARRAY_SIZE * mem::size_of::<cl_float>(), value);
809
810 let value = buffer.host_ptr().unwrap();
811 println!("buffer.host_ptr(): {:?}", value);
812 assert_eq!(0, value);
813
814 let value = buffer.map_count().unwrap();
815 println!("buffer.map_count(): {}", value);
816 assert_eq!(0, value);
817
818 let value = buffer.reference_count().unwrap();
819 println!("buffer.reference_count(): {}", value);
820 assert_eq!(1, value);
821
822 let value = buffer.context().unwrap();
823 assert!(context.get() == value);
824
825 let value = buffer.associated_memobject().unwrap() as intptr_t;
826 println!("buffer.associated_memobject(): {:?}", value);
827 assert_eq!(0, value);
828
829 let value = buffer.offset().unwrap();
830 println!("buffer.offset(): {}", value);
831 assert_eq!(0, value);
832
833 let value = buffer.uses_svm_pointer().unwrap();
834 println!("buffer.uses_svm_pointer(): {}", value);
835 assert_eq!(0, value);
836
837 match buffer.properties() {
839 Ok(value) => {
840 println!("buffer.properties: {:?}", value)
841 }
842 Err(e) => println!("OpenCL error, CL_MEM_PROPERTIES: {:?}, {}", e, e),
843 }
844 }
845}