diff options
author | Zhigang Gong <zhigang.gong@gmail.com> | 2013-08-26 22:45:48 +0800 |
---|---|---|
committer | Zhigang Gong <zhigang.gong@linux.intel.com> | 2013-09-06 16:24:57 +0800 |
commit | 4a6106b0b6bc13b76855cfa9b1f4d33248ed97c7 (patch) | |
tree | 806d6c058b4776af8c6cc099d97dae73dd2e8fe8 /src | |
parent | 9a2fd56bc0982499449f2ea84d7e0d5a3d49ad82 (diff) |
CL: Enalbe gl sharing with new egl extension.
The previous implementation is only for 2d/3d texture sharing and
is implemented in a hacky fashinon. We need to replace it with a
clean and complete one. We introduce a new egl extension to export
low level layout information of a buffer object/texture/render buffer
from the mesa dri driver to the cl driver layer. As the extension is
not accpepted by mesa, we have to implement this new extension in
beignet internally.
Signed-off-by: Zhigang Gong <zhigang.gong@linux.intel.com>
Tested-by: He Junyan <junyan.he@inbox.com>
Diffstat (limited to 'src')
28 files changed, 1233 insertions, 1076 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 58d23cb0..f7f77cc0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -29,16 +29,14 @@ set(OPENCL_SRC x11/dricommon.c x11/va_dri2.c) -if (EGL_FOUND AND GBM_FOUND) -set (OPENCL_SRC ${OPENCL_SRC} cl_mem_gl.c cl_gl_api.c x11/gbm_dri2_x11_platform.c) -SET(CMAKE_CXX_FLAGS "-DHAS_EGL ${CMAKE_CXX_FLAGS}") -SET(CMAKE_C_FLAGS "-DHAS_EGL ${CMAKE_C_FLAGS}") +if (EGL_FOUND AND MESA_SOURCE_FOUND) +set (OPENCL_SRC ${OPENCL_SRC} cl_mem_gl.c cl_gl_api.c x11/mesa_egl_extension.c x11/mesa_egl_res_share.c intel/intel_dri_resource_sharing.c) +SET(CMAKE_CXX_FLAGS "-DHAS_EGL ${CMAKE_CXX_FLAGS} ${MESA_SOURCE_INCLUDES}") +SET(CMAKE_C_FLAGS "-DHAS_EGL ${CMAKE_C_FLAGS} ${MESA_SOURCE_INCLUDES}") SET(OPTIONAL_EGL_LIBRARY "${EGL_LIBRARY}") -SET(OPTIONAL_GBM_LIBRARY "${GBM_LIBRARY}") -else(EGL_FOUND AND GBM_FOUND) +else(EGL_FOUND AND MESA_SOURCE_FOUND) SET(OPTIONAL_EGL_LIBRARY "") -SET(OPTIONAL_GBM_LIBRARY "") -endif (EGL_FOUND AND GBM_FOUND) +endif (EGL_FOUND AND MESA_SOURCE_FOUND) if (OCLIcd_FOUND) set (OPENCL_SRC ${OPENCL_SRC} cl_khr_icd.c) @@ -46,7 +44,7 @@ SET(CMAKE_CXX_FLAGS "-DHAS_OCLIcd ${CMAKE_CXX_FLAGS}") SET(CMAKE_C_FLAGS "-DHAS_OCLIcd ${CMAKE_C_FLAGS}") endif (OCLIcd_FOUND) -SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-Bsymbolic") +SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-Bsymbolic,--allow-shlib-undefined") link_directories (${LLVM_LIBRARY_DIR}) add_library(cl SHARED ${OPENCL_SRC}) @@ -59,6 +57,5 @@ target_link_libraries( ${DRM_INTEL_LIBRARY} ${DRM_LIBRARY} ${OPENGL_LIBRARIES} - ${OPTIONAL_EGL_LIBRARY} - ${OPTIONAL_GBM_LIBRARY}) + ${OPTIONAL_EGL_LIBRARY}) install (TARGETS cl LIBRARY DESTINATION lib) diff --git a/src/cl_context.h b/src/cl_context.h index b1ef4796..ac61f574 100644 --- a/src/cl_context.h +++ b/src/cl_context.h @@ -51,6 +51,9 @@ struct _cl_context_prop { }; }; +#define IS_EGL_CONTEXT(ctx) (ctx->props.gl_type == CL_GL_EGL_DISPLAY) +#define EGL_DISP(ctx) (EGLDisplay)(ctx->props.egl_display) +#define EGL_CTX(ctx) (EGLContext)(ctx->props.gl_context) /* Encapsulate the whole device */ struct _cl_context { DEFINE_ICD(dispatch) diff --git a/src/cl_driver.h b/src/cl_driver.h index 95d6485f..024033a5 100644 --- a/src/cl_driver.h +++ b/src/cl_driver.h @@ -22,7 +22,7 @@ #include <stdint.h> #include <stdlib.h> - +#include "cl_driver_type.h" /* Various limitations we should remove actually */ #define GEN_MAX_SURFACES 128 #define GEN_MAX_SAMPLERS 16 @@ -33,28 +33,6 @@ * will allow us to make the use of a software performance simulator easier and * to minimize the code specific for the HW and for the simulator **************************************************************************/ - -/* Encapsulates command buffer / data buffer / kernels */ -typedef struct _cl_buffer *cl_buffer; - -/* Encapsulates buffer manager */ -typedef struct _cl_buffer_mgr *cl_buffer_mgr; - -/* Encapsulates the driver backend functionalities */ -typedef struct _cl_driver *cl_driver; - -/* Encapsulates the gpgpu stream of commands */ -typedef struct _cl_gpgpu *cl_gpgpu; - -/* Encapsulates the event of a command stream */ -typedef struct _cl_gpgpu_event *cl_gpgpu_event; - -typedef struct _cl_context_prop *cl_context_prop; -typedef struct _cl_sampler *cl_sampler; - -/************************************************************************** - * Driver - **************************************************************************/ /* Create a new driver */ typedef cl_driver (cl_driver_new_cb)(cl_context_prop); extern cl_driver_new_cb *cl_driver_new; @@ -234,14 +212,18 @@ typedef cl_buffer (cl_buffer_set_tiling_cb)(cl_buffer, int tiling, size_t stride extern cl_buffer_set_tiling_cb *cl_buffer_set_tiling; #include "cl_context.h" +#include "cl_mem.h" typedef struct _cl_context *cl_context; -typedef cl_buffer (cl_buffer_alloc_from_eglimage_cb)(cl_context, void*, unsigned int *, - int *, int *, int *, int *); -extern cl_buffer_alloc_from_eglimage_cb *cl_buffer_alloc_from_eglimage; +typedef cl_buffer (cl_buffer_alloc_from_texture_cb)(cl_context, unsigned int, int, unsigned int, + struct _cl_mem_image *gl_image); +extern cl_buffer_alloc_from_texture_cb *cl_buffer_alloc_from_texture; + +typedef void (cl_buffer_release_from_texture_cb)(cl_context, unsigned int, int, unsigned int); +extern cl_buffer_release_from_texture_cb *cl_buffer_release_from_texture; /* Unref a buffer and destroy it if no more ref */ -typedef void (cl_buffer_unreference_cb)(cl_buffer); +typedef int (cl_buffer_unreference_cb)(cl_buffer); extern cl_buffer_unreference_cb *cl_buffer_unreference; /* Add one more ref on a buffer */ @@ -296,5 +278,35 @@ extern cl_buffer_wait_rendering_cb *cl_buffer_wait_rendering; typedef int (cl_driver_get_device_id_cb)(void); extern cl_driver_get_device_id_cb *cl_driver_get_device_id; +/************************************************************************** + * cl_khr_gl_sharing. + **************************************************************************/ +typedef int (cl_gl_acquire_texture_cb)(void *driver, void *ctx, int target, + int level, int texture, void*user_data); +extern cl_gl_acquire_texture_cb *cl_gl_acquire_texture; + +typedef int (cl_gl_release_texture_cb)(void *driver, void *ctx, int target, + int level, int texture); +extern cl_gl_release_texture_cb *cl_gl_release_texture; + +typedef int (cl_gl_acquire_buffer_object_cb)(void *driver, void *ctx, + int bufobj, void* user_data); +extern cl_gl_acquire_buffer_object_cb *cl_gl_acquire_buffer_object; + +typedef int (cl_gl_release_buffer_object_cb)(void *driver, void *ctx, int bufobj); +extern cl_gl_release_buffer_object_cb *cl_gl_release_buffer_object; + +typedef int (cl_gl_acquire_render_buffer_cb)(void *driver, void *ctx, + int rb, void* user_data); +extern cl_gl_acquire_render_buffer_cb *cl_gl_acquire_render_buffer; + +typedef int (cl_gl_release_render_buffer_cb)(void *driver, void *ctx, int rb); +extern cl_gl_release_render_buffer_cb *cl_gl_release_render_buffer; + +#ifndef DEFAULT_DRIVER_DIR +/* this is normally defined in Mesa/configs/default with DRI_DRIVER_SEARCH_PATH */ +#define DEFAULT_DRIVER_DIR "/usr/local/lib/dri" +#endif + #endif /* __CL_DRIVER_H__ */ diff --git a/src/cl_driver_defs.c b/src/cl_driver_defs.c index ae130fae..ac4ff7a4 100644 --- a/src/cl_driver_defs.c +++ b/src/cl_driver_defs.c @@ -30,7 +30,8 @@ LOCAL cl_driver_get_device_id_cb *cl_driver_get_device_id = NULL; /* Buffer */ LOCAL cl_buffer_alloc_cb *cl_buffer_alloc = NULL; LOCAL cl_buffer_set_tiling_cb *cl_buffer_set_tiling = NULL; -LOCAL cl_buffer_alloc_from_eglimage_cb *cl_buffer_alloc_from_eglimage = NULL; +LOCAL cl_buffer_alloc_from_texture_cb *cl_buffer_alloc_from_texture = NULL; +LOCAL cl_buffer_release_from_texture_cb *cl_buffer_release_from_texture = NULL; LOCAL cl_buffer_reference_cb *cl_buffer_reference = NULL; LOCAL cl_buffer_unreference_cb *cl_buffer_unreference = NULL; LOCAL cl_buffer_map_cb *cl_buffer_map = NULL; @@ -45,6 +46,13 @@ LOCAL cl_buffer_unpin_cb *cl_buffer_unpin = NULL; LOCAL cl_buffer_subdata_cb *cl_buffer_subdata = NULL; LOCAL cl_buffer_wait_rendering_cb *cl_buffer_wait_rendering = NULL; +/* cl_khr_gl_sharing */ +LOCAL cl_gl_acquire_texture_cb *cl_gl_acquire_texture = NULL; +LOCAL cl_gl_release_texture_cb *cl_gl_release_texture = NULL; +LOCAL cl_gl_acquire_buffer_object_cb *cl_gl_acquire_buffer_object = NULL; +LOCAL cl_gl_release_buffer_object_cb *cl_gl_release_buffer_object = NULL; +LOCAL cl_gl_acquire_render_buffer_cb *cl_gl_acquire_render_buffer = NULL; +LOCAL cl_gl_release_render_buffer_cb *cl_gl_release_render_buffer = NULL; /* GPGPU */ LOCAL cl_gpgpu_new_cb *cl_gpgpu_new = NULL; LOCAL cl_gpgpu_delete_cb *cl_gpgpu_delete = NULL; diff --git a/src/cl_driver_type.h b/src/cl_driver_type.h new file mode 100644 index 00000000..891a33c6 --- /dev/null +++ b/src/cl_driver_type.h @@ -0,0 +1,24 @@ +/************************************************************************** + * cl_driver: + * Hide behind some call backs the buffer allocation / deallocation ... This + * will allow us to make the use of a software performance simulator easier and + * to minimize the code specific for the HW and for the simulator + **************************************************************************/ + +/* Encapsulates command buffer / data buffer / kernels */ +typedef struct _cl_buffer *cl_buffer; + +/* Encapsulates buffer manager */ +typedef struct _cl_buffer_mgr *cl_buffer_mgr; + +/* Encapsulates the driver backend functionalities */ +typedef struct _cl_driver *cl_driver; + +/* Encapsulates the gpgpu stream of commands */ +typedef struct _cl_gpgpu *cl_gpgpu; + +/* Encapsulates the event of a command stream */ +typedef struct _cl_gpgpu_event *cl_gpgpu_event; + +typedef struct _cl_context_prop *cl_context_prop; +typedef struct _cl_sampler *cl_sampler; diff --git a/src/cl_extensions.c b/src/cl_extensions.c index 335278d6..d07a5257 100644 --- a/src/cl_extensions.c +++ b/src/cl_extensions.c @@ -40,26 +40,12 @@ void check_opt1_extension(cl_extensions_t *extensions) void check_gl_extension(cl_extensions_t *extensions) { -#ifdef HAS_EGL -static struct cl_gl_ext_deps egl_funcs; +#if defined(HAS_EGL) int id; -#if defined(EGL_KHR_image) && defined(EGL_KHR_gl_texture_2D_image) && defined(HAS_GBM) - egl_funcs.eglCreateImageKHR_func = (PFNEGLCREATEIMAGEKHRPROC) eglGetProcAddress("eglCreateImageKHR"); - egl_funcs.eglDestroyImageKHR_func = (PFNEGLDESTROYIMAGEKHRPROC) eglGetProcAddress("eglDestroyImageKHR"); -#else - egl_funcs.eglCreateImageKHR_func = NULL; - egl_funcs.eglDestroyImageKHR_func = NULL; -#endif - - if (egl_funcs.eglCreateImageKHR_func != NULL - && egl_funcs.eglDestroyImageKHR_func != NULL) { /* For now, we only support cl_khr_gl_sharing. */ - for(id = GL_EXT_START_ID; id <= GL_EXT_END_ID; id++) - if (id == EXT_ID(khr_gl_sharing)) { - extensions->extensions[id].base.ext_enabled = 1; - extensions->extensions[id].EXT_STRUCT_NAME(khr_gl_sharing).gl_ext_deps = &egl_funcs; - } - } + for(id = GL_EXT_START_ID; id <= GL_EXT_END_ID; id++) + if (id == EXT_ID(khr_gl_sharing)) + extensions->extensions[id].base.ext_enabled = 1; #endif } diff --git a/src/cl_extensions.h b/src/cl_extensions.h index 51eb8e05..52ee0a49 100644 --- a/src/cl_extensions.h +++ b/src/cl_extensions.h @@ -76,29 +76,6 @@ struct EXT_STRUCT_NAME(name) { \ DECL_BASE_EXTENSIONS DECL_OPT1_EXTENSIONS DECL_D3D_EXTENSIONS -#undef DECL_EXT - -#define DECL_EXT(name) \ -struct EXT_STRUCT_NAME(name) { \ - struct cl_extension_base base; \ - struct cl_gl_ext_deps *gl_ext_deps; \ -}; - -struct cl_gl_ext_deps { -#ifdef HAS_EGL -#ifndef EGL_KHR_image -#define PFNEGLCREATEIMAGEKHRPROC void* -#define PFNEGLDESTROYIMAGEKHRPROC void* -#endif - PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR_func; - PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR_func; -#ifndef EGL_KHR_image -#undef PFNEGLCREATEIMAGEKHRPROC -#undef PFNEGLDESTROYIMAGEKHRPROC -#endif -#endif -}; - DECL_GL_EXTENSIONS #undef DECL_EXT @@ -117,8 +94,6 @@ typedef struct cl_extensions { struct _cl_platform_id; typedef struct _cl_platform_id * cl_platform_id; -#define CL_EXTENSION_GET_FUNCS(ctx, name, funcs) \ - ctx->device->platform->internal_extensions->extensions[EXT_ID(name)].EXT_STRUCT_NAME(name).funcs extern void cl_intel_platform_extension_init(cl_platform_id intel_platform); diff --git a/src/cl_khr_icd.h b/src/cl_khr_icd.h index 6c8b9f4c..1e206b43 100644 --- a/src/cl_khr_icd.h +++ b/src/cl_khr_icd.h @@ -14,6 +14,8 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see <http://www.gnu.org/licenses/>. */ +#ifndef __CL_KHR_ICD_H__ +#define __CL_KHR_ICD_H__ #ifdef HAS_OCLIcd @@ -28,3 +30,5 @@ extern struct _cl_icd_dispatch const cl_khr_icd_dispatch; #define INIT_ICD(member) #define DEFINE_ICD(member) #endif + +#endif diff --git a/src/cl_mem.c b/src/cl_mem.c index 8df2f890..f74b5cff 100644 --- a/src/cl_mem.c +++ b/src/cl_mem.c @@ -42,6 +42,31 @@ return CL_INVALID_VALUE; \ break; +#define CL_MEM_OBJECT_BUFFER 0x10F0 +#define CL_MEM_OBJECT_IMAGE2D 0x10F1 +#define CL_MEM_OBJECT_IMAGE3D 0x10F2 + +static cl_mem_object_type +cl_get_mem_object_type(cl_mem mem) +{ + switch (mem->type) { + case CL_MEM_BUFFER_TYPE: return CL_MEM_OBJECT_BUFFER; + case CL_MEM_IMAGE_TYPE: + case CL_MEM_GL_IMAGE_TYPE: + { + struct _cl_mem_image *image = cl_mem_image(mem); + if (image->depth == 1) + return CL_MEM_OBJECT_IMAGE1D; + else if (image->depth == 2) + return CL_MEM_OBJECT_IMAGE2D; + else if (image->depth == 3) + return CL_MEM_OBJECT_IMAGE3D; + } + default: + return CL_MEM_OBJECT_BUFFER; + } +} + LOCAL cl_int cl_get_mem_object_info(cl_mem mem, cl_mem_info param_name, @@ -67,7 +92,7 @@ cl_get_mem_object_info(cl_mem mem, switch(param_name) { case CL_MEM_TYPE: - *((cl_mem_object_type *)param_value) = mem->type; + *((cl_mem_object_type *)param_value) = cl_get_mem_object_type(mem); break; case CL_MEM_FLAGS: *((cl_mem_flags *)param_value) = mem->flags; @@ -165,8 +190,6 @@ cl_mem_allocate(enum cl_mem_type type, { cl_buffer_mgr bufmgr = NULL; cl_mem mem = NULL; - struct _cl_mem_image *image = NULL; - struct _cl_mem_buffer *buffer = NULL; cl_int err = CL_SUCCESS; size_t alignment = 64; cl_ulong max_mem_size; @@ -187,10 +210,15 @@ cl_mem_allocate(enum cl_mem_type type, /* Allocate and inialize the structure itself */ if (type == CL_MEM_IMAGE_TYPE) { + struct _cl_mem_image *image = NULL; TRY_ALLOC (image, CALLOC(struct _cl_mem_image)); mem = &image->base; - } - else { + } else if (type == CL_MEM_GL_IMAGE_TYPE ) { + struct _cl_mem_gl_image *gl_image = NULL; + TRY_ALLOC (gl_image, CALLOC(struct _cl_mem_gl_image)); + mem = &gl_image->base.base; + } else { + struct _cl_mem_buffer *buffer = NULL; TRY_ALLOC (buffer, CALLOC(struct _cl_mem_buffer)); mem = &buffer->base; } @@ -282,8 +310,6 @@ cl_mem_new_buffer(cl_context ctx, if (mem == NULL || err != CL_SUCCESS) goto error; - mem->type = CL_MEM_OBJECT_BUFFER; - /* Copy the data if required */ if (flags & CL_MEM_COPY_HOST_PTR || flags & CL_MEM_USE_HOST_PTR) cl_buffer_subdata(mem->bo, 0, sz, data); @@ -440,7 +466,9 @@ _cl_mem_new_image(cl_context ctx, slice_pitch = (image_type == CL_MEM_OBJECT_IMAGE1D || image_type == CL_MEM_OBJECT_IMAGE2D) ? 0 : aligned_pitch*aligned_h; - cl_mem_image_init(cl_mem_image(mem), w, h, image_type, depth, *fmt, intel_fmt, bpp, aligned_pitch, slice_pitch, tiling); + cl_mem_image_init(cl_mem_image(mem), w, h, image_type, depth, *fmt, + intel_fmt, bpp, aligned_pitch, slice_pitch, tiling, + 0, 0, 0); /* Copy the data if required */ if (flags & CL_MEM_COPY_HOST_PTR) @@ -491,13 +519,13 @@ cl_mem_delete(cl_mem mem) return; if (atomic_dec(&mem->ref_n) > 1) return; - if (LIKELY(mem->bo != NULL)) - cl_buffer_unreference(mem->bo); #ifdef HAS_EGL - if (UNLIKELY(IS_IMAGE(mem) && cl_mem_image(mem)->egl_image != NULL)) { - cl_mem_gl_delete(cl_mem_image(mem)); + if (UNLIKELY(IS_GL_IMAGE(mem))) { + cl_mem_gl_delete(cl_mem_gl_image(mem)); } #endif + if (LIKELY(mem->bo != NULL)) + cl_buffer_unreference(mem->bo); /* Remove it from the list */ assert(mem->ctx); diff --git a/src/cl_mem.h b/src/cl_mem.h index c0d55039..9a70913c 100644 --- a/src/cl_mem.h +++ b/src/cl_mem.h @@ -21,8 +21,9 @@ #define __CL_MEM_H__ #include "cl_internals.h" -#include "cl_driver.h" +#include "cl_driver_type.h" #include "CL/cl.h" +#include "cl_khr_icd.h" #include <assert.h> #ifndef CL_VERSION_1_2 @@ -63,11 +64,13 @@ typedef struct _cl_mem_dstr_cb { }cl_mem_dstr_cb; /* Used for buffers and images */ -#define IS_IMAGE(mem) (mem->type == CL_MEM_IMAGE_TYPE) enum cl_mem_type { CL_MEM_BUFFER_TYPE, - CL_MEM_IMAGE_TYPE + CL_MEM_IMAGE_TYPE, + CL_MEM_GL_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 { uint64_t magic; /* To identify it as a memory object */ @@ -97,7 +100,13 @@ struct _cl_mem_image { 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; - void *egl_image; /* created from external egl image*/ +}; + +struct _cl_mem_gl_image { + struct _cl_mem_image base; + uint32_t target; + int miplevel; + uint32_t texture; }; inline static void @@ -106,7 +115,9 @@ cl_mem_image_init(struct _cl_mem_image *image, size_t w, size_t h, 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) + cl_image_tiling_t tiling, + size_t tile_x, size_t tile_y, + size_t offset) { image->w = w; image->h = h; @@ -118,6 +129,8 @@ cl_mem_image_init(struct _cl_mem_image *image, size_t w, size_t h, image->row_pitch = row_pitch; image->slice_pitch = slice_pitch; image->tiling = tiling; + image->tile_x = tile_x; + image->tile_y = tile_y; } struct _cl_mem_buffer { @@ -132,6 +145,13 @@ cl_mem_image(cl_mem 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_buffer * cl_mem_buffer(cl_mem mem) { @@ -161,7 +181,7 @@ cl_mem_new_image(cl_context context, extern void cl_mem_delete(cl_mem); /* Destroy egl image. */ -extern void cl_mem_gl_delete(struct _cl_mem_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); diff --git a/src/cl_mem_gl.c b/src/cl_mem_gl.c index c77bcb90..2d262264 100644 --- a/src/cl_mem_gl.c +++ b/src/cl_mem_gl.c @@ -37,92 +37,6 @@ #include "CL/cl_intel.h" #include "CL/cl_gl.h" -#ifndef CL_VERSION_1_2 -#define CL_INVALID_IMAGE_DESCRIPTOR -65 -#endif - -static int cl_get_clformat_from_texture(GLint tex_format, cl_image_format * cl_format) -{ - cl_int ret = CL_SUCCESS; - - switch (tex_format) { - case GL_RGBA8: - case GL_RGBA: - case GL_RGBA16: - case GL_RGBA8I: - case GL_RGBA16I: - case GL_RGBA32I: - case GL_RGBA8UI: - case GL_RGBA16UI: - case GL_RGBA32UI: - case GL_RGBA16F: - case GL_RGBA32F: - cl_format->image_channel_order = CL_RGBA; - break; - case GL_BGRA: - cl_format->image_channel_order = CL_BGRA; - break; - default: - ret = CL_INVALID_IMAGE_DESCRIPTOR; - goto error; - } - - switch (tex_format) { - case GL_RGBA8: - case GL_RGBA: - case GL_BGRA: - cl_format->image_channel_data_type = CL_UNORM_INT8; - break; - case GL_RGBA16: - cl_format->image_channel_data_type = CL_UNORM_INT16; - break; - case GL_RGBA8I: - cl_format->image_channel_data_type = CL_SIGNED_INT8; - break; - case GL_RGBA16I: - cl_format->image_channel_data_type = CL_SIGNED_INT16; - break; - case GL_RGBA32I: - cl_format->image_channel_data_type = CL_SIGNED_INT32; - break; - case GL_RGBA8UI: - cl_format->image_channel_data_type = CL_UNSIGNED_INT8; - break; - case GL_RGBA16UI: - cl_format->image_channel_data_type = CL_UNSIGNED_INT16; - break; - case GL_RGBA32UI: - cl_format->image_channel_data_type = CL_UNSIGNED_INT32; - break; - case GL_RGBA16F: - cl_format->image_channel_data_type = CL_HALF_FLOAT; - break; - case GL_RGBA32F: - cl_format->image_channel_order = CL_FLOAT; - break; - default: - ret = CL_INVALID_IMAGE_DESCRIPTOR; - goto error; - } - -error: - return ret; -} - -static cl_mem_object_type -get_mem_type_from_target(GLenum texture_target, cl_mem_object_type *type) -{ - switch(texture_target) { - case GL_TEXTURE_1D: *type = CL_MEM_OBJECT_IMAGE1D; break; - case GL_TEXTURE_2D: *type = CL_MEM_OBJECT_IMAGE2D; break; - case GL_TEXTURE_3D: *type = CL_MEM_OBJECT_IMAGE3D; break; - case GL_TEXTURE_1D_ARRAY: *type = CL_MEM_OBJECT_IMAGE1D_ARRAY; break; - case GL_TEXTURE_2D_ARRAY: *type = CL_MEM_OBJECT_IMAGE2D_ARRAY; break; - default: - return -1; - } - return 0; -} LOCAL cl_mem cl_mem_new_gl_buffer(cl_context ctx, @@ -133,28 +47,6 @@ cl_mem_new_gl_buffer(cl_context ctx, NOT_IMPLEMENTED; } -static EGLImageKHR -cl_create_textured_egl_image(cl_context ctx, - GLenum texture_target, - GLint miplevel, - GLuint texture) -{ - struct cl_gl_ext_deps *egl_funcs; - EGLDisplay egl_display; - EGLContext egl_context; - EGLint egl_attribs[] = { EGL_GL_TEXTURE_LEVEL_KHR, miplevel, EGL_NONE}; - - assert(ctx->props.gl_type == CL_GL_EGL_DISPLAY); - egl_funcs = CL_EXTENSION_GET_FUNCS(ctx, khr_gl_sharing, gl_ext_deps); - assert(egl_funcs != NULL); - egl_display = (EGLDisplay)ctx->props.egl_display; - egl_context = (EGLDisplay)ctx->props.gl_context; - return egl_funcs->eglCreateImageKHR_func(egl_display, egl_context, - EGL_GL_TEXTURE_2D_KHR, - (EGLClientBuffer)(uintptr_t)texture, - &egl_attribs[0]); -} - LOCAL cl_mem cl_mem_new_gl_texture(cl_context ctx, cl_mem_flags flags, @@ -165,52 +57,28 @@ cl_mem_new_gl_texture(cl_context ctx, { cl_int err = CL_SUCCESS; cl_mem mem = NULL; - EGLImageKHR egl_image; - int w, h, pitch, tiling; - unsigned int bpp, intel_fmt; - cl_image_format cl_format; - unsigned int gl_format; /* Check flags consistency */ if (UNLIKELY(flags & CL_MEM_COPY_HOST_PTR)) { err = CL_INVALID_ARG_VALUE; goto error; } - mem = cl_mem_allocate(CL_MEM_IMAGE_TYPE, ctx, flags, 0, 0, errcode_ret); + mem = cl_mem_allocate(CL_MEM_GL_IMAGE_TYPE, ctx, flags, 0, 0, errcode_ret); if (mem == NULL) { err = CL_OUT_OF_HOST_MEMORY; goto error; } - egl_image = cl_create_textured_egl_image(ctx, texture_target, miplevel, texture); - if (egl_image == NULL) { - err = CL_INVALID_GL_OBJECT; - goto error; - } - mem->bo = cl_buffer_alloc_from_eglimage(ctx, (void*)egl_image, &gl_format, &w, &h, &pitch, &tiling); + mem->bo = cl_buffer_alloc_from_texture(ctx, texture_target, miplevel, + texture, cl_mem_image(mem)); if (UNLIKELY(mem->bo == NULL)) { err = CL_MEM_OBJECT_ALLOCATION_FAILURE; goto error; } - cl_get_clformat_from_texture(gl_format, &cl_format); - - /* XXX Maybe we'd better to check the hw format in driver? */ - intel_fmt = cl_image_get_intel_format(&cl_format); - - if (intel_fmt == INTEL_UNSUPPORTED_FORMAT) { - err = CL_INVALID_IMAGE_DESCRIPTOR; - goto error; - } - cl_image_byte_per_pixel(&cl_format, &bpp); - - cl_mem_object_type image_type; - if (get_mem_type_from_target(texture_target, &image_type) != 0) { - err = CL_INVALID_IMAGE_DESCRIPTOR; - goto error; - } - cl_mem_image_init(cl_mem_image(mem), w, h, image_type, 1, cl_format, intel_fmt, bpp, pitch, 0, tiling); - cl_mem_image(mem)->egl_image = egl_image; + cl_mem_gl_image(mem)->target = texture_target; + cl_mem_gl_image(mem)->miplevel = miplevel; + cl_mem_gl_image(mem)->texture = texture; exit: if (errcode_ret) @@ -223,10 +91,9 @@ error: } -LOCAL void cl_mem_gl_delete(struct _cl_mem_image *image) +LOCAL void cl_mem_gl_delete(struct _cl_mem_gl_image *gl_image) { - struct cl_gl_ext_deps *egl_funcs; - EGLDisplay egl_display = (EGLDisplay)image->base.ctx->props.egl_display; - egl_funcs = CL_EXTENSION_GET_FUNCS(image->base.ctx, khr_gl_sharing, gl_ext_deps); - egl_funcs->eglDestroyImageKHR_func(egl_display, image->egl_image); + if (gl_image->base.base.bo != NULL) + cl_buffer_release_from_texture(gl_image->base.base.ctx, gl_image->target, + gl_image->miplevel, gl_image->texture); } diff --git a/src/intel/intel_dri_resource_sharing.c b/src/intel/intel_dri_resource_sharing.c new file mode 100644 index 00000000..b31844e5 --- /dev/null +++ b/src/intel/intel_dri_resource_sharing.c @@ -0,0 +1,208 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#define HAVE_PTHREAD 1 +#include <errno.h> +#include <time.h> +#include "main/context.h" +#include "main/renderbuffer.h" +#include "main/texobj.h" +#include <stdbool.h> +#include <string.h> +#include <drm.h> +#include <i915_drm.h> +#include <intel_bufmgr.h> +#include <GL/internal/dri_interface.h> +#include "intel_mipmap_tree.h" +#include "intel_regions.h" +#include "intel_context.h" + +#include "intel_dri_resource_sharing.h" +#include "intel_dri_resource_sharing_int.h" + +#include <dlfcn.h> +/** + * Sets up a DRIImage structure to point to our shared image in a region + */ +static bool +intel_setup_cl_region_from_mipmap_tree(void *driver, + struct intel_context *intel, + struct intel_mipmap_tree *mt, + GLuint level, GLuint zoffset, + struct _intel_dri_share_image_region *region) +{ + unsigned int draw_x, draw_y; + uint32_t mask_x, mask_y; + struct intel_region *null_region = (struct intel_region *)NULL; + + intel_miptree_check_level_layer(mt, level, zoffset); + + _intel_region_get_tile_masks(mt->region, &mask_x, &mask_y, false); + _intel_miptree_get_image_offset(mt, level, zoffset, &draw_x, &draw_y); + + region->w = mt->level[level].width; + region->h = mt->level[level].height; + region->tile_x = draw_x & mask_x; + region->tile_y = draw_y & mask_y; + region->tiling = mt->region->tiling; + /* XXX hard code to 1 right now. */ + region->depth = 1; + region->row_pitch = mt->region->pitch; + + region->offset = _intel_region_get_aligned_offset(mt->region, + draw_x & ~mask_x, + draw_y & ~mask_y, + false); + if (!_intel_region_flink(mt->region, ®ion->name)) + return false; + _intel_region_reference(&null_region, mt->region); + return true; +} + +typedef void +_mesa_test_texobj_completeness_t( const struct gl_context *ctx, + struct gl_texture_object *t ); +_mesa_test_texobj_completeness_t *__mesa_test_texobj_completeness; + +typedef struct gl_texture_object * +_mesa_lookup_texture_t( const struct gl_context *ctx, GLuint id); +_mesa_lookup_texture_t *__mesa_lookup_texture; + +static struct gl_texture_object * +intel_get_gl_obj_from_texture(void *driver, + struct intel_context *intel, + GLenum target, GLint level, + GLuint texture, GLuint face) +{ + struct gl_texture_object *obj; + __mesa_lookup_texture = dlsym(driver, "_mesa_lookup_texture"); + obj = __mesa_lookup_texture(&intel->ctx, texture); + if (!obj || obj->Target != target) { + return NULL; + } + + __mesa_test_texobj_completeness = dlsym(driver, "_mesa_test_texobj_completeness"); + __mesa_test_texobj_completeness(&intel->ctx, obj); + if (!obj->_BaseComplete || (level > 0 && !obj->_MipmapComplete)) { + return NULL; + } + + if (level < obj->BaseLevel || level > obj->_MaxLevel) { + return NULL; + } + + return obj; +} + +static GLenum +get_cl_gl_format(gl_format format) +{ + switch (format) { + case MESA_FORMAT_RGBA8888: + return GL_RGBA; + case MESA_FORMAT_ARGB8888: + return GL_BGRA; + default: + return GL_BGRA; + } +} + +static bool +intelAcquireTexture(void *driver, __DRIcontext *context, GLenum target, + GLint level, GLuint texture, void *user_data) +{ + struct _intel_dri_share_image_region *region = intel_dri_share_image_region(user_data); + struct intel_context *intel = context->driverPrivate; + struct gl_texture_object *obj; + struct intel_texture_object *iobj; + /* XXX Always be face 0? */ + GLuint face = 0; + + obj = intel_get_gl_obj_from_texture(driver, intel, target, level, texture, face); + if (obj == NULL) + return false; + iobj = intel_texture_object(obj); + region->gl_format = get_cl_gl_format(obj->Image[face][level]->TexFormat); + return intel_setup_cl_region_from_mipmap_tree(driver, intel, iobj->mt, level, 0, region); +} + +static bool +intelReleaseTexture(void *driver, __DRIcontext *context, GLenum target, + GLint level, GLuint texture) +{ + struct intel_context *intel = context->driverPrivate; + struct gl_texture_object *obj; + struct intel_texture_object *iobj; + /* XXX Always be face 0? */ + GLuint face = 0; + + obj = intel_get_gl_obj_from_texture(driver, intel, target, level, texture, face); + if (obj == NULL) + return false; + + iobj = intel_texture_object(obj); + _intel_region_release(&iobj->mt->region); + return true; +} + +static bool +intelAcquireBufferObj(void *driver, __DRIcontext *driContextPriv, + GLuint bufobj, void *user_data) +{ + return false; +} + +static bool +intelReleaseBufferObj(void *driver, __DRIcontext *driContextPriv, GLuint bufobj) +{ + return false; +} + +static bool +intelAcquireRenderBuffer(void *driver, __DRIcontext *driContextPriv, + GLuint bufobj, void *user_data) +{ + return false; +} + +static bool +intelReleaseRenderBuffer(void *driver, __DRIcontext *driContextPriv, GLuint bufobj) +{ + return false; +} + +#include "cl_driver.h" +void +intel_set_cl_gl_callbacks(void) +{ + cl_gl_acquire_texture = (cl_gl_acquire_texture_cb*)intelAcquireTexture; + cl_gl_release_texture = (cl_gl_release_texture_cb*)intelReleaseTexture; + cl_gl_acquire_buffer_object = (cl_gl_acquire_buffer_object_cb*)intelAcquireBufferObj; + cl_gl_release_buffer_object = (cl_gl_release_buffer_object_cb*)intelReleaseBufferObj; + cl_gl_acquire_render_buffer = (cl_gl_acquire_render_buffer_cb*)intelAcquireRenderBuffer; + cl_gl_release_render_buffer = (cl_gl_release_render_buffer_cb*)intelReleaseRenderBuffer; +} diff --git a/src/intel/intel_dri_resource_sharing.h b/src/intel/intel_dri_resource_sharing.h new file mode 100644 index 00000000..6d2ce4df --- /dev/null +++ b/src/intel/intel_dri_resource_sharing.h @@ -0,0 +1,39 @@ +#ifndef __INTEL_DRI_RESOURCE_SHARING_H__ +#define __INTEL_DRI_RESOURCE_SHARING_H__ + +struct _intel_dri_share_image_region { + unsigned int name; + size_t w; + size_t h; + size_t depth; + size_t pitch; + int tiling; + size_t offset; + size_t tile_x; + size_t tile_y; + unsigned int gl_format; + size_t row_pitch, slice_pitch; +}; + +struct _intel_dri_share_buffer_object { + unsigned int name; + size_t sz; + size_t offset; +}; + +inline static struct _intel_dri_share_image_region * +intel_dri_share_image_region(void *user_data) +{ + return (struct _intel_dri_share_image_region *)user_data; +} + +inline static struct _intel_dri_share_buffer_object * +intel_dri_share_buffer_object(void *user_data) +{ + return (struct _intel_dri_share_buffer_object *)user_data; +} + +extern void intel_set_cl_gl_callbacks(void); + + +#endif diff --git a/src/intel/intel_dri_resource_sharing_int.h b/src/intel/intel_dri_resource_sharing_int.h new file mode 100644 index 00000000..c7b283a5 --- /dev/null +++ b/src/intel/intel_dri_resource_sharing_int.h @@ -0,0 +1,143 @@ +/***************************************************************** + * The following functions are copied from i965 driver, commit + * id 292368570a13501dfa95b1b0dd70966caf6ffc6b. Need to keep consistant + * with the dri driver installed on current system. + *****************************************************************/ +static bool +_intel_region_flink(struct intel_region *region, uint32_t *name) +{ + if (region->name == 0) { + if (drm_intel_bo_flink(region->bo, ®ion->name)) + return false; + } + + *name = region->name; + + return true; +} + +#define _DBG(...) +static void +_intel_region_release(struct intel_region **region_handle) +{ + struct intel_region *region = *region_handle; + + if (region == NULL) { + _DBG("%s NULL\n", __FUNCTION__); + return; + } + + _DBG("%s %p %d\n", __FUNCTION__, region, region->refcount - 1); + + ASSERT(region->refcount > 0); + region->refcount--; + + if (region->refcount == 0) { + drm_intel_bo_unreference(region->bo); + + free(region); + } + *region_handle = NULL; +} + +static void +_intel_region_reference(struct intel_region **dst, struct intel_region *src) +{ + _DBG("%s: %p(%d) -> %p(%d)\n", __FUNCTION__, + *dst, *dst ? (*dst)->refcount : 0, src, src ? src->refcount : 0); + + if (src != *dst) { + if (*dst) + _intel_region_release(dst); + + if (src) + src->refcount++; + *dst = src; + } +} + +/** + * This function computes masks that may be used to select the bits of the X + * and Y coordinates that indicate the offset within a tile. If the region is + * untiled, the masks are set to 0. + */ +static void +_intel_region_get_tile_masks(struct intel_region *region, + uint32_t *mask_x, uint32_t *mask_y, + bool map_stencil_as_y_tiled) +{ + int cpp = region->cpp; + uint32_t tiling = region->tiling; + + if (map_stencil_as_y_tiled) + tiling = I915_TILING_Y; + + switch (tiling) { + default: + assert(false); + case I915_TILING_NONE: + *mask_x = *mask_y = 0; + break; + case I915_TILING_X: + *mask_x = 512 / cpp - 1; + *mask_y = 7; + break; + case I915_TILING_Y: + *mask_x = 128 / cpp - 1; + *mask_y = 31; + break; + } +} + +/** + * Compute the offset (in bytes) from the start of the region to the given x + * and y coordinate. For tiled regions, caller must ensure that x and y are + * multiples of the tile size. + */ +static uint32_t +_intel_region_get_aligned_offset(struct intel_region *region, uint32_t x, + uint32_t y, bool map_stencil_as_y_tiled) +{ + int cpp = region->cpp; + uint32_t pitch = region->pitch; + uint32_t tiling = region->tiling; + + if (map_stencil_as_y_tiled) { + tiling = I915_TILING_Y; + + /* When mapping a W-tiled stencil buffer as Y-tiled, each 64-high W-tile + * gets transformed into a 32-high Y-tile. Accordingly, the pitch of + * the resulting region is twice the pitch of the original region, since + * each row in the Y-tiled view corresponds to two rows in the actual + * W-tiled surface. So we need to correct the pitch before computing + * the offsets. + */ + pitch *= 2; + } + + switch (tiling) { + default: + assert(false); + case I915_TILING_NONE: + return y * pitch + x * cpp; + case I915_TILING_X: + assert((x % (512 / cpp)) == 0); + assert((y % 8) == 0); + return y * pitch + x / (512 / cpp) * 4096; + case I915_TILING_Y: + assert((x % (128 / cpp)) == 0); + assert((y % 32) == 0); + return y * pitch + x / (128 / cpp) * 4096; + } +} + +static void +_intel_miptree_get_image_offset(struct intel_mipmap_tree *mt, + GLuint level, GLuint slice, + GLuint *x, GLuint *y) +{ + assert(slice < mt->level[level].depth); + + *x = mt->level[level].slice[slice].x_offset; + *y = mt->level[level].slice[slice].y_offset; +} diff --git a/src/intel/intel_driver.c b/src/intel/intel_driver.c index ef6e6c3c..1072a3db 100644 --- a/src/intel/intel_driver.c +++ b/src/intel/intel_driver.c @@ -45,6 +45,13 @@ * Zou Nan hai <nanhai.zou@intel.com> * */ + +#if defined(HAS_EGL) +#include "GL/gl.h" +#include "EGL/egl.h" +#include "x11/mesa_egl_extension.h" +#endif + #include "intel_driver.h" #include "intel_gpgpu.h" #include "intel_batchbuffer.h" @@ -65,6 +72,8 @@ #include "cl_alloc.h" #include "cl_context.h" #include "cl_driver.h" +#include "cl_device_id.h" +#include "cl_platform_id.h" #define SET_BLOCKED_SIGSET(DRIVER) do { \ sigset_t bl_mask; \ @@ -169,6 +178,7 @@ static void intel_driver_open(intel_driver_t *intel, cl_context_prop props) { int cardi; + char *driver_name; if (props != NULL && props->gl_type != CL_GL_NOSHARE && props->gl_type != CL_GL_GLX_DISPLAY @@ -182,7 +192,7 @@ intel_driver_open(intel_driver_t *intel, cl_context_prop props) if(intel->x11_display) { if((intel->dri_ctx = getDRI2State(intel->x11_display, DefaultScreen(intel->x11_display), - NULL))) + &driver_name))) intel_driver_init_shared(intel, intel->dri_ctx); else printf("X server found. dri2 connection failed! \n"); @@ -206,15 +216,9 @@ intel_driver_open(intel_driver_t *intel, cl_context_prop props) exit(-1); } -#if defined(HAS_GBM) && defined(HAS_EGL) +#ifdef HAS_EGL if (props && props->gl_type == CL_GL_EGL_DISPLAY) { assert(props->egl_display); - intel->gbm = gbm_create_device(intel->fd); - if (intel->gbm == NULL) { - printf("GBM device create failed.\n"); - exit(-1); - } - cl_gbm_set_image_extension(intel->gbm, (void*)props->egl_display); } #endif } @@ -222,9 +226,6 @@ intel_driver_open(intel_driver_t *intel, cl_context_prop props) static void intel_driver_close(intel_driver_t *intel) { -#ifdef HAS_GBM - if(intel->gbm) gbm_device_destroy(intel->gbm); -#endif if(intel->dri_ctx) dri_state_release(intel->dri_ctx); if(intel->x11_display) XCloseDisplay(intel->x11_display); if(intel->fd) close(intel->fd); @@ -404,11 +405,9 @@ intel_driver_get_ver(struct intel_driver *drv) static size_t drm_intel_bo_get_size(drm_intel_bo *bo) { return bo->size; } static void* drm_intel_bo_get_virtual(drm_intel_bo *bo) { return bo->virtual; } -#if defined(HAS_EGL) && defined(HAS_GBM) -#include "gbm.h" -#include "GL/gl.h" -#include "EGL/egl.h" -#include "EGL/eglext.h" +#if defined(HAS_EGL) +#include "intel_dri_resource_sharing.h" +#include "cl_image.h" static int get_cl_tiling(uint32_t drm_tiling) { switch(drm_tiling) { @@ -421,50 +420,166 @@ static int get_cl_tiling(uint32_t drm_tiling) return CL_NO_TILE; } -static unsigned int get_gl_format(uint32_t gbm_format) +static int cl_get_clformat_from_texture(GLint tex_format, cl_image_format * cl_format) { - switch(gbm_format) { - case GBM_FORMAT_ARGB8888: return GL_BGRA; - case GBM_FORMAT_ABGR8888: return GL_RGBA; + cl_int ret = CL_SUCCESS; + + switch (tex_format) { + case GL_RGBA8: + case GL_RGBA: + case GL_RGBA16: + case GL_RGBA8I: + case GL_RGBA16I: + case GL_RGBA32I: + case GL_RGBA8UI: + case GL_RGBA16UI: + case GL_RGBA32UI: + case GL_RGBA16F: + case GL_RGBA32F: + cl_format->image_channel_order = CL_RGBA; + break; + case GL_BGRA: + cl_format->image_channel_order = CL_BGRA; + break; default: - NOT_IMPLEMENTED; + ret = -1; + goto error; } - return 0; + + switch (tex_format) { + case GL_RGBA8: + case GL_RGBA: + case GL_BGRA: + cl_format->image_channel_data_type = CL_UNORM_INT8; + break; + case GL_RGBA16: + cl_format->image_channel_data_type = CL_UNORM_INT16; + break; + case GL_RGBA8I: + cl_format->image_channel_data_type = CL_SIGNED_INT8; + break; + case GL_RGBA16I: + cl_format->image_channel_data_type = CL_SIGNED_INT16; + break; + case GL_RGBA32I: + cl_format->image_channel_data_type = CL_SIGNED_INT32; + break; + case GL_RGBA8UI: + cl_format->image_channel_data_type = CL_UNSIGNED_INT8; + break; + case GL_RGBA16UI: + cl_format->image_channel_data_type = CL_UNSIGNED_INT16; + break; + case GL_RGBA32UI: + cl_format->image_channel_data_type = CL_UNSIGNED_INT32; + break; + case GL_RGBA16F: + cl_format->image_channel_data_type = CL_HALF_FLOAT; + break; + case GL_RGBA32F: + cl_format->image_channel_order = CL_FLOAT; + break; + default: + ret = -1; + goto error; + } + +error: + return ret; } -cl_buffer intel_alloc_buffer_from_eglimage(cl_context ctx, - void* image, - unsigned int *gl_format, - int *w, int *h, int *pitch, - int *tiling) +static int +get_mem_type_from_target(GLenum texture_target, cl_mem_object_type *type) { - struct gbm_bo *bo; - uint32_t gbm_format; - drm_intel_bo *intel_bo; - int32_t name; - uint32_t drm_tiling, swizzle; - EGLImageKHR egl_image = (EGLImageKHR)image; - intel_driver_t *intel = (intel_driver_t*)ctx->drv; - - bo = gbm_bo_import(intel->gbm, GBM_BO_IMPORT_EGL_IMAGE, (void*)egl_image, 0); - - *w = gbm_bo_get_width(bo); - *h = gbm_bo_get_height(bo); - *pitch = gbm_bo_get_stride(bo); - gbm_format = gbm_bo_get_format(bo); - *gl_format = get_gl_format(gbm_format); - name = cl_gbm_bo_get_name(bo); - - intel_bo = intel_driver_share_buffer((intel_driver_t *)ctx->drv, name); - - if (drm_intel_bo_get_tiling(intel_bo, &drm_tiling, &swizzle)!= 0) - assert(0); - *tiling = get_cl_tiling(drm_tiling); + switch(texture_target) { + case GL_TEXTURE_1D: *type = CL_MEM_OBJECT_IMAGE1D; break; + case GL_TEXTURE_2D: *type = CL_MEM_OBJECT_IMAGE2D; break; + case GL_TEXTURE_3D: *type = CL_MEM_OBJECT_IMAGE3D; break; + case GL_TEXTURE_1D_ARRAY: *type = CL_MEM_OBJECT_IMAGE1D_ARRAY; break; + case GL_TEXTURE_2D_ARRAY: *type = CL_MEM_OBJECT_IMAGE2D_ARRAY; break; + default: + return -1; + } + return CL_SUCCESS; +} - gbm_bo_destroy(bo); +static cl_buffer +intel_alloc_buffer_from_texture_egl(cl_context ctx, unsigned int target, + int miplevel, unsigned int texture, + struct _cl_mem_image *image) +{ + cl_buffer bo = (cl_buffer) NULL; + struct _intel_dri_share_image_region region; + unsigned int bpp, intel_fmt; + cl_image_format cl_format; + EGLBoolean ret; + EGLint attrib_list[] = { EGL_GL_TEXTURE_ID_MESA, texture, + EGL_GL_TEXTURE_LEVEL_MESA, miplevel, + EGL_GL_TEXTURE_TARGET_MESA, target, + EGL_NONE}; + ret = eglAcquireResourceMESA(EGL_DISP(ctx), EGL_CTX(ctx), + EGL_GL_TEXTURE_MESA, + &attrib_list[0], ®ion); + if (!ret) + goto out; + + bo = (cl_buffer)intel_driver_share_buffer((intel_driver_t *)ctx->drv, region.name); + + if (bo == NULL) { + eglReleaseResourceMESA(EGL_DISP(ctx), EGL_CTX(ctx), EGL_GL_TEXTURE_MESA, &attrib_list[0]); + goto out; + } + region.tiling = get_cl_tiling(region.tiling); + if (cl_get_clformat_from_texture(region.gl_format, &cl_format) != 0) + goto error; + intel_fmt = cl_image_get_intel_format(&cl_format); + if (intel_fmt == INTEL_UNSUPPORTED_FORMAT) + goto error; + cl_image_byte_per_pixel(&cl_format, &bpp); + cl_mem_object_type image_type; + if (get_mem_type_from_target(target, &image_type) != 0) + goto error; + + cl_mem_image_init(image, region.w, region.h, + image_type, region.depth, cl_format, + intel_fmt, bpp, region.row_pitch, + region.slice_pitch, region.tiling, + region.tile_x, region.tile_y, region.offset); +out: + return bo; - return (cl_buffer)intel_bo; +error: + cl_buffer_unreference(bo); + eglReleaseResourceMESA(EGL_DISP(ctx), EGL_CTX(ctx), EGL_GL_TEXTURE_MESA, &attrib_list[0]); + return NULL; +} +static cl_buffer +intel_alloc_buffer_from_texture(cl_context ctx, unsigned int target, + int miplevel, unsigned int texture, + struct _cl_mem_image *image) +{ + + if (IS_EGL_CONTEXT(ctx)) + return intel_alloc_buffer_from_texture_egl(ctx, target, miplevel, texture, image); + + return NULL; +} + +static int +intel_release_buffer_from_texture(cl_context ctx, unsigned int target, + int miplevel, unsigned int texture) +{ + if (IS_EGL_CONTEXT(ctx)) { + EGLint attrib_list[] = { EGL_GL_TEXTURE_ID_MESA, texture, + EGL_GL_TEXTURE_LEVEL_MESA, miplevel, + EGL_GL_TEXTURE_TARGET_MESA, target, + EGL_NONE}; + + eglReleaseResourceMESA(EGL_DISP(ctx), EGL_CTX(ctx), EGL_GL_TEXTURE_MESA, &attrib_list[0]); + return CL_SUCCESS; + } + return -1; } #endif @@ -510,8 +625,10 @@ intel_setup_callbacks(void) cl_driver_get_device_id = (cl_driver_get_device_id_cb *) intel_get_device_id; cl_buffer_alloc = (cl_buffer_alloc_cb *) drm_intel_bo_alloc; cl_buffer_set_tiling = (cl_buffer_set_tiling_cb *) intel_buffer_set_tiling; -#ifdef HAS_EGL - cl_buffer_alloc_from_eglimage = (cl_buffer_alloc_from_eglimage_cb *) intel_alloc_buffer_from_eglimage; +#if defined(HAS_EGL) + cl_buffer_alloc_from_texture = (cl_buffer_alloc_from_texture_cb *) intel_alloc_buffer_from_texture; + cl_buffer_release_from_texture = (cl_buffer_release_from_texture_cb *) intel_release_buffer_from_texture; + intel_set_cl_gl_callbacks(); #endif cl_buffer_reference = (cl_buffer_reference_cb *) drm_intel_bo_reference; cl_buffer_unreference = (cl_buffer_unreference_cb *) drm_intel_bo_unreference; @@ -528,4 +645,3 @@ intel_setup_callbacks(void) cl_buffer_wait_rendering = (cl_buffer_wait_rendering_cb *) drm_intel_bo_wait_rendering; intel_set_gpgpu_callbacks(); } - diff --git a/src/intel/intel_driver.h b/src/intel/intel_driver.h index f70f96a5..8042059a 100644 --- a/src/intel/intel_driver.h +++ b/src/intel/intel_driver.h @@ -54,9 +54,6 @@ #include <drm.h> #include <i915_drm.h> #include <intel_bufmgr.h> -#ifdef HAS_GBM -#include <gbm.h> -#endif #define CMD_MI (0x0 << 29) #define CMD_2D (0x2 << 29) @@ -90,9 +87,6 @@ typedef struct intel_driver int master; Display *x11_display; struct dri_state *dri_ctx; -#ifdef HAS_GBM - struct gbm_device *gbm; -#endif } intel_driver_t; /* device control */ diff --git a/src/x11/dricommon.h b/src/x11/dricommon.h index 08e66a5b..5a950b4b 100644 --- a/src/x11/dricommon.h +++ b/src/x11/dricommon.h @@ -94,11 +94,6 @@ void dri_state_release(dri_state_t*); // Create a dri2 state from dpy and screen dri_state_t *getDRI2State(Display* dpy, int screen, char **driver_name); -#ifdef HAS_GBM -#include<gbm.h> -void cl_gbm_set_image_extension(struct gbm_device *gbm, void *display); -int cl_gbm_bo_get_name(struct gbm_bo *bo); -#endif #endif /* _VA_DRICOMMON_H_ */ diff --git a/src/x11/gbm_deps/backend.h b/src/x11/gbm_deps/backend.h deleted file mode 100644 index 4a643750..00000000 --- a/src/x11/gbm_deps/backend.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright © 2011 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Benjamin Franzke <benjaminfranzke@googlemail.com> - */ - -#ifndef MODULE_H_ -#define MODULE_H_ - -#include "gbmint.h" - -struct gbm_device * -_gbm_create_device(int fd); - -#endif diff --git a/src/x11/gbm_deps/common.h b/src/x11/gbm_deps/common.h deleted file mode 100644 index 1fcdfcac..00000000 --- a/src/x11/gbm_deps/common.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright © 2011 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Benjamin Franzke <benjaminfranzke@googlemail.com> - */ - -#ifndef _COMMON_H_ -#define _COMMON_H_ - -#include <libudev.h> - -struct udev_device * -_gbm_udev_device_new_from_fd(struct udev *udev, int fd); - -char * -_gbm_fd_get_device_name(int fd); - -void -_gbm_log(const char *fmt_str, ...); - -#endif diff --git a/src/x11/gbm_deps/common_drm.h b/src/x11/gbm_deps/common_drm.h deleted file mode 100644 index d28c3f01..00000000 --- a/src/x11/gbm_deps/common_drm.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright © 2011 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Benjamin Franzke <benjaminfranzke@googlemail.com> - */ - -#ifndef _COMMON_DRM_H_ -#define _COMMON_DRM_H_ - -#include "gbmint.h" - -enum gbm_drm_driver_type { - GBM_DRM_DRIVER_TYPE_DRI, - GBM_DRM_DRIVER_TYPE_GALLIUM, -}; - -struct gbm_drm_device { - struct gbm_device base; - enum gbm_drm_driver_type type; - char *driver_name; -}; - -struct gbm_drm_bo { - struct gbm_bo base; -}; - -#endif diff --git a/src/x11/gbm_deps/gbm.h b/src/x11/gbm_deps/gbm.h deleted file mode 100644 index e516df2b..00000000 --- a/src/x11/gbm_deps/gbm.h +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright © 2011 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Benjamin Franzke <benjaminfranzke@googlemail.com> - */ - -#ifndef _GBM_H_ -#define _GBM_H_ - -#ifdef __cplusplus -extern "C" { -#endif - - -#define __GBM__ 1 - -#include <stdint.h> - -/** - * \file gbm.h - * \brief Generic Buffer Manager - */ - -struct gbm_device; -struct gbm_bo; -struct gbm_surface; - -/** - * \mainpage The Generic Buffer Manager - * - * This module provides an abstraction that the caller can use to request a - * buffer from the underlying memory management system for the platform. - * - * This allows the creation of portable code whilst still allowing access to - * the underlying memory manager. - */ - -/** - * Abstraction representing the handle to a buffer allocated by the - * manager - */ -union gbm_bo_handle { - void *ptr; - int32_t s32; - uint32_t u32; - int64_t s64; - uint64_t u64; -}; - -/** Format of the allocated buffer */ -enum gbm_bo_format { - /** RGB with 8 bits per channel in a 32 bit value */ - GBM_BO_FORMAT_XRGB8888, - /** ARGB with 8 bits per channel in a 32 bit value */ - GBM_BO_FORMAT_ARGB8888 -}; - -#define __gbm_fourcc_code(a,b,c,d) ((uint32_t)(a) | ((uint32_t)(b) << 8) | \ - ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24)) - -#define GBM_FORMAT_BIG_ENDIAN (1<<31) /* format is big endian instead of little endian */ - -/* color index */ -#define GBM_FORMAT_C8 __gbm_fourcc_code('C', '8', ' ', ' ') /* [7:0] C */ - -/* 8 bpp RGB */ -#define GBM_FORMAT_RGB332 __gbm_fourcc_code('R', 'G', 'B', '8') /* [7:0] R:G:B 3:3:2 */ -#define GBM_FORMAT_BGR233 __gbm_fourcc_code('B', 'G', 'R', '8') /* [7:0] B:G:R 2:3:3 */ - -/* 16 bpp RGB */ -#define GBM_FORMAT_XRGB4444 __gbm_fourcc_code('X', 'R', '1', '2') /* [15:0] x:R:G:B 4:4:4:4 little endian */ -#define GBM_FORMAT_XBGR4444 __gbm_fourcc_code('X', 'B', '1', '2') /* [15:0] x:B:G:R 4:4:4:4 little endian */ -#define GBM_FORMAT_RGBX4444 __gbm_fourcc_code('R', 'X', '1', '2') /* [15:0] R:G:B:x 4:4:4:4 little endian */ -#define GBM_FORMAT_BGRX4444 __gbm_fourcc_code('B', 'X', '1', '2') /* [15:0] B:G:R:x 4:4:4:4 little endian */ - -#define GBM_FORMAT_ARGB4444 __gbm_fourcc_code('A', 'R', '1', '2') /* [15:0] A:R:G:B 4:4:4:4 little endian */ -#define GBM_FORMAT_ABGR4444 __gbm_fourcc_code('A', 'B', '1', '2') /* [15:0] A:B:G:R 4:4:4:4 little endian */ -#define GBM_FORMAT_RGBA4444 __gbm_fourcc_code('R', 'A', '1', '2') /* [15:0] R:G:B:A 4:4:4:4 little endian */ -#define GBM_FORMAT_BGRA4444 __gbm_fourcc_code('B', 'A', '1', '2') /* [15:0] B:G:R:A 4:4:4:4 little endian */ - -#define GBM_FORMAT_XRGB1555 __gbm_fourcc_code('X', 'R', '1', '5') /* [15:0] x:R:G:B 1:5:5:5 little endian */ -#define GBM_FORMAT_XBGR1555 __gbm_fourcc_code('X', 'B', '1', '5') /* [15:0] x:B:G:R 1:5:5:5 little endian */ -#define GBM_FORMAT_RGBX5551 __gbm_fourcc_code('R', 'X', '1', '5') /* [15:0] R:G:B:x 5:5:5:1 little endian */ -#define GBM_FORMAT_BGRX5551 __gbm_fourcc_code('B', 'X', '1', '5') /* [15:0] B:G:R:x 5:5:5:1 little endian */ - -#define GBM_FORMAT_ARGB1555 __gbm_fourcc_code('A', 'R', '1', '5') /* [15:0] A:R:G:B 1:5:5:5 little endian */ -#define GBM_FORMAT_ABGR1555 __gbm_fourcc_code('A', 'B', '1', '5') /* [15:0] A:B:G:R 1:5:5:5 little endian */ -#define GBM_FORMAT_RGBA5551 __gbm_fourcc_code('R', 'A', '1', '5') /* [15:0] R:G:B:A 5:5:5:1 little endian */ -#define GBM_FORMAT_BGRA5551 __gbm_fourcc_code('B', 'A', '1', '5') /* [15:0] B:G:R:A 5:5:5:1 little endian */ - -#define GBM_FORMAT_RGB565 __gbm_fourcc_code('R', 'G', '1', '6') /* [15:0] R:G:B 5:6:5 little endian */ -#define GBM_FORMAT_BGR565 __gbm_fourcc_code('B', 'G', '1', '6') /* [15:0] B:G:R 5:6:5 little endian */ - -/* 24 bpp RGB */ -#define GBM_FORMAT_RGB888 __gbm_fourcc_code('R', 'G', '2', '4') /* [23:0] R:G:B little endian */ -#define GBM_FORMAT_BGR888 __gbm_fourcc_code('B', 'G', '2', '4') /* [23:0] B:G:R little endian */ - -/* 32 bpp RGB */ -#define GBM_FORMAT_XRGB8888 __gbm_fourcc_code('X', 'R', '2', '4') /* [31:0] x:R:G:B 8:8:8:8 little endian */ -#define GBM_FORMAT_XBGR8888 __gbm_fourcc_code('X', 'B', '2', '4') /* [31:0] x:B:G:R 8:8:8:8 little endian */ -#define GBM_FORMAT_RGBX8888 __gbm_fourcc_code('R', 'X', '2', '4') /* [31:0] R:G:B:x 8:8:8:8 little endian */ -#define GBM_FORMAT_BGRX8888 __gbm_fourcc_code('B', 'X', '2', '4') /* [31:0] B:G:R:x 8:8:8:8 little endian */ - -#define GBM_FORMAT_ARGB8888 __gbm_fourcc_code('A', 'R', '2', '4') /* [31:0] A:R:G:B 8:8:8:8 little endian */ -#define GBM_FORMAT_ABGR8888 __gbm_fourcc_code('A', 'B', '2', '4') /* [31:0] A:B:G:R 8:8:8:8 little endian */ -#define GBM_FORMAT_RGBA8888 __gbm_fourcc_code('R', 'A', '2', '4') /* [31:0] R:G:B:A 8:8:8:8 little endian */ -#define GBM_FORMAT_BGRA8888 __gbm_fourcc_code('B', 'A', '2', '4') /* [31:0] B:G:R:A 8:8:8:8 little endian */ - -#define GBM_FORMAT_XRGB2101010 __gbm_fourcc_code('X', 'R', '3', '0') /* [31:0] x:R:G:B 2:10:10:10 little endian */ -#define GBM_FORMAT_XBGR2101010 __gbm_fourcc_code('X', 'B', '3', '0') /* [31:0] x:B:G:R 2:10:10:10 little endian */ -#define GBM_FORMAT_RGBX1010102 __gbm_fourcc_code('R', 'X', '3', '0') /* [31:0] R:G:B:x 10:10:10:2 little endian */ -#define GBM_FORMAT_BGRX1010102 __gbm_fourcc_code('B', 'X', '3', '0') /* [31:0] B:G:R:x 10:10:10:2 little endian */ - -#define GBM_FORMAT_ARGB2101010 __gbm_fourcc_code('A', 'R', '3', '0') /* [31:0] A:R:G:B 2:10:10:10 little endian */ -#define GBM_FORMAT_ABGR2101010 __gbm_fourcc_code('A', 'B', '3', '0') /* [31:0] A:B:G:R 2:10:10:10 little endian */ -#define GBM_FORMAT_RGBA1010102 __gbm_fourcc_code('R', 'A', '3', '0') /* [31:0] R:G:B:A 10:10:10:2 little endian */ -#define GBM_FORMAT_BGRA1010102 __gbm_fourcc_code('B', 'A', '3', '0') /* [31:0] B:G:R:A 10:10:10:2 little endian */ - -/* packed YCbCr */ -#define GBM_FORMAT_YUYV __gbm_fourcc_code('Y', 'U', 'Y', 'V') /* [31:0] Cr0:Y1:Cb0:Y0 8:8:8:8 little endian */ -#define GBM_FORMAT_YVYU __gbm_fourcc_code('Y', 'V', 'Y', 'U') /* [31:0] Cb0:Y1:Cr0:Y0 8:8:8:8 little endian */ -#define GBM_FORMAT_UYVY __gbm_fourcc_code('U', 'Y', 'V', 'Y') /* [31:0] Y1:Cr0:Y0:Cb0 8:8:8:8 little endian */ -#define GBM_FORMAT_VYUY __gbm_fourcc_code('V', 'Y', 'U', 'Y') /* [31:0] Y1:Cb0:Y0:Cr0 8:8:8:8 little endian */ - -#define GBM_FORMAT_AYUV __gbm_fourcc_code('A', 'Y', 'U', 'V') /* [31:0] A:Y:Cb:Cr 8:8:8:8 little endian */ - -/* - * 2 plane YCbCr - * index 0 = Y plane, [7:0] Y - * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian - * or - * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian - */ -#define GBM_FORMAT_NV12 __gbm_fourcc_code('N', 'V', '1', '2') /* 2x2 subsampled Cr:Cb plane */ -#define GBM_FORMAT_NV21 __gbm_fourcc_code('N', 'V', '2', '1') /* 2x2 subsampled Cb:Cr plane */ -#define GBM_FORMAT_NV16 __gbm_fourcc_code('N', 'V', '1', '6') /* 2x1 subsampled Cr:Cb plane */ -#define GBM_FORMAT_NV61 __gbm_fourcc_code('N', 'V', '6', '1') /* 2x1 subsampled Cb:Cr plane */ - -/* - * 3 plane YCbCr - * index 0: Y plane, [7:0] Y - * index 1: Cb plane, [7:0] Cb - * index 2: Cr plane, [7:0] Cr - * or - * index 1: Cr plane, [7:0] Cr - * index 2: Cb plane, [7:0] Cb - */ -#define GBM_FORMAT_YUV410 __gbm_fourcc_code('Y', 'U', 'V', '9') /* 4x4 subsampled Cb (1) and Cr (2) planes */ -#define GBM_FORMAT_YVU410 __gbm_fourcc_code('Y', 'V', 'U', '9') /* 4x4 subsampled Cr (1) and Cb (2) planes */ -#define GBM_FORMAT_YUV411 __gbm_fourcc_code('Y', 'U', '1', '1') /* 4x1 subsampled Cb (1) and Cr (2) planes */ -#define GBM_FORMAT_YVU411 __gbm_fourcc_code('Y', 'V', '1', '1') /* 4x1 subsampled Cr (1) and Cb (2) planes */ -#define GBM_FORMAT_YUV420 __gbm_fourcc_code('Y', 'U', '1', '2') /* 2x2 subsampled Cb (1) and Cr (2) planes */ -#define GBM_FORMAT_YVU420 __gbm_fourcc_code('Y', 'V', '1', '2') /* 2x2 subsampled Cr (1) and Cb (2) planes */ -#define GBM_FORMAT_YUV422 __gbm_fourcc_code('Y', 'U', '1', '6') /* 2x1 subsampled Cb (1) and Cr (2) planes */ -#define GBM_FORMAT_YVU422 __gbm_fourcc_code('Y', 'V', '1', '6') /* 2x1 subsampled Cr (1) and Cb (2) planes */ -#define GBM_FORMAT_YUV444 __gbm_fourcc_code('Y', 'U', '2', '4') /* non-subsampled Cb (1) and Cr (2) planes */ -#define GBM_FORMAT_YVU444 __gbm_fourcc_code('Y', 'V', '2', '4') /* non-subsampled Cr (1) and Cb (2) planes */ - - -/** - * Flags to indicate the intended use for the buffer - these are passed into - * gbm_bo_create(). The caller must set the union of all the flags that are - * appropriate - * - * \sa Use gbm_device_is_format_supported() to check if the combination of format - * and use flags are supported - */ -enum gbm_bo_flags { - /** - * Buffer is going to be presented to the screen using an API such as KMS - */ - GBM_BO_USE_SCANOUT = (1 << 0), - /** - * Buffer is going to be used as cursor - the dimensions for the buffer - * must be 64x64 if this flag is passed. - */ - GBM_BO_USE_CURSOR_64X64 = (1 << 1), - /** - * Buffer is to be used for rendering - for example it is going to be used - * as the storage for a color buffer - */ - GBM_BO_USE_RENDERING = (1 << 2), - /** - * Buffer can be used for gbm_bo_write. This is guaranteed to work - * with GBM_BO_USE_CURSOR_64X64. but may not work for other - * combinations. - */ - GBM_BO_USE_WRITE = (1 << 3), -}; - -int -gbm_device_get_fd(struct gbm_device *gbm); - -const char * -gbm_device_get_backend_name(struct gbm_device *gbm); - -int -gbm_device_is_format_supported(struct gbm_device *gbm, - uint32_t format, uint32_t usage); - -void -gbm_device_destroy(struct gbm_device *gbm); - -struct gbm_device * -gbm_create_device(int fd); - -struct gbm_bo * -gbm_bo_create(struct gbm_device *gbm, - uint32_t width, uint32_t height, - uint32_t format, uint32_t flags); - -#define GBM_BO_IMPORT_WL_BUFFER 0x5501 -#define GBM_BO_IMPORT_EGL_IMAGE 0x5502 - -struct gbm_bo * -gbm_bo_import(struct gbm_device *gbm, uint32_t type, - void *buffer, uint32_t usage); - -uint32_t -gbm_bo_get_width(struct gbm_bo *bo); - -uint32_t -gbm_bo_get_height(struct gbm_bo *bo); - -uint32_t -gbm_bo_get_stride(struct gbm_bo *bo); - -uint32_t -gbm_bo_get_format(struct gbm_bo *bo); - -struct gbm_device * -gbm_bo_get_device(struct gbm_bo *bo); - -union gbm_bo_handle -gbm_bo_get_handle(struct gbm_bo *bo); - -int -gbm_bo_write(struct gbm_bo *bo, const void *buf, size_t count); - -void -gbm_bo_set_user_data(struct gbm_bo *bo, void *data, - void (*destroy_user_data)(struct gbm_bo *, void *)); - -void * -gbm_bo_get_user_data(struct gbm_bo *bo); - -void -gbm_bo_destroy(struct gbm_bo *bo); - -struct gbm_surface * -gbm_surface_create(struct gbm_device *gbm, - uint32_t width, uint32_t height, - uint32_t format, uint32_t flags); - -struct gbm_bo * -gbm_surface_lock_front_buffer(struct gbm_surface *surface); - -void -gbm_surface_release_buffer(struct gbm_surface *surface, struct gbm_bo *bo); - -int -gbm_surface_has_free_buffers(struct gbm_surface *surface); - -void -gbm_surface_destroy(struct gbm_surface *surface); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/x11/gbm_deps/gbm_driint.h b/src/x11/gbm_deps/gbm_driint.h deleted file mode 100644 index 18fc3c09..00000000 --- a/src/x11/gbm_deps/gbm_driint.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright © 2011 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Benjamin Franzke <benjaminfranzke@googlemail.com> - */ - -#ifndef _GBM_DRI_INTERNAL_H_ -#define _GBM_DRI_INTERNAL_H_ - -#include "gbmint.h" - -#include "common.h" -#include "common_drm.h" - -#include <GL/gl.h> /* dri_interface needs GL types */ -#include "GL/internal/dri_interface.h" - -struct gbm_dri_surface; - -struct gbm_dri_device { - struct gbm_drm_device base; - - void *driver; - - __DRIscreen *screen; - - __DRIcoreExtension *core; - __DRIdri2Extension *dri2; - __DRIimageExtension *image; - __DRI2flushExtension *flush; - __DRIdri2LoaderExtension *loader; - - const __DRIconfig **driver_configs; - const __DRIextension *extensions[4]; - - __DRIimage *(*lookup_image)(__DRIscreen *screen, void *image, void *data); - void *lookup_user_data; - - __DRIbuffer *(*get_buffers)(__DRIdrawable * driDrawable, - int *width, int *height, - unsigned int *attachments, int count, - int *out_count, void *data); - void (*flush_front_buffer)(__DRIdrawable * driDrawable, void *data); - __DRIbuffer *(*get_buffers_with_format)(__DRIdrawable * driDrawable, - int *width, int *height, - unsigned int *attachments, int count, - int *out_count, void *data); -}; - -struct gbm_dri_bo { - struct gbm_drm_bo base; - - __DRIimage *image; - - /* Only used for cursors */ - uint32_t handle, size; - void *map; -}; - -struct gbm_dri_surface { - struct gbm_surface base; - - void *dri_private; -}; - -static inline struct gbm_dri_device * -gbm_dri_device(struct gbm_device *gbm) -{ - return (struct gbm_dri_device *) gbm; -} - -static inline struct gbm_dri_bo * -gbm_dri_bo(struct gbm_bo *bo) -{ - return (struct gbm_dri_bo *) bo; -} - -static inline struct gbm_dri_surface * -gbm_dri_surface(struct gbm_surface *surface) -{ - return (struct gbm_dri_surface *) surface; -} - -char * -dri_fd_get_driver_name(int fd); - -#endif diff --git a/src/x11/gbm_deps/gbmint.h b/src/x11/gbm_deps/gbmint.h deleted file mode 100644 index a467beae..00000000 --- a/src/x11/gbm_deps/gbmint.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright © 2011 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Benjamin Franzke <benjaminfranzke@googlemail.com> - */ - -#ifndef INTERNAL_H_ -#define INTERNAL_H_ - -#include "gbm.h" -#include <sys/stat.h> - -/* GCC visibility */ -#if defined(__GNUC__) && __GNUC__ >= 4 -#define GBM_EXPORT __attribute__ ((visibility("default"))) -#else -#define GBM_EXPORT -#endif - -/** - * \file gbmint.h - * \brief Internal implementation details of gbm - */ - -/** - * The device used for the memory allocation. - * - * The members of this structure should be not accessed directly - */ -struct gbm_device { - /* Hack to make a gbm_device detectable by its first element. */ - struct gbm_device *(*dummy)(int); - - int fd; - const char *name; - unsigned int refcount; - struct stat stat; - - void (*destroy)(struct gbm_device *gbm); - int (*is_format_supported)(struct gbm_device *gbm, - uint32_t format, - uint32_t usage); - - struct gbm_bo *(*bo_create)(struct gbm_device *gbm, - uint32_t width, uint32_t height, - uint32_t format, - uint32_t usage); - struct gbm_bo *(*bo_import)(struct gbm_device *gbm, uint32_t type, - void *buffer, uint32_t usage); - int (*bo_write)(struct gbm_bo *bo, const void *buf, size_t data); - void (*bo_destroy)(struct gbm_bo *bo); - - struct gbm_surface *(*surface_create)(struct gbm_device *gbm, - uint32_t width, uint32_t height, - uint32_t format, uint32_t flags); - struct gbm_bo *(*surface_lock_front_buffer)(struct gbm_surface *surface); - void (*surface_release_buffer)(struct gbm_surface *surface, - struct gbm_bo *bo); - int (*surface_has_free_buffers)(struct gbm_surface *surface); - void (*surface_destroy)(struct gbm_surface *surface); -}; - -/** - * The allocated buffer object. - * - * The members in this structure should not be accessed directly. - */ -struct gbm_bo { - struct gbm_device *gbm; - uint32_t width; - uint32_t height; - uint32_t stride; - uint32_t format; - union gbm_bo_handle handle; - void *user_data; - void (*destroy_user_data)(struct gbm_bo *, void *); -}; - -struct gbm_surface { - struct gbm_device *gbm; - uint32_t width; - uint32_t height; - uint32_t format; - uint32_t flags; -}; - -struct gbm_backend { - const char *backend_name; - struct gbm_device *(*create_device)(int fd); -}; - -GBM_EXPORT struct gbm_device * -_gbm_mesa_get_device(int fd); - -#endif diff --git a/src/x11/gbm_dri2_x11_platform.c b/src/x11/gbm_dri2_x11_platform.c deleted file mode 100644 index 481f4072..00000000 --- a/src/x11/gbm_dri2_x11_platform.c +++ /dev/null @@ -1,126 +0,0 @@ -#include <string.h> -#include "GL/gl.h" /* dri_interface need gl types definitions. */ -#include "GL/internal/dri_interface.h" -#include "gbm_deps/gbm_driint.h" -#include "gbm_deps/gbmint.h" -#include "dricommon.h" - -typedef struct EGLDisplay _EGLDisplay; -typedef struct EGLDriver _EGLDriver; -/* XXX should check whether we support pthread.*/ -typedef pthread_mutex_t _EGLMutex; - -enum _egl_platform_type { - _EGL_PLATFORM_WINDOWS, - _EGL_PLATFORM_X11, - _EGL_PLATFORM_WAYLAND, - _EGL_PLATFORM_DRM, - _EGL_PLATFORM_FBDEV, - _EGL_PLATFORM_NULL, - _EGL_PLATFORM_ANDROID, - - _EGL_NUM_PLATFORMS, - _EGL_INVALID_PLATFORM = -1 -}; -typedef enum _egl_platform_type _EGLPlatformType; -typedef unsigned int EGLBoolean; -typedef int32_t EGLint; - -struct _hack_egl_display -{ - /* used to link displays */ - _EGLDisplay *Next; - - _EGLMutex Mutex; - - _EGLPlatformType Platform; /**< The type of the platform display */ - void *PlatformDisplay; /**< A pointer to the platform display */ - - _EGLDriver *Driver; /**< Matched driver of the display */ - - EGLBoolean Initialized; /**< True if the display is initialized */ - - /* options that affect how the driver initializes the display */ - struct { - EGLBoolean TestOnly; /**< Driver should not set fields when true */ - EGLBoolean UseFallback; /**< Use fallback driver (sw or less features) */ - } Options; - - /* these fields are set by the driver during init */ - void *DriverData; /**< Driver private data */ - EGLint VersionMajor; /**< EGL major version */ - EGLint VersionMinor; /**< EGL minor version */ - EGLint ClientAPIs; /**< Bitmask of APIs supported (EGL_xxx_BIT) */ -}; - -struct _hack_dri2_egl_display -{ - int dri2_major; - int dri2_minor; - __DRIscreen *dri_screen; - int own_dri_screen; - const __DRIconfig **driver_configs; - void *driver; - __DRIcoreExtension *core; - __DRIdri2Extension *dri2; - __DRIswrastExtension *swrast; - __DRI2flushExtension *flush; - __DRItexBufferExtension *tex_buffer; - __DRIimageExtension *image; - __DRIrobustnessExtension *robustness; - __DRI2configQueryExtension *config; - int fd; - - int own_device; - int swap_available; - int invalidate_available; - int min_swap_interval; - int max_swap_interval; - int default_swap_interval; - struct gbm_dri_device *gbm_dri; - - char *device_name; - char *driver_name; - - __DRIdri2LoaderExtension dri2_loader_extension; - __DRIswrastLoaderExtension swrast_loader_extension; - const __DRIextension *extensions[4]; -}; - -static __DRIimageLookupExtension *image_lookup_extension; - -/* We are use DRI2 x11 platform, and by default, gbm doesn't register - * a valid image extension, and actually, it doesn't know how to register - * it based on current interface. We have to hack it here. */ -void cl_gbm_set_image_extension(struct gbm_device *gbm, void *display) -{ - struct gbm_dri_device *gbm_dri = gbm_dri_device(gbm); - struct _hack_egl_display *egl_dpy = (struct _hack_egl_display*)display; - struct _hack_dri2_egl_display *dri2_dpy = (struct _hack_dri2_egl_display*)egl_dpy->DriverData; - int i; - - if (gbm_dri->lookup_image == NULL - && egl_dpy->Platform == _EGL_PLATFORM_X11) { - for(i = 0; i < 4; i++) - if (dri2_dpy->extensions[i] - && ((strncmp(dri2_dpy->extensions[i]->name, - __DRI_IMAGE_LOOKUP, - sizeof(__DRI_IMAGE_LOOKUP))) == 0)) - break; - if (i >= 4) return; - image_lookup_extension = (__DRIimageLookupExtension*)dri2_dpy->extensions[i]; - gbm_dri->lookup_image = image_lookup_extension->lookupEGLImage; - gbm_dri->lookup_user_data = display; - } -} - -int cl_gbm_bo_get_name(struct gbm_bo *bo) -{ - int name; - struct gbm_dri_device *gbm_dri = gbm_dri_device(bo->gbm); - struct gbm_dri_bo *bo_dri = gbm_dri_bo(bo); - - gbm_dri->image->queryImage(bo_dri->image, __DRI_IMAGE_ATTRIB_NAME, - &name); - return name; -} diff --git a/src/x11/mesa_egl_extension.c b/src/x11/mesa_egl_extension.c new file mode 100644 index 00000000..a7fc8cba --- /dev/null +++ b/src/x11/mesa_egl_extension.c @@ -0,0 +1,307 @@ +#include <stdio.h> +#include "mesa_egl_extension.h" +#include "mesa_egl_res_share.h" +#include "src/cl_driver.h" + +struct _egl_display; +struct _egl_resource; +struct _egl_thread_info; +struct _egl_config; +struct _egl_surface; +struct _egl_driver; + +typedef struct _egl_display _EGLDisplay; +typedef struct _egl_resource _EGLResource; +typedef struct _egl_thread_info _EGLThreadInfo; +typedef struct _egl_config _EGLConfig; +typedef struct _egl_surface _EGLSurface; +typedef struct _egl_driver _EGLDriver; + +/** + * A resource of a display. + */ +struct _egl_resource +{ + /* which display the resource belongs to */ + _EGLDisplay *Display; + EGLBoolean IsLinked; + EGLint RefCount; + + /* used to link resources of the same type */ + _EGLResource *Next; +}; + +/** + * "Base" class for device driver contexts. + */ +struct _egl_context +{ + /* A context is a display resource */ + _EGLResource Resource; + + /* The bound status of the context */ + _EGLThreadInfo *Binding; + _EGLSurface *DrawSurface; + _EGLSurface *ReadSurface; + + _EGLConfig *Config; + + EGLint ClientAPI; /**< EGL_OPENGL_ES_API, EGL_OPENGL_API, EGL_OPENVG_API */ + EGLint ClientMajorVersion; + EGLint ClientMinorVersion; + EGLint Flags; + EGLint Profile; + EGLint ResetNotificationStrategy; + + /* The real render buffer when a window surface is bound */ + EGLint WindowRenderBuffer; +}; + +typedef struct _egl_context _EGLContext; + +struct dri2_egl_display +{ + int dri2_major; + int dri2_minor; + __DRIscreen *dri_screen; + int own_dri_screen; + const __DRIconfig **driver_configs; + void *driver; +}; + +enum _egl_platform_type { + _EGL_PLATFORM_WINDOWS, + _EGL_PLATFORM_X11, + _EGL_PLATFORM_WAYLAND, + _EGL_PLATFORM_DRM, + _EGL_PLATFORM_FBDEV, + _EGL_PLATFORM_NULL, + _EGL_PLATFORM_ANDROID, + + _EGL_NUM_PLATFORMS, + _EGL_INVALID_PLATFORM = -1 +}; +typedef enum _egl_platform_type _EGLPlatformType; + +typedef pthread_mutex_t _EGLMutex; + +struct _egl_display +{ + /* used to link displays */ + _EGLDisplay *Next; + + _EGLMutex Mutex; + + _EGLPlatformType Platform; /**< The type of the platform display */ + void *PlatformDisplay; /**< A pointer to the platform display */ + + _EGLDriver *Driver; /**< Matched driver of the display */ + EGLBoolean Initialized; /**< True if the display is initialized */ + + /* options that affect how the driver initializes the display */ + struct { + EGLBoolean TestOnly; /**< Driver should not set fields when true */ + EGLBoolean UseFallback; /**< Use fallback driver (sw or less features) */ + } Options; + + /* these fields are set by the driver during init */ + void *DriverData; /**< Driver private data */ +}; + +static struct dri2_egl_display * +dri2_egl_display(_EGLDisplay *dpy) +{ + return (struct dri2_egl_display *)dpy->DriverData; +} + +static _EGLDisplay * +_eglLockDisplay(EGLDisplay dpy) +{ + return (_EGLDisplay *)dpy; +} + +static _EGLContext * +_eglLookupContext(EGLContext ctx, EGLDisplay disp) +{ + disp = disp; + return (_EGLContext *) ctx; +} + +struct dri2_egl_context +{ + _EGLContext base; + __DRIcontext *dri_context; +}; + +static struct dri2_egl_context * +dri2_egl_context(_EGLContext *ctx) +{ + return (struct dri2_egl_context *)ctx; +} + +static EGLBoolean +dri2_acquire_texture(_EGLDisplay *disp, + _EGLContext *ctx, + const EGLint *attr_list, + void *user_data) +{ + struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + GLuint texture = 0; + GLenum gl_target = 0; + GLint level = 0; + GLboolean ret; + + if (_eglParseTextureAttribList(&texture, &gl_target, &level, attr_list) != EGL_SUCCESS) + return EGL_FALSE; + + ret = cl_gl_acquire_texture(dri2_dpy->driver, + dri2_ctx->dri_context, + gl_target, level, texture, + user_data); + return ret; +} + +static EGLBoolean +dri2_release_texture(_EGLDisplay *disp, _EGLContext *ctx, const EGLint *attr_list) +{ + struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + GLuint texture = 0; + GLenum gl_target = 0; + GLint level = 0; + GLboolean ret; + + if (_eglParseTextureAttribList(&texture, &gl_target, &level, attr_list) != EGL_SUCCESS) + return EGL_FALSE; + + ret = cl_gl_release_texture(dri2_dpy->driver, dri2_ctx->dri_context, + gl_target, level, texture); + return ret; +} + +static EGLBoolean +dri2_acquire_buffer_object(_EGLDisplay *disp, _EGLContext *ctx, const EGLint *attr_list, + void *user_data) +{ + struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + GLuint bufobj = 0; + GLboolean ret; + + if (_eglParseBufferObjAttribList(&bufobj, attr_list) != EGL_SUCCESS) + return EGL_FALSE; + + ret = cl_gl_acquire_buffer_object(dri2_dpy->driver, + dri2_ctx->dri_context, + bufobj, user_data); + return ret; +} + +static EGLBoolean +dri2_release_buffer_object(_EGLDisplay *disp, _EGLContext *ctx, const EGLint *attr_list) +{ + struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + GLuint bufobj = 0; + GLboolean ret; + + if (_eglParseBufferObjAttribList(&bufobj, attr_list) != EGL_SUCCESS) + return EGL_FALSE; + + ret = cl_gl_release_buffer_object(dri2_dpy->driver, + dri2_ctx->dri_context, + bufobj); + return ret; +} + +static EGLBoolean +dri2_acquire_render_buffer(_EGLDisplay *disp, + _EGLContext *ctx, + const EGLint *attr_list, + void *user_data) +{ + struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + GLuint rb = 0; + GLboolean ret; + + if (_eglParseBufferObjAttribList(&rb, attr_list) != EGL_SUCCESS) + return EGL_FALSE; + + ret = cl_gl_acquire_render_buffer(dri2_dpy->driver, + dri2_ctx->dri_context, + rb, user_data); + return ret; +} + +static EGLBoolean +dri2_release_render_buffer(_EGLDisplay *disp, _EGLContext *ctx, const EGLint *attr_list) +{ + struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + GLuint rb = 0; + GLboolean ret; + + if (_eglParseBufferObjAttribList(&rb, attr_list) != EGL_SUCCESS) + return EGL_FALSE; + + ret = cl_gl_release_render_buffer(dri2_dpy->driver, + dri2_ctx->dri_context, + rb); + return ret; +} + +static EGLBoolean +dri2_acquire_resource_mesa(_EGLDisplay *disp, _EGLContext *ctx, const EGLenum target, + const EGLint *attrib_list, void *user_data) +{ + switch (target) { + case EGL_GL_TEXTURE_MESA: + return dri2_acquire_texture(disp, ctx, attrib_list, user_data); + case EGL_GL_BUFFER_OBJECT_MESA: + return dri2_acquire_buffer_object(disp, ctx, attrib_list, user_data); + case EGL_GL_RENDER_BUFFER_MESA: + return dri2_acquire_render_buffer(disp, ctx, attrib_list, user_data); + default: + fprintf(stderr, "bad resource target value 0x%04x", + target); + } + return EGL_FALSE; +} + +static EGLBoolean +dri2_release_resource_mesa(_EGLDisplay *disp, _EGLContext *ctx, const EGLenum target, + const EGLint *attrib_list) +{ + switch (target) { + case EGL_GL_TEXTURE_MESA: + return dri2_release_texture(disp, ctx, attrib_list); + case EGL_GL_BUFFER_OBJECT_MESA: + return dri2_release_buffer_object(disp, ctx, attrib_list); + case EGL_GL_RENDER_BUFFER_MESA: + return dri2_release_render_buffer(disp, ctx, attrib_list); + default: + fprintf(stderr, "bad resource target value 0x%04x", + target); + } + return EGL_FALSE; +} + +EGLBoolean +eglAcquireResourceMESA(EGLDisplay dpy, EGLContext ctx, EGLenum target, const EGLint *attrib_list, void *user) +{ + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLContext *context = _eglLookupContext(ctx, disp); + + return dri2_acquire_resource_mesa(disp, context, target, attrib_list, user); +} + +EGLBoolean +eglReleaseResourceMESA(EGLDisplay dpy, EGLContext ctx, EGLenum target, const EGLint *attrib_list) +{ + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLContext *context = _eglLookupContext(ctx, disp); + + return dri2_release_resource_mesa(disp, context, target, attrib_list); +} diff --git a/src/x11/mesa_egl_extension.h b/src/x11/mesa_egl_extension.h new file mode 100644 index 00000000..39ea1349 --- /dev/null +++ b/src/x11/mesa_egl_extension.h @@ -0,0 +1,20 @@ +#ifndef __MESA_EGL_EXTENSION_H__ +#define __MESA_EGL_EXTENSION_H__ + +#include <EGL/egl.h> +#include <GL/gl.h> +#include <GL/internal/dri_interface.h> + +#define EGL_GL_TEXTURE_MESA 0x3300 /* eglAcuireResource target */ +#define EGL_GL_BUFFER_OBJECT_MESA 0x3301 /* eglAcuireResource target */ +#define EGL_GL_RENDER_BUFFER_MESA 0x3302 /* eglAcuireResource target */ +#define EGL_GL_TEXTURE_ID_MESA 0x3303 /* eglAcuireResource attribute */ +#define EGL_GL_TEXTURE_LEVEL_MESA 0x3304 /* eglAcuireResource attribute */ +#define EGL_GL_TEXTURE_TARGET_MESA 0x3305 /* eglAcuireResource attribute */ +#define EGL_GL_BUFFER_OBJECT_ID_MESA 0x3306 /* eglAcuireResource attribute */ +#define EGL_GL_RENDER_BUFFER_ID_MESA 0x3307 /* eglAcuireResource attribute */ + +EGLBoolean eglAcquireResourceMESA(EGLDisplay dpy, EGLContext ctx, EGLenum target, const EGLint *attrib_list, void * user_data); +EGLBoolean eglReleaseResourceMESA(EGLDisplay dpy, EGLContext ctx, EGLenum target, const EGLint *attrib_list); + +#endif diff --git a/src/x11/mesa_egl_res_share.c b/src/x11/mesa_egl_res_share.c new file mode 100644 index 00000000..93e94549 --- /dev/null +++ b/src/x11/mesa_egl_res_share.c @@ -0,0 +1,135 @@ +/************************************************************************** + * + * Copyright 2013-2014 Zhigang Gong <zhigang.gong@linux.intel.com> + * Copyright 2013-2014 Intel, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include <assert.h> +#include <string.h> + +#include "mesa_egl_extension.h" +#include "mesa_egl_res_share.h" + +/** + * Parse the list of share texture attributes and return the proper error code. + */ +EGLint +_eglParseTextureAttribList(unsigned int *texture, EGLenum *gl_target, EGLint *level, + const EGLint *attrib_list) +{ + EGLint i, err = EGL_SUCCESS; + + *texture = 0; + *gl_target = 0; + *level = 0; + + if (!attrib_list) + return EGL_BAD_ATTRIBUTE; + + for (i = 0; attrib_list[i] != EGL_NONE; i++) { + EGLint attr = attrib_list[i++]; + EGLint val = attrib_list[i]; + + switch (attr) { + case EGL_GL_TEXTURE_LEVEL_MESA: + *level = val; + break; + case EGL_GL_TEXTURE_ID_MESA: + *texture = val; + break; + case EGL_GL_TEXTURE_TARGET_MESA: + *gl_target = val; + break; + default: + /* unknown attrs are ignored */ + break; + } + } + + return err; +} + +/** + * Parse the list of share texture attributes and return the proper error code. + */ +EGLint +_eglParseBufferObjAttribList(unsigned int *bufobj, const EGLint *attrib_list) +{ + EGLint i, err = EGL_SUCCESS; + *bufobj = 0; + + if (!attrib_list) + return EGL_BAD_ATTRIBUTE; + + for (i = 0; attrib_list[i] != EGL_NONE; i++) { + EGLint attr = attrib_list[i++]; + EGLint val = attrib_list[i]; + + switch (attr) { + case EGL_GL_BUFFER_OBJECT_ID_MESA: + *bufobj = val; + break; + default: + /* unknown attrs are ignored */ + break; + } + } + if (*bufobj == 0) + err = EGL_BAD_ATTRIBUTE; + + return err; +} + +/** + * Parse the list of share texture attributes and return the proper error code. + */ +EGLint +_eglParseRenderBufferAttribList(unsigned int *rb, const EGLint *attrib_list) +{ + EGLint i, err = EGL_SUCCESS; + *rb = 0; + + if (!attrib_list) + return EGL_BAD_ATTRIBUTE; + + for (i = 0; attrib_list[i] != EGL_NONE; i++) { + EGLint attr = attrib_list[i++]; + EGLint val = attrib_list[i]; + + switch (attr) { + case EGL_GL_RENDER_BUFFER_ID_MESA: + *rb = val; + break; + default: + /* unknown attrs are ignored */ + break; + } + } + if (*rb == 0) + err = EGL_BAD_ATTRIBUTE; + + return err; +} diff --git a/src/x11/mesa_egl_res_share.h b/src/x11/mesa_egl_res_share.h new file mode 100644 index 00000000..43e746ec --- /dev/null +++ b/src/x11/mesa_egl_res_share.h @@ -0,0 +1,44 @@ +/************************************************************************** + * + * Copyright 2013-2014 Zhigang Gong <zhigang.gong@linux.intel.com> + * Copyright 2013-2014 Intel, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef EGLRESSHARE_INCLUDED +#define EGLRESSHARE_INCLUDED + +#include <EGL/egl.h> + +EGLint +_eglParseTextureAttribList(unsigned int *texture, EGLenum *gl_target, + EGLint *level, const EGLint *attrib_list); +EGLint +_eglParseBufferObjAttribList(unsigned int *bufobj, + const EGLint *attrib_list); + +EGLint +_eglParseRenderBufferAttribList(unsigned int *rb, const EGLint *attrib_list); +#endif |