예제 #1
0
파일: mem.cpp 프로젝트: Agorath/freeocl
	cl_int clEnqueueUnmapMemObjectFCL (cl_command_queue command_queue,
									cl_mem memobj,
									void *mapped_ptr,
									cl_uint num_events_in_wait_list,
									const cl_event *event_wait_list,
									cl_event *event)
	{
		MSG(clEnqueueUnmapMemObjectFCL);
		FreeOCL::unlocker unlock;
		if (!FreeOCL::is_valid(command_queue))
			return CL_INVALID_COMMAND_QUEUE;
		unlock.handle(command_queue);

		if (!FreeOCL::is_valid(command_queue->context))
			return CL_INVALID_CONTEXT;
		command_queue->context->unlock();

		if (!FreeOCL::is_valid(memobj))
			return CL_INVALID_MEM_OBJECT;
		unlock.handle(memobj);

		FreeOCL::smartptr<FreeOCL::command_unmap_buffer> cmd = new FreeOCL::command_unmap_buffer;
		cmd->num_events_in_wait_list = num_events_in_wait_list;
		cmd->event_wait_list = event_wait_list;
		cmd->event = event ? new _cl_event(command_queue->context) : NULL;
		cmd->buffer = memobj;
		cmd->ptr = mapped_ptr;

		if (cmd->event)
		{
			*event = cmd->event.weak();
			cmd->event->command_queue = command_queue;
			cmd->event->command_type = CL_COMMAND_UNMAP_MEM_OBJECT;
			cmd->event->status = CL_QUEUED;
		}
		unlock.forget(command_queue);
		command_queue->enqueue(cmd);

		return CL_SUCCESS;
	}
예제 #2
0
파일: mem.cpp 프로젝트: Agorath/freeocl
	cl_int clEnqueueCopyBufferFCL (cl_command_queue command_queue,
								cl_mem src_buffer,
								cl_mem dst_buffer,
								size_t src_offset,
								size_t dst_offset,
								size_t cb,
								cl_uint num_events_in_wait_list,
								const cl_event *event_wait_list,
								cl_event *event)
	{
		MSG(clEnqueueCopyBufferFCL);
		FreeOCL::unlocker unlock;
		if (!FreeOCL::is_valid(command_queue))
			return CL_INVALID_COMMAND_QUEUE;
		unlock.handle(command_queue);

		if (!FreeOCL::is_valid(command_queue->context))
			return CL_INVALID_CONTEXT;
		command_queue->context->unlock();

		if (!FreeOCL::is_valid(src_buffer))
			return CL_INVALID_MEM_OBJECT;
		unlock.handle(src_buffer);
		if (src_buffer->size < src_offset + cb)
			return CL_INVALID_VALUE;

		if (dst_buffer != src_buffer)		// Don't lock it twice if it's the same buffer
		{
			if (!FreeOCL::is_valid(dst_buffer))
				return CL_INVALID_MEM_OBJECT;
			unlock.handle(dst_buffer);
			if (dst_buffer->size < dst_offset + cb)
				return CL_INVALID_VALUE;
		}

		if (src_buffer == dst_buffer
			&& std::max(src_offset, dst_offset) - std::min(src_offset, dst_offset) < cb)
			return CL_MEM_COPY_OVERLAP;

		FreeOCL::smartptr<FreeOCL::command_copy_buffer> cmd = new FreeOCL::command_copy_buffer;
		cmd->num_events_in_wait_list = num_events_in_wait_list;
		cmd->event_wait_list = event_wait_list;
		cmd->event = event ? new _cl_event(command_queue->context) : NULL;
		cmd->src_buffer = src_buffer;
		cmd->src_offset = src_offset;
		cmd->dst_buffer = dst_buffer;
		cmd->dst_offset = dst_offset;
		cmd->cb = cb;

		if (cmd->event)
		{
			cmd->event->command_queue = command_queue;
			cmd->event->command_type = CL_COMMAND_COPY_BUFFER;
			cmd->event->status = CL_QUEUED;
		}

		if (event)
			*event = cmd->event.weak();

		unlock.forget(command_queue);
		command_queue->enqueue(cmd);

		return CL_SUCCESS;
	}
예제 #3
0
파일: mem.cpp 프로젝트: Agorath/freeocl
	void * clEnqueueMapBufferFCL (cl_command_queue command_queue,
							   cl_mem buffer,
							   cl_bool blocking_map,
							   cl_map_flags map_flags,
							   size_t offset,
							   size_t cb,
							   cl_uint num_events_in_wait_list,
							   const cl_event *event_wait_list,
							   cl_event *event,
							   cl_int *errcode_ret)
	{
		MSG(clEnqueueMapBufferFCL);
		if (map_flags & ~(CL_MAP_READ | CL_MAP_WRITE | CL_MAP_WRITE_INVALIDATE_REGION))
		{
			SET_RET(CL_INVALID_VALUE);
			return NULL;
		}
		FreeOCL::unlocker unlock;
		if (!FreeOCL::is_valid(command_queue))
		{
			SET_RET(CL_INVALID_COMMAND_QUEUE);
			return NULL;
		}
		unlock.handle(command_queue);

		if (!FreeOCL::is_valid(command_queue->context))
		{
			SET_RET(CL_INVALID_CONTEXT);
			return NULL;
		}
		command_queue->context->unlock();

		if (!FreeOCL::is_valid(buffer))
		{
			SET_RET(CL_INVALID_MEM_OBJECT);
			return NULL;
		}
		unlock.handle(buffer);

		if (buffer->size < offset + cb)
		{
			SET_RET(CL_INVALID_VALUE);
			return NULL;
		}

		void *p = (char*)buffer->ptr + offset;
		if ((num_events_in_wait_list == 0 || event_wait_list == NULL) && blocking_map == CL_FALSE)
		{
			buffer->mapped.insert(p);
			if (event)
			{
				cl_event e = new _cl_event(command_queue->context);
				*event = e;
				e->command_queue = command_queue;
				e->command_type = CL_COMMAND_MAP_BUFFER;
				e->status = CL_QUEUED;
				e->change_status(CL_QUEUED);
				e->change_status(CL_SUBMITTED);
				e->change_status(CL_RUNNING);
				e->change_status(CL_COMPLETE);
			}
		}
		else
		{
			FreeOCL::smartptr<FreeOCL::command_map_buffer> cmd = new FreeOCL::command_map_buffer;
			cmd->num_events_in_wait_list = num_events_in_wait_list;
			cmd->event_wait_list = event_wait_list;
			cmd->event = (blocking_map == CL_TRUE || event) ? new _cl_event(command_queue->context) : NULL;
			if (cmd->event)
			{
				cmd->event->command_queue = command_queue;
				cmd->event->command_type = CL_COMMAND_MAP_BUFFER;
				cmd->event->status = CL_QUEUED;
				if (event)
					*event = cmd->event.weak();
			}
			cmd->buffer = buffer;
			cmd->ptr = p;

			unlock.forget(command_queue);
			command_queue->enqueue(cmd);
			unlock.unlockall();

			if (blocking_map == CL_TRUE)
			{
				clWaitForEventsFCL(1, &cmd->event.weak());
				if (event == NULL)
					clReleaseEventFCL(cmd->event.weak());
			}
		}
		SET_RET(CL_SUCCESS);
		return p;
	}
예제 #4
0
파일: mem.cpp 프로젝트: Agorath/freeocl
	cl_int clEnqueueWriteBufferFCL (cl_command_queue command_queue,
								 cl_mem buffer,
								 cl_bool blocking_write,
								 size_t offset,
								 size_t cb,
								 const void *ptr,
								 cl_uint num_events_in_wait_list,
								 const cl_event *event_wait_list,
								 cl_event *event)
	{
		MSG(clEnqueueWriteBufferFCL);
		FreeOCL::unlocker unlock;
		if (ptr == NULL)
			return CL_INVALID_VALUE;

		if (!FreeOCL::is_valid(command_queue))
			return CL_INVALID_COMMAND_QUEUE;
		unlock.handle(command_queue);

		if (!FreeOCL::is_valid(command_queue->context))
			return CL_INVALID_CONTEXT;
		command_queue->context->unlock();

		if (!FreeOCL::is_valid(buffer))
			return CL_INVALID_MEM_OBJECT;
		unlock.handle(buffer);

		if (!FreeOCL::is_valid(buffer->context))
			return CL_INVALID_CONTEXT;
		buffer->context->unlock();

		if (buffer->context != command_queue->context)
			return CL_INVALID_CONTEXT;

		if (buffer->size < offset + cb)
			return CL_INVALID_VALUE;

		if (buffer->flags & (CL_MEM_HOST_NO_ACCESS | CL_MEM_HOST_READ_ONLY))
			return CL_INVALID_OPERATION;

		if (event_wait_list == NULL && num_events_in_wait_list > 0)
			return CL_INVALID_EVENT_WAIT_LIST;

		if (event_wait_list != NULL && num_events_in_wait_list == 0)
			return CL_INVALID_EVENT_WAIT_LIST;

		for(size_t i = 0 ; i < num_events_in_wait_list ; ++i)
		{
			if (!FreeOCL::is_valid(event_wait_list[i]))
				return CL_INVALID_EVENT_WAIT_LIST;
			unlock.handle(event_wait_list[i]);
		}

		if (blocking_write == CL_TRUE)
		{
			for(size_t i = 0 ; i < num_events_in_wait_list ; ++i)
				if (event_wait_list[i]->status < 0)
					return CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST;
		}

		FreeOCL::smartptr<FreeOCL::command_write_buffer> cmd = new FreeOCL::command_write_buffer;
		cmd->num_events_in_wait_list = num_events_in_wait_list;
		cmd->event_wait_list = event_wait_list;
		cmd->event = (blocking_write == CL_TRUE || event) ? new _cl_event(command_queue->context) : NULL;
		cmd->buffer = buffer;
		cmd->offset = offset;
		cmd->cb = cb;
		cmd->ptr = ptr;

		if (cmd->event)
		{
			cmd->event->command_queue = command_queue;
			cmd->event->command_type = CL_COMMAND_WRITE_BUFFER;
			cmd->event->status = CL_QUEUED;
		}

		if (event)
			*event = cmd->event.weak();

		unlock.forget(command_queue);
		command_queue->enqueue(cmd);

		unlock.unlockall();

		if (blocking_write == CL_TRUE)
		{
			clWaitForEventsFCL(1, &(cmd->event.weak()));
			if (event == NULL)
				clReleaseEventFCL(cmd->event.weak());
		}

		return CL_SUCCESS;
	}