/*
* 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: Zhigang Gong
*/
#include
#include
#include
#ifdef HAS_GL_EGL
#include
#endif
#include "cl_platform_id.h"
#include "cl_device_id.h"
#include "cl_context.h"
#include "cl_command_queue.h"
#include "cl_program.h"
#include "cl_kernel.h"
#include "cl_mem.h"
#include "cl_image.h"
#include "cl_sampler.h"
#include "cl_alloc.h"
#include "cl_utils.h"
#include "cl_enqueue.h"
#include "cl_event.h"
#include "CL/cl.h"
#include "CL/cl_gl.h"
#include "CL/cl_intel.h"
#include "cl_mem_gl.h"
#define CHECK_GL_CONTEXT(CTX) \
do { \
if (UNLIKELY(CTX->props.gl_type == CL_GL_NOSHARE)) { \
err = CL_INVALID_CONTEXT; \
goto error; \
} \
} while (0)
cl_mem
clCreateFromGLBuffer(cl_context context,
cl_mem_flags flags,
GLuint bufobj,
cl_int * errcode_ret)
{
cl_mem mem = NULL;
cl_int err = CL_SUCCESS;
CHECK_CONTEXT (context);
CHECK_GL_CONTEXT (context);
mem = cl_mem_new_gl_buffer(context, flags, bufobj, &err);
error:
if (errcode_ret)
*errcode_ret = err;
return mem;
}
cl_mem
clCreateFromGLTexture2D(cl_context context,
cl_mem_flags flags,
GLenum texture_target,
GLint miplevel,
GLuint texture,
cl_int * errcode_ret)
{
cl_mem mem = NULL;
cl_int err = CL_SUCCESS;
CHECK_CONTEXT (context);
CHECK_GL_CONTEXT (context);
mem = cl_mem_new_gl_texture(context, flags, texture_target, miplevel, texture, &err);
error:
if (errcode_ret)
*errcode_ret = err;
return mem;
}
cl_mem
clCreateFromGLTexture3D(cl_context context,
cl_mem_flags flags,
GLenum texture_target,
GLint miplevel,
GLuint texture,
cl_int * errcode_ret)
{
NOT_IMPLEMENTED;
}
cl_mem
clCreateFromGLTexture(cl_context context,
cl_mem_flags flags,
cl_GLenum target,
cl_GLint miplevel,
cl_GLuint texture,
cl_int * errcode_ret)
{
cl_mem mem = NULL;
cl_int err = CL_SUCCESS;
CHECK_CONTEXT (context);
CHECK_GL_CONTEXT (context);
//We just support GL_TEXTURE_2D now.
if(target != GL_TEXTURE_2D){
err = CL_INVALID_VALUE;
goto error;
}
mem = cl_mem_new_gl_texture(context, flags, target, miplevel, texture, &err);
error:
if (errcode_ret)
*errcode_ret = err;
return mem;
}
/* XXX NULL function currently. */
cl_int clEnqueueAcquireGLObjects (cl_command_queue command_queue,
cl_uint num_objects,
const cl_mem *mem_objects,
cl_uint num_events_in_wait_list,
const cl_event *event_wait_list,
cl_event *event)
{
cl_int err = CL_SUCCESS;
cl_int e_status, i;
cl_event e = NULL;
enqueue_data *data = NULL;
do {
if (!CL_OBJECT_IS_COMMAND_QUEUE(command_queue)) {
err = CL_INVALID_COMMAND_QUEUE;
break;
}
if (UNLIKELY(command_queue->ctx->props.gl_type == CL_GL_NOSHARE)) {
err = CL_INVALID_CONTEXT;
break;
}
if ((num_objects == 0 && mem_objects != NULL) ||
(num_objects > 0 && mem_objects == NULL)) {
err = CL_INVALID_VALUE;
break;
}
for (i = 0; i < num_objects; i++) {
if (!cl_mem_image(mem_objects[i])) {
err = CL_INVALID_MEM_OBJECT;
break;
}
if (!IS_GL_IMAGE(mem_objects[i])) {
err = CL_INVALID_GL_OBJECT;
break;
}
}
if (err != CL_SUCCESS) {
break;
}
err = cl_event_check_waitlist(num_events_in_wait_list, event_wait_list,
event, command_queue->ctx);
if (err != CL_SUCCESS) {
break;
}
e = cl_event_create(command_queue->ctx, command_queue, num_events_in_wait_list,
event_wait_list, CL_COMMAND_ACQUIRE_GL_OBJECTS, &err);
if (err != CL_SUCCESS) {
break;
}
e_status = cl_event_is_ready(e);
data = &e->exec_data;
data->type = EnqueueReturnSuccesss;
if (cl_command_queue_allow_bypass_submit(command_queue) && (e_status == CL_COMPLETE)) {
// Sync mode, no need to queue event.
err = cl_event_exec(e, CL_COMPLETE, CL_FALSE);
if (err != CL_SUCCESS) {
break;
}
} else {
err = cl_event_exec(e, CL_SUBMITTED, CL_TRUE); // Submit to get the address.
if (err != CL_SUCCESS) {
break;
}
cl_command_queue_enqueue_event(command_queue, e);
}
} while (0);
if (err == CL_SUCCESS && event) {
*event = e;
} else {
cl_event_delete(e);
}
return err;
}
/* XXX NULL function currently. */
cl_int clEnqueueReleaseGLObjects (cl_command_queue command_queue,
cl_uint num_objects,
const cl_mem *mem_objects,
cl_uint num_events_in_wait_list,
const cl_event *event_wait_list,
cl_event *event)
{
cl_int err = CL_SUCCESS;
cl_int e_status, i;
cl_event e = NULL;
enqueue_data *data = NULL;
do {
if (!CL_OBJECT_IS_COMMAND_QUEUE(command_queue)) {
err = CL_INVALID_COMMAND_QUEUE;
break;
}
if (UNLIKELY(command_queue->ctx->props.gl_type == CL_GL_NOSHARE)) {
err = CL_INVALID_CONTEXT;
break;
}
if ((num_objects == 0 && mem_objects != NULL) ||
(num_objects > 0 && mem_objects == NULL)) {
err = CL_INVALID_VALUE;
break;
}
for (i = 0; i < num_objects; i++) {
if (!cl_mem_image(mem_objects[i])) {
err = CL_INVALID_MEM_OBJECT;
break;
}
if (!IS_GL_IMAGE(mem_objects[i])) {
err = CL_INVALID_GL_OBJECT;
break;
}
}
if (err != CL_SUCCESS) {
break;
}
err = cl_event_check_waitlist(num_events_in_wait_list, event_wait_list,
event, command_queue->ctx);
if (err != CL_SUCCESS) {
break;
}
e = cl_event_create(command_queue->ctx, command_queue, num_events_in_wait_list,
event_wait_list, CL_COMMAND_ACQUIRE_GL_OBJECTS, &err);
if (err != CL_SUCCESS) {
break;
}
e_status = cl_event_is_ready(e);
data = &e->exec_data;
data->type = EnqueueReturnSuccesss;
if (cl_command_queue_allow_bypass_submit(command_queue) && (e_status == CL_COMPLETE)) {
// Sync mode, no need to queue event.
err = cl_event_exec(e, CL_COMPLETE, CL_FALSE);
if (err != CL_SUCCESS) {
break;
}
} else {
err = cl_event_exec(e, CL_SUBMITTED, CL_TRUE); // Submit to get the address.
if (err != CL_SUCCESS) {
break;
}
cl_command_queue_enqueue_event(command_queue, e);
}
} while (0);
if (err == CL_SUCCESS && event) {
*event = e;
} else {
cl_event_delete(e);
}
return err;
}