/* * Copyright © 2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . * * Author: Benjamin Segovia */ #ifndef __CL_MEM_H__ #define __CL_MEM_H__ #include "cl_internals.h" #include "cl_driver_type.h" #include "CL/cl.h" #include "cl_base_object.h" #include #include #if defined(HAS_GL_EGL) #include "EGL/egl.h" #endif #ifndef CL_VERSION_1_2 #define CL_MEM_OBJECT_IMAGE1D 0x10F4 #define CL_MEM_OBJECT_IMAGE1D_ARRAY 0x10F5 #define CL_MEM_OBJECT_IMAGE1D_BUFFER 0x10F6 #define CL_MEM_OBJECT_IMAGE2D_ARRAY 0x10F3 typedef struct _cl_image_desc { cl_mem_object_type image_type; size_t image_width; size_t image_height; size_t image_depth; size_t image_array_size; size_t image_row_pitch; size_t image_slice_pitch; cl_uint num_mip_levels; cl_uint num_samples; cl_mem buffer; } cl_image_desc; #endif typedef enum cl_image_tiling { CL_NO_TILE = 0, CL_TILE_X = 1, CL_TILE_Y = 2 } cl_image_tiling_t; typedef struct _cl_mapped_ptr { void * ptr; void * v_ptr; size_t size; size_t origin[3]; /* mapped origin */ size_t region[3]; /* mapped region */ cl_mem tmp_ker_buf; /* this object is tmp buffer for OCL kernel copying */ uint8_t ker_write_map; /* this flag is used to indicate CL_MAP_WRITE for OCL kernel copying */ }cl_mapped_ptr; typedef struct _cl_mem_dstr_cb { list_node node; /* Mem callback list node */ void(CL_CALLBACK *pfn_notify)(cl_mem memobj, void *user_data); void *user_data; } _cl_mem_dstr_cb; typedef _cl_mem_dstr_cb* cl_mem_dstr_cb; /* Used for buffers and images */ enum cl_mem_type { CL_MEM_BUFFER_TYPE, CL_MEM_SUBBUFFER_TYPE, CL_MEM_PIPE_TYPE, CL_MEM_SVM_TYPE, CL_MEM_IMAGE_TYPE, CL_MEM_GL_IMAGE_TYPE, CL_MEM_BUFFER1D_IMAGE_TYPE }; #define IS_IMAGE(mem) (mem->type >= CL_MEM_IMAGE_TYPE) #define IS_GL_IMAGE(mem) (mem->type == CL_MEM_GL_IMAGE_TYPE) typedef struct _cl_mem { _cl_base_object base; enum cl_mem_type type; cl_buffer bo; /* Data in GPU memory */ size_t size; /* original request size, not alignment size, used in constant buffer */ cl_context ctx; /* Context it belongs to */ cl_mem_flags flags; /* Flags specified at the creation time */ void * host_ptr; /* Pointer of the host mem specified by CL_MEM_ALLOC_HOST_PTR, CL_MEM_USE_HOST_PTR */ cl_mapped_ptr* mapped_ptr;/* Store the mapped addresses and size by caller. */ int mapped_ptr_sz; /* The array size of mapped_ptr. */ int map_ref; /* The mapped count. */ uint8_t mapped_gtt; /* This object has mapped gtt, for unmap. */ list_head dstr_cb_head; /* All destroy callbacks. */ uint8_t is_userptr; /* CL_MEM_USE_HOST_PTR is enabled */ cl_bool is_svm; /* This object is svm */ size_t offset; /* offset of host_ptr to the page beginning, only for CL_MEM_USE_HOST_PTR*/ uint8_t cmrt_mem_type; /* CmBuffer, CmSurface2D, ... */ void* cmrt_mem; } _cl_mem; #define CL_OBJECT_MEM_MAGIC 0x381a27b9ee6504dfLL #define CL_OBJECT_IS_MEM(obj) ((obj && \ ((cl_base_object)obj)->magic == CL_OBJECT_MEM_MAGIC && \ CL_OBJECT_GET_REF(obj) >= 1)) #define CL_OBJECT_IS_IMAGE(mem) ((mem && \ ((cl_base_object)mem)->magic == CL_OBJECT_MEM_MAGIC && \ CL_OBJECT_GET_REF(mem) >= 1 && \ mem->type >= CL_MEM_IMAGE_TYPE)) #define CL_OBJECT_IS_BUFFER(mem) ((mem && \ ((cl_base_object)mem)->magic == CL_OBJECT_MEM_MAGIC && \ CL_OBJECT_GET_REF(mem) >= 1 && \ mem->type < CL_MEM_IMAGE_TYPE)) typedef struct _cl_mem_pipe { _cl_mem base; cl_svm_mem_flags flags; /* Flags specified at the creation time */ uint32_t packet_size; uint32_t max_packets; } _cl_mem_pipe; typedef struct _cl_mem_svm { _cl_mem base; cl_svm_mem_flags flags; /* Flags specified at the creation time */ } _cl_mem_svm; struct _cl_mem_image { _cl_mem base; cl_image_format fmt; /* only for images */ uint32_t intel_fmt; /* format to provide in the surface state */ size_t bpp; /* number of bytes per pixel */ cl_mem_object_type image_type; /* only for images 1D/2D...*/ size_t w, h, depth; /* only for images (depth is only for 3D images) */ size_t row_pitch, slice_pitch; size_t host_row_pitch, host_slice_pitch; cl_image_tiling_t tiling; /* only IVB+ supports TILE_[X,Y] (image only) */ size_t tile_x, tile_y; /* tile offset, used for mipmap images. */ size_t offset; /* offset for dri_bo, used when it's reloc. */ cl_mem buffer_1d; /* if the image is created from buffer, it point to the buffer.*/ uint8_t is_image_from_buffer; /* IMAGE from Buffer*/ cl_mem nv12_image; /* if the image is created from nv12 Image, it point to the image.*/ uint8_t is_image_from_nv12_image; /* IMAGE from NV12 Image*/ cl_bool is_ker_copy; /* this object is copied by OCL kernel */ cl_mem tmp_ker_buf; /* this object is tmp buffer for OCL kernel copying */ }; struct _cl_mem_gl_image { struct _cl_mem_image base; int fd; #if defined(HAS_GL_EGL) EGLImage egl_image; #endif }; struct _cl_mem_buffer1d_image { struct _cl_mem_image base; uint32_t size; _cl_mem * descbuffer; }; #define IS_1D_IMAGE(image) (image->image_type == CL_MEM_OBJECT_IMAGE1D || \ image->image_type == CL_MEM_OBJECT_IMAGE1D_ARRAY || \ image->image_type == CL_MEM_OBJECT_IMAGE1D_BUFFER) #define IS_2D_IMAGE(image) (image->image_type == CL_MEM_OBJECT_IMAGE2D || \ image->image_type == CL_MEM_OBJECT_IMAGE2D_ARRAY) #define IS_3D_IMAGE(image) (image->image_type == CL_MEM_OBJECT_IMAGE3D) #define IS_IMAGE_ARRAY(image) (image->image_type == CL_MEM_OBJECT_IMAGE1D_ARRAY || \ image->image_type == CL_MEM_OBJECT_IMAGE2D_ARRAY) inline static void cl_mem_image_init(struct _cl_mem_image *image, size_t w, size_t h, cl_mem_object_type image_type, size_t depth, cl_image_format fmt, uint32_t intel_fmt, uint32_t bpp, size_t row_pitch, size_t slice_pitch, cl_image_tiling_t tiling, size_t tile_x, size_t tile_y, size_t offset) { image->w = w; image->h = h; image->image_type = image_type; image->depth = depth; image->fmt = fmt; image->intel_fmt = intel_fmt; image->bpp = bpp; image->row_pitch = row_pitch; image->slice_pitch = slice_pitch; image->tiling = tiling; image->tile_x = tile_x; image->tile_y = tile_y; image->offset = offset; } struct _cl_mem_buffer { _cl_mem base; struct _cl_mem_buffer* subs; /* Sub buf objects. */ size_t sub_offset; /* The sub start offset. */ struct _cl_mem_buffer* sub_prev, *sub_next;/* We chain the sub memory buffers together */ pthread_mutex_t sub_lock; /* Sub buffers list lock*/ struct _cl_mem_buffer* parent; /* Point to the parent buffer if is sub-buffer */ }; inline static struct _cl_mem_image * cl_mem_image(cl_mem mem) { assert(IS_IMAGE(mem)); return (struct _cl_mem_image *)mem; } inline static struct _cl_mem_gl_image * cl_mem_gl_image(cl_mem mem) { assert(IS_GL_IMAGE(mem)); return (struct _cl_mem_gl_image*)mem; } inline static struct _cl_mem_pipe * cl_mem_pipe(cl_mem mem) { assert(mem->type == CL_MEM_PIPE_TYPE); return (struct _cl_mem_pipe *)mem; } /* Query information about a memory object */ extern cl_mem_object_type cl_get_mem_object_type(cl_mem mem); /* Query whether mem is in buffers */ extern cl_int cl_mem_is_valid(cl_mem mem, cl_context ctx); /* Create a new memory object and initialize it with possible user data */ extern cl_mem cl_mem_new_buffer(cl_context, cl_mem_flags, size_t, void*, cl_int*); /* Create a new sub memory object */ extern cl_mem cl_mem_new_sub_buffer(cl_mem, cl_mem_flags, cl_buffer_create_type, const void *, cl_int *); extern cl_mem cl_mem_new_pipe(cl_context, cl_mem_flags, cl_uint, cl_uint, cl_int *); /* Query information about a pipe object */ extern cl_int cl_get_pipe_info(cl_mem, cl_mem_info, size_t, void *, size_t *); void* cl_mem_svm_allocate(cl_context, cl_svm_mem_flags, size_t, unsigned int); void cl_mem_svm_delete(cl_context, void *svm_pointer); /* Idem but this is an image */ extern cl_mem cl_mem_new_image(cl_context context, cl_mem_flags flags, const cl_image_format *image_format, const cl_image_desc *image_desc, void *host_ptr, cl_int *errcode_ret); /* Unref the object and delete it if no more reference */ extern void cl_mem_delete(cl_mem); /* Destroy egl image. */ extern void cl_mem_gl_delete(struct _cl_mem_gl_image *); /* Add one more reference to this object */ extern void cl_mem_add_ref(cl_mem); /* api clEnqueueCopyBuffer help function */ extern cl_int cl_mem_copy(cl_command_queue queue, cl_event event, cl_mem src_buf, cl_mem dst_buf, size_t src_offset, size_t dst_offset, size_t cb); extern cl_int cl_mem_fill(cl_command_queue queue, cl_event e, const void * pattern, size_t pattern_size, cl_mem buffer, size_t offset, size_t size); extern cl_int cl_image_fill(cl_command_queue queue, cl_event e, const void * pattern, struct _cl_mem_image*, const size_t *, const size_t *); /* api clEnqueueCopyBufferRect help function */ extern cl_int cl_mem_copy_buffer_rect(cl_command_queue, cl_event event, cl_mem, cl_mem, const size_t *, const size_t *, const size_t *, size_t, size_t, size_t, size_t); /* api clEnqueueCopyImage help function */ extern cl_int cl_mem_kernel_copy_image(cl_command_queue, cl_event event, struct _cl_mem_image*, struct _cl_mem_image*, const size_t *, const size_t *, const size_t *); /* api clEnqueueCopyImageToBuffer help function */ extern cl_int cl_mem_copy_image_to_buffer(cl_command_queue, cl_event, struct _cl_mem_image*, cl_mem, const size_t *, const size_t, const size_t *); /* api clEnqueueCopyBufferToImage help function */ extern cl_int cl_mem_copy_buffer_to_image(cl_command_queue, cl_event, cl_mem, struct _cl_mem_image*, const size_t, const size_t *, const size_t *); /* Directly map a memory object */ extern void *cl_mem_map(cl_mem, int); /* Unmap a memory object */ extern cl_int cl_mem_unmap(cl_mem); /* Directly map a memory object in GTT mode */ extern void *cl_mem_map_gtt(cl_mem); /* Directly map a memory object in GTT mode, with out waiting gpu idle */ extern void *cl_mem_map_gtt_unsync(cl_mem); /* Unmap a memory object in GTT mode */ extern cl_int cl_mem_unmap_gtt(cl_mem); /* Directly map a memory object - tiled images are mapped in GTT mode */ extern void *cl_mem_map_auto(cl_mem, int); /* Unmap a memory object - tiled images are unmapped in GTT mode */ extern cl_int cl_mem_unmap_auto(cl_mem); /* Pin/unpin the buffer in memory (you must be root) */ extern cl_int cl_mem_pin(cl_mem); extern cl_int cl_mem_unpin(cl_mem); extern cl_mem cl_mem_allocate(enum cl_mem_type type, cl_context ctx, cl_mem_flags flags, size_t sz, cl_int is_tiled, void *host_ptr, cl_mem buffer, cl_int *errcode); void cl_mem_copy_image_region(const size_t *origin, const size_t *region, void *dst, size_t dst_row_pitch, size_t dst_slice_pitch, const void *src, size_t src_row_pitch, size_t src_slice_pitch, const struct _cl_mem_image *image, cl_bool offset_dst, cl_bool offset_src); void cl_mem_copy_image_to_image(const size_t *dst_origin,const size_t *src_origin, const size_t *region, const struct _cl_mem_image *dst_image, const struct _cl_mem_image *src_image); extern cl_mem cl_mem_new_libva_buffer(cl_context ctx, unsigned int bo_name, cl_int *errcode); extern cl_mem cl_mem_new_libva_image(cl_context ctx, unsigned int bo_name, size_t offset, size_t width, size_t height, cl_image_format fmt, size_t row_pitch, cl_int *errcode); extern cl_int cl_mem_get_fd(cl_mem mem, int* fd); extern cl_mem cl_mem_new_buffer_from_fd(cl_context ctx, int fd, int buffer_sz, cl_int* errcode); extern cl_mem cl_mem_new_image_from_fd(cl_context ctx, int fd, int image_sz, size_t offset, size_t width, size_t height, cl_image_format fmt, size_t row_pitch, cl_int *errcode); extern cl_int cl_mem_record_map_mem(cl_mem mem, void *ptr, void **mem_ptr, size_t offset, size_t size, const size_t *origin, const size_t *region); extern cl_int cl_mem_record_map_mem_for_kernel(cl_mem mem, void *ptr, void **mem_ptr, size_t offset, size_t size, const size_t *origin, const size_t *region, cl_mem tmp_ker_buf, uint8_t write_map); extern cl_int cl_mem_set_destructor_callback(cl_mem memobj, void(CL_CALLBACK *pfn_notify)(cl_mem, void *), void *user_data); #endif /* __CL_MEM_H__ */