예제 #1
0
/**
 * @private
 */
void printDeviceUsageLine(OutputStream* outputStream, char header, Device* device, bool showOnlyProblem) {
    DeviceInterface* deviceInterface = device->deviceInterface;

    int argumentLength = deviceInterface->deviceGetInterface(header, DEVICE_MODE_INPUT, true);
    int resultLength = deviceInterface->deviceGetInterface(header, DEVICE_MODE_OUTPUT, true);
    if (showOnlyProblem) {
        OutputStream nullOutputStream;
        initNullOutputStream(&nullOutputStream);
        bool ok = printMethodOrNotificationMetaData(&nullOutputStream, deviceInterface, header, argumentLength, resultLength, false);
        // If there is a problem, we relaunch with a real outputStream
        if (!ok) {
            printMethodOrNotificationMetaData(outputStream, deviceInterface, header, argumentLength, resultLength, false);
        }
    }
    else{
        printMethodOrNotificationMetaData(outputStream, deviceInterface, header, argumentLength, resultLength, false);
    }
}
예제 #2
0
Image::Image (const DeviceInterface&	vk,
			  const VkDevice			device,
			  Allocator&				allocator,
			  const VkImageCreateInfo&	imageCreateInfo,
			  const MemoryRequirement	memoryRequirement)
{
	m_image = createImage(vk, device, &imageCreateInfo);
	m_allocation = allocator.allocate(getImageMemoryRequirements(vk, device, *m_image), memoryRequirement);
	VK_CHECK(vk.bindImageMemory(device, *m_image, m_allocation->getMemory(), m_allocation->getOffset()));
}
예제 #3
0
Buffer::Buffer (const DeviceInterface&		vk,
				const VkDevice				device,
				Allocator&					allocator,
				const VkBufferCreateInfo&	bufferCreateInfo,
				const MemoryRequirement		memoryRequirement)
{
	m_buffer = createBuffer(vk, device, &bufferCreateInfo);
	m_allocation = allocator.allocate(getBufferMemoryRequirements(vk, device, *m_buffer), memoryRequirement);
	VK_CHECK(vk.bindBufferMemory(device, *m_buffer, m_allocation->getMemory(), m_allocation->getOffset()));
}
예제 #4
0
std::vector<VkImage> getSwapchainImages (const DeviceInterface&			vkd,
										 VkDevice						device,
										 VkSwapchainKHR					swapchain)
{
	deUint32	numImages	= 0;

	VK_CHECK(vkd.getSwapchainImagesKHR(device, swapchain, &numImages, DE_NULL));

	if (numImages > 0)
	{
		std::vector<VkImage>	images	(numImages);

		VK_CHECK(vkd.getSwapchainImagesKHR(device, swapchain, &numImages, &images[0]));

		return images;
	}
	else
		return std::vector<VkImage>();
}
예제 #5
0
void beginCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
{
	const VkCommandBufferBeginInfo commandBufBeginParams =
	{
		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType					sType;
		DE_NULL,										// const void*						pNext;
		0u,												// VkCommandBufferUsageFlags		flags;
		(const VkCommandBufferInheritanceInfo*)DE_NULL,
	};
	VK_CHECK(vk.beginCommandBuffer(commandBuffer, &commandBufBeginParams));
}
예제 #6
0
void invalidateMappedMemoryRange (const DeviceInterface& vkd, VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size)
{
	const VkMappedMemoryRange	range	=
	{
		VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
		DE_NULL,
		memory,
		offset,
		size
	};

	VK_CHECK(vkd.invalidateMappedMemoryRanges(device, 1u, &range));
}
예제 #7
0
QVariant deviceNameColumnData(const Device::Node& node, DeviceInterface& dev, int role)
{
    static const QFont italicFont{[] () { QFont f; f.setItalic(true); return f; }()};

    using namespace iscore;

    switch(role)
    {
        case Qt::DisplayRole:
        case Qt::EditRole:
            return node.get<DeviceSettings>().name;
        case Qt::FontRole:
        {
            if(!dev.connected())
                return italicFont;
        }
        default:
            return {};
    }
}
예제 #8
0
void bindImagePlaneMemory (const DeviceInterface&	vkd,
						   VkDevice					device,
						   VkImage					image,
						   VkDeviceMemory			memory,
						   VkDeviceSize				memoryOffset,
						   VkImageAspectFlagBits	planeAspect)
{
	const VkBindImagePlaneMemoryInfo	planeInfo	=
	{
		VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO_KHR,
		DE_NULL,
		planeAspect
	};
	const VkBindImageMemoryInfo			coreInfo	=
	{
		VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO_KHR,
		&planeInfo,
		image,
		memory,
		memoryOffset,
	};

	VK_CHECK(vkd.bindImageMemory2(device, 1u, &coreInfo));
}
예제 #9
0
void endCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
{
	VK_CHECK(vk.endCommandBuffer(commandBuffer));
}
예제 #10
0
cl_int MemObject::init()
{
    // Get the device list of the context
    DeviceInterface **devices = 0;
    cl_int rs;

    rs = ((Context *)parent())->info(CL_CONTEXT_NUM_DEVICES,
                                     sizeof(unsigned int),
                                     &p_num_devices, 0);

    if (rs != CL_SUCCESS)
        return rs;

    p_devices_to_allocate = p_num_devices;
    devices = (DeviceInterface **)std::malloc(p_num_devices *
                                        sizeof(DeviceInterface *));

    if (!devices)
        return CL_OUT_OF_HOST_MEMORY;

    rs = ((Context *)parent())->info(CL_CONTEXT_DEVICES,
                                     p_num_devices * sizeof(DeviceInterface *),
                                     devices, 0);

    if (rs != CL_SUCCESS)
    {
        std::free((void *)devices);
        return rs;
    }

    // Allocate a table of DeviceBuffers
    p_devicebuffers = (DeviceBuffer **)std::malloc(p_num_devices *
                                             sizeof(DeviceBuffer *));

    if (!p_devicebuffers)
    {
        std::free((void *)devices);
        return CL_OUT_OF_HOST_MEMORY;
    }

    // If we have more than one device, the allocation on the devices is
    // defered to first use, so host_ptr can become invalid. So, copy it in
    // a RAM location and keep it. Also, set a flag telling CPU devices that
    // they don't need to reallocate and re-copy host_ptr
    if (p_num_devices > 1 && (p_flags & CL_MEM_COPY_HOST_PTR))
    {
        void *tmp_hostptr = std::malloc(size());

        if (!tmp_hostptr)
        {
            std::free((void *)devices);
            return CL_OUT_OF_HOST_MEMORY;
        }

        std::memcpy(tmp_hostptr, p_host_ptr, size());

        p_host_ptr = tmp_hostptr;
        // Now, the client application can safely std::free() its host_ptr
    }

    // Create a DeviceBuffer for each device
    unsigned int failed_devices = 0;

    for (unsigned int i=0; i<p_num_devices; ++i)
    {
        DeviceInterface *device = devices[i];

        rs = CL_SUCCESS;
        p_devicebuffers[i] = device->createDeviceBuffer(this, &rs);

        if (rs != CL_SUCCESS)
        {
            p_devicebuffers[i] = 0;
            failed_devices++;
        }
    }

    if (failed_devices == p_num_devices)
    {
        // Each device found a reason to reject the buffer, so it's invalid
        std::free((void *)devices);
        return rs;
    }

    std::free((void *)devices);
    devices = 0;

    // If we have only one device, already allocate the buffer
    if (p_num_devices == 1)
    {
        if (!p_devicebuffers[0]->allocate())
            return CL_MEM_OBJECT_ALLOCATION_FAILURE;
    }

    return CL_SUCCESS;
}
예제 #11
0
/**
 * @private
 */
void printDeviceNotificationLine(OutputStream* outputStream, unsigned char header, Device* device) {
    DeviceInterface* deviceInterface = device->deviceInterface;

    int argumentLength = deviceInterface->deviceGetInterface(header, DEVICE_MODE_NOTIFY, true);
    printMethodOrNotificationMetaData(outputStream, deviceInterface, header, argumentLength, 0, true);
}
예제 #12
0
DeviceContext::DeviceContext(bool disableFateTime)
{
	HINSTANCE drv;
	ctor_b_InitDeviceDriver InitDeviceDriverPtr;
	last_timestamp = 0.0;
	// read in the csv file and parse it, then load the standard device driver and initialize it
	// the csv file is called plugins.csv
	errorMessage = DEVICE_NO_ERROR;
	std::string line, all("");
	std::string envPath;
	std::string plgsPath;

	ifstream plugins;

	// Before we get the path out of the registry, we try to get the current working directory

	char workingDir[_MAX_PATH];
	getcwd(workingDir,_MAX_PATH);
	
	// try to open plugin.csv from the current working directory, if there is no such file fallback and use the path from the registry, which was set at the installation

	envPath = workingDir;

	for(unsigned int i=0;i<envPath.length();i++)
	{
		if (envPath[i] == '\\'){
			envPath.insert(i,1,'\\');
			i++;
		}
	}


	plgsPath = envPath;
	plgsPath.append("\\\\plugins.csv");
	plugins.open(plgsPath.c_str(),ios::out |ios::binary);
	if(plugins.fail())
	{
		// we fallback and try the registry entry
	

		// NOTE: the installer of the lib, or the developer has to SET THE environment variable AMBIENT to the path where the lib is
		// this is because the library can be used by a variety of programs and every program has it's own working directory
		char *en;
		size_t si;
		errno_t err = _dupenv_s(&en,&si,"AMBIENT");
		if(err) return;		// nothing loaded, no available registry path
		envPath = en;
		// convert to nt path
	
		for(unsigned int i=0;i<envPath.length();i++)
		{
			if (envPath[i] == '\\'){
				envPath.insert(i,1,'\\');
				i++;
			}
		}
	
		plgsPath = envPath;
	
		plgsPath.append("\\\\plugins.csv");
		plugins.open(plgsPath.c_str(),ios::out | ios::binary);
	}

	if(plugins.fail())
	{
		cout << "Error opening:"<< plgsPath << endl;
		MessageBox(NULL,plgsPath.c_str(),"Ambient Library - Error", MB_OK);
		errorMessage = DEVICE_ERROR_OPEN_DRIVER_LIST ;
	}else
	{
		while(plugins.good()){

			getline(plugins,line);
			all.append(line);
		}
	}
	plugins.close();

	// parse the file
	//MessageBox(NULL,all.c_str(), "MUH", MB_OK);
	std::vector<std::string> devs = Utils::StringSplit(all,";");
	
	// now we know which drivers to load, because the number after every dll specifies which ones we are going to load

	// after loading the dll, query it and save which effects it can handle

	for(unsigned int i=0;i<devs.size();i+=2){
	
		if(atoi(devs[i+1].c_str()) == LOAD_DRIVER)
		{
			
			wchar_t *libText;
			std::string pt = envPath;
			pt.append("\\\\plugins\\\\");
			
			
			pt.append(devs[i].c_str());
			
			libText = new wchar_t[strlen(pt.c_str())+1];
			memset(libText,0,strlen(pt.c_str())+1);
			MultiByteToWideChar(CP_ACP,NULL,pt.c_str(),-1,libText,strlen(pt.c_str())+1);
			
			drv = LoadLibrary(pt.c_str());
			delete []libText;
		
			if(drv != NULL){
				
				// dll got loaded properly

				// get our entrypoint
				InitDeviceDriverPtr = (ctor_b_InitDeviceDriver) GetProcAddress(drv,"ctor_b_InitDeviceDriver");

				if (NULL != InitDeviceDriverPtr)
				{
					// add the driver to our list
					DeviceInterface *devI = InitDeviceDriverPtr(disableFateTime);	

					ptr<std::vector<int>> vec;				// we are responsible for the vector ...

					vec = new std::vector<int>();			

					devI->getSupportedSensoryEffects(vec);

					devices.insert(pair<DeviceInterface *,ptr<std::vector<int>>>(devI,vec));
					// now we have our driver loaded
			    	cout << "Loaded device driver successfuly!"<< endl;
					
					loadedPlugins.push_back(drv);
					
				}else{
					std::string error_msg;
					error_msg.append("Error at loading driver: ");
					error_msg.append(devs[i].c_str());
					MessageBox(NULL, error_msg.c_str(), "Ambient Library - Error", MB_OK);
					cout << "Error at loading driver: "<< devs[i].c_str() << endl;
					errorMessage = DEVICE_ERROR_LOADING_DRIVERS;
					FreeLibrary(drv);
				}

			}else{
				cout << "No such device driver could be found: " << devs[i].c_str() << endl;
			}

		}else{

			//MessageBox(NULL, devs[i].c_str(), "Not Loading..", MB_OK);
		}
	}
}
예제 #13
0
MovePtr<Allocation> bindBufferDedicated (const InstanceInterface& vki, const DeviceInterface& vkd, const VkPhysicalDevice physDevice, const VkDevice device, const VkBuffer buffer, const MemoryRequirement requirement)
{
	MovePtr<Allocation> alloc(allocateDedicated(vki, vkd, physDevice, device, buffer, requirement));
	VK_CHECK(vkd.bindBufferMemory(device, buffer, alloc->getMemory(), alloc->getOffset()));
	return alloc;
}
예제 #14
0
MovePtr<Allocation> bindBuffer (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkBuffer buffer, const MemoryRequirement requirement)
{
	MovePtr<Allocation> alloc(allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), requirement));
	VK_CHECK(vk.bindBufferMemory(device, buffer, alloc->getMemory(), alloc->getOffset()));
	return alloc;
}
예제 #15
0
MovePtr<Allocation> bindImage (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkImage image, const MemoryRequirement requirement)
{
	MovePtr<Allocation> alloc = allocator.allocate(getImageMemoryRequirements(vk, device, image), requirement);
	VK_CHECK(vk.bindImageMemory(device, image, alloc->getMemory(), alloc->getOffset()));
	return alloc;
}
예제 #16
0
/*
 * Native kernel
 */
NativeKernelEvent::NativeKernelEvent(CommandQueue *parent,
                                     void (*user_func)(void *),
                                     void *args,
                                     size_t cb_args,
                                     cl_uint num_mem_objects,
                                     const MemObject **mem_list,
                                     const void **args_mem_loc,
                                     cl_uint num_events_in_wait_list,
                                     const Event **event_wait_list,
                                     cl_int *errcode_ret)
: Event (parent, Queued, num_events_in_wait_list, event_wait_list, errcode_ret),
  p_user_func((void *)user_func), p_args(0)
{
    if (*errcode_ret != CL_SUCCESS) return;

    // Parameters sanity
    if (!user_func)
    {
        *errcode_ret = CL_INVALID_VALUE;
        return;
    }

    if (!args && (cb_args || num_mem_objects))
    {
        *errcode_ret = CL_INVALID_VALUE;
        return;
    }

    if (args && !cb_args)
    {
        *errcode_ret = CL_INVALID_VALUE;
        return;
    }

    if (num_mem_objects && (!mem_list || !args_mem_loc))
    {
        *errcode_ret = CL_INVALID_VALUE;
        return;
    }

    if (!num_mem_objects && (mem_list || args_mem_loc))
    {
        *errcode_ret = CL_INVALID_VALUE;
        return;
    }

    // Check that the device can execute a native kernel
    DeviceInterface *device;
    cl_device_exec_capabilities caps;

    *errcode_ret = parent->info(CL_QUEUE_DEVICE, sizeof(DeviceInterface *),
                                &device, 0);

    if (*errcode_ret != CL_SUCCESS)
        return;

    *errcode_ret = device->info(CL_DEVICE_EXECUTION_CAPABILITIES,
                                sizeof(cl_device_exec_capabilities), &caps, 0);

    if (*errcode_ret != CL_SUCCESS)
        return;

    if ((caps & CL_EXEC_NATIVE_KERNEL) == 0)
    {
        *errcode_ret = CL_INVALID_OPERATION;
        return;
    }

    // Copy the arguments in a new list
    if (cb_args)
    {
        p_args = std::malloc(cb_args);

        if (!p_args)
        {
            *errcode_ret = CL_OUT_OF_HOST_MEMORY;
            return;
        }

        std::memcpy((void *)p_args, (void *)args, cb_args);

        // Replace memory objects with global pointers
        for (cl_uint i=0; i<num_mem_objects; ++i)
        {
            const MemObject *buffer = mem_list[i];
            const char *loc = (const char *)args_mem_loc[i];

            if (!buffer)
            {
                *errcode_ret = CL_INVALID_MEM_OBJECT;
                return;
            }

            // We need to do relocation : loc is in args, we need it in p_args
            size_t delta = (char *)p_args - (char *)args;
            loc += delta;

            *(void **)loc = buffer->deviceBuffer(device)->nativeGlobalPointer();
        }
    }
}
예제 #17
0
/*
 * Kernel event
 */
KernelEvent::KernelEvent(CommandQueue *parent,
                         Kernel *kernel,
                         cl_uint work_dim,
                         const size_t *global_work_offset,
                         const size_t *global_work_size,
                         const size_t *local_work_size,
                         cl_uint num_events_in_wait_list,
                         const Event **event_wait_list,
                         cl_int *errcode_ret)
: Event(parent, Queued, num_events_in_wait_list, event_wait_list, errcode_ret),
  p_work_dim(work_dim), p_kernel(kernel)
{
  // TODO This is where everything else needs to be handled. Need to try to use
  // device specific methods though.
#ifdef DBG_EVENT
  std::cerr << "Entering KernelEvent::KernelEvent\n";
#endif
    if (*errcode_ret != CL_SUCCESS) return;

    *errcode_ret = CL_SUCCESS;

    // Sanity checks
    if (!kernel)
    {
        *errcode_ret = CL_INVALID_KERNEL;
        return;
    }

    // Check that the kernel was built for parent's device.
    DeviceInterface *device;
    Context *k_ctx, *q_ctx;
    size_t max_work_group_size;
    cl_uint max_dims = 0;

    *errcode_ret = parent->info(CL_QUEUE_DEVICE, sizeof(DeviceInterface *),
                                &device, 0);

    if (*errcode_ret != CL_SUCCESS)
        return;

    *errcode_ret = parent->info(CL_QUEUE_CONTEXT, sizeof(Context *), &q_ctx, 0);
    *errcode_ret |= kernel->info(CL_KERNEL_CONTEXT, sizeof(Context *), &k_ctx, 0);
    *errcode_ret |= device->info(CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(size_t),
                                &max_work_group_size, 0);
    *errcode_ret |= device->info(CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, sizeof(size_t),
                                &max_dims, 0);
    *errcode_ret |= device->info(CL_DEVICE_MAX_WORK_ITEM_SIZES,
                                max_dims * sizeof(size_t), p_max_work_item_sizes, 0);

    if (*errcode_ret != CL_SUCCESS)
        return;

    p_dev_kernel = kernel->deviceDependentKernel(device);
#ifdef DBG_EVENT
    std::cerr << "got deviceDependentKernel\n";
#endif

    if (!p_dev_kernel)
    {
        *errcode_ret = CL_INVALID_PROGRAM_EXECUTABLE;
#ifdef DBG_EVENT
        std::cerr << "ERROR: deviceDependentKernel failed\n";
#endif
        return;
    }

    // Check that contexts match
    if (k_ctx != q_ctx)
    {
#ifdef DBG_EVENT
        std::cerr << "ERROR: contexts don't match!\n";
#endif
        *errcode_ret = CL_INVALID_CONTEXT;
        return;
    }

    // Check args
    if (!kernel->argsSpecified())
    {
#ifdef DBG_EVENT
        std::cerr << "ERROR: kernel args aren't specifed\n";
#endif
        *errcode_ret = CL_INVALID_KERNEL_ARGS;
        return;
    }

    // Check dimension
    if (work_dim == 0 || work_dim > max_dims)
    {
#ifdef DBG_EVENT
        std::cerr << "ERROR: invalid work dimension\n";
#endif
        *errcode_ret = CL_INVALID_WORK_DIMENSION;
        return;
    }

    // Initialise kernel attributes
    for (unsigned i = 0; i < 3; ++i) {
      p_global_work_offset[i] = 0;
      p_global_work_size[i] = 0;
      p_local_work_size[i] = 0;
    }

    // Populate work_offset, work_size and local_work_size
    size_t work_group_size = 1;

    for (cl_uint i=0; i<work_dim; ++i)
    {
        if (global_work_offset)
        {
            p_global_work_offset[i] = global_work_offset[i];
        }
        else
        {
            p_global_work_offset[i] = 0;
        }

        if (!global_work_size || !global_work_size[i])
        {
            *errcode_ret = CL_INVALID_GLOBAL_WORK_SIZE;
        }
        p_global_work_size[i] = global_work_size[i];

        if (!local_work_size)
        {
            // Guess the best value according to the device
          // TODO Use this call to calculate work item merges.
          // Also try to set the kernel function to be a tailcall(?)
          // so it doesn't have to save the regs
            p_local_work_size[i] =
                p_dev_kernel->guessWorkGroupSize(work_dim, i, global_work_size[i]);

            // TODO: CL_INVALID_WORK_GROUP_SIZE if
            // __attribute__((reqd_work_group_size(X, Y, Z))) is set
        }
        else
        {
            // Check divisibility
            if ((global_work_size[i] % local_work_size[i]) != 0)
            {
                *errcode_ret = CL_INVALID_WORK_GROUP_SIZE;
                return;
            }

            // Not too big ?
            if (local_work_size[i] > p_max_work_item_sizes[i])
            {
                *errcode_ret = CL_INVALID_WORK_ITEM_SIZE;
                return;
            }

            // TODO: CL_INVALID_WORK_GROUP_SIZE if
            // __attribute__((reqd_work_group_size(X, Y, Z))) doesn't match

            p_local_work_size[i] = local_work_size[i];
            work_group_size *= local_work_size[i];
        }
    }

    // Check we don't ask too much to the device
    if (work_group_size > max_work_group_size)
    {
        *errcode_ret = CL_INVALID_WORK_GROUP_SIZE;
        return;
    }

    // Check arguments (buffer alignment, image size, ...)
    for (unsigned int i=0; i<kernel->numArgs(); ++i)
    {
#ifdef DBG_EVENT
      std::cerr << "Checking argument " << i << std::endl;
#endif
        const Kernel::Arg &a = kernel->arg(i);
        if (a.file() == Kernel::Arg::Local)
          continue;

        if (a.kind() == Kernel::Arg::Buffer)
        {
#ifdef DBG_EVENT
          std::cerr << "Arg is a buffer\n";
#endif
            const MemObject *buffer = *(const MemObject **)(a.value(0));

            if (!BufferEvent::isSubBufferAligned(buffer, device))
            {
                *errcode_ret = CL_MISALIGNED_SUB_BUFFER_OFFSET;
                return;
            }
        }
        else if (a.kind() == Kernel::Arg::Image2D)
        {
            const Image2D *image = *(const Image2D **)(a.value(0));
            size_t maxWidth, maxHeight;

            *errcode_ret = device->info(CL_DEVICE_IMAGE2D_MAX_WIDTH,
                                        sizeof(size_t), &maxWidth, 0);
            *errcode_ret |= device->info(CL_DEVICE_IMAGE2D_MAX_HEIGHT,
                                         sizeof(size_t), &maxHeight, 0);

            if (*errcode_ret != CL_SUCCESS)
                return;

            if (image->width() > maxWidth || image->height() > maxHeight)
            {
                *errcode_ret = CL_INVALID_IMAGE_SIZE;
                return;
            }
        }
        else if (a.kind() == Kernel::Arg::Image3D)
        {
            const Image3D *image = *(const Image3D **)a.value(0);
            size_t maxWidth, maxHeight, maxDepth;

            *errcode_ret = device->info(CL_DEVICE_IMAGE3D_MAX_WIDTH,
                                        sizeof(size_t), &maxWidth, 0);
            *errcode_ret |= device->info(CL_DEVICE_IMAGE3D_MAX_HEIGHT,
                                         sizeof(size_t), &maxHeight, 0);
            *errcode_ret |= device->info(CL_DEVICE_IMAGE3D_MAX_DEPTH,
                                         sizeof(size_t), &maxDepth, 0);

            if (*errcode_ret != CL_SUCCESS)
                return;

            if (image->width() > maxWidth || image->height() > maxHeight ||
                image->depth() > maxDepth)
            {
                *errcode_ret = CL_INVALID_IMAGE_SIZE;
                return;
            }
        }
    }
#ifdef DBG_EVENT
    std::cerr << "Leaving KernelEvent::KernelEvent\n";
#endif
}
bool handleStreamInstruction(Buffer* inputBuffer,
                            Buffer* outputBuffer,
                            OutputStream* outputStream,
                            filterCharFunction* inputFilterChar,
                            filterCharFunction* outputFilterChar) {

    if (inputBuffer == NULL) {
        writeError(DRIVER_STREAM_LISTENER_INPUT_BUFFER_NULL);
        return false;
    }
    if (outputBuffer == NULL) {
        writeError(DRIVER_STREAM_LISTENER_OUTPUT_BUFFER_NULL);
        return false;
    }

    // Try to clear the buffer if needed ('z' char)
    if (clearBufferIfNeeded(inputBuffer)) {
        return false;
    }

    // We received data
    int inputBufferCount = getBufferElementsCount(inputBuffer);

    if (inputBufferCount > 0) {

        if (filterFirstNextChar(inputBuffer, inputFilterChar)) {
            return false;
        }

        // As there is clear of char filtering, we must reload the size of the buffer
        int bufferSize = getBufferElementsCount(inputBuffer);

        if (bufferSize < DEVICE_HEADER_LENGTH) {
            return false;
        }

        // Get the header
        unsigned char deviceHeader = bufferGetCharAtIndex(inputBuffer, DEVICE_HEADER_INDEX);

        // Manage the dispatcher specifier (3 chars : Ex j01 before real command ...)
        unsigned char specifyDispatcherLength = 0;
        if (deviceHeader == DATA_DISPATCHER_DEVICE_HEADER) {
            specifyDispatcherLength += DISPATCHER_COMMAND_AND_INDEX_HEADER_LENGTH;
        }

        // Check if enough data
        if (bufferSize < specifyDispatcherLength + DEVICE_AND_COMMAND_HEADER_LENGTH) {
            return false;
        }

        // Reload the deviceHeader to take the dispatcher specifier if any
        deviceHeader = bufferGetCharAtIndex(inputBuffer, specifyDispatcherLength + DEVICE_HEADER_INDEX);
        unsigned char commandHeader = bufferGetCharAtIndex(inputBuffer, specifyDispatcherLength + COMMAND_HEADER_INDEX);

        // find the device corresponding to this header. It must at least be declared in local or in remote !
        unsigned char dataSize = bufferSize - specifyDispatcherLength;
        const Device* device = deviceDataDispatcherFindDevice(deviceHeader, commandHeader, dataSize, DEVICE_MODE_INPUT);

        // if the device was not found
        if (device == NULL) {
            return false;
        }

        // At this moment, device Interface is found
        DeviceInterface* deviceInterface = device->deviceInterface;

        // We must send device specifyDispatcherLength + Header + commandHeader + data => + 2
        int dataToTransferCount = deviceInterface->deviceGetInterface(commandHeader, DEVICE_MODE_INPUT, false) + specifyDispatcherLength + DEVICE_AND_COMMAND_HEADER_LENGTH;

        if (bufferSize < dataToTransferCount) {
            return false;
        }

        // We must receive ack + device header + command header + data => + 3
        int dataToReceiveCount = deviceInterface->deviceGetInterface(commandHeader, DEVICE_MODE_OUTPUT, false) + ACK_LENGTH + DEVICE_AND_COMMAND_HEADER_LENGTH;

        InputStream* bufferedInputStream = getInputStream(inputBuffer);
        OutputStream* bufferedOutputStream = getOutputStream(outputBuffer);

        TransmitMode transmitMode = device->transmitMode;

        // we handle locally the request
        if (specifyDispatcherLength == 0 && transmitMode == TRANSMIT_LOCAL) {

            // We need the implementation for local mode
            DeviceDescriptor* deviceDescriptor = device->descriptor;
            if (deviceDescriptor == NULL) {
                writeError(NO_DEVICE_DESC_FOUND_FOR);
                append(getErrorOutputStreamLogger(), deviceHeader);
                append(getErrorOutputStreamLogger(), commandHeader);
                return false;
            }

            // remove the first chars corresponding to the device header and command Header
            bufferClearLastChars(inputBuffer, DEVICE_AND_COMMAND_HEADER_LENGTH);

            // Call to the device
            deviceDescriptor->deviceHandleRawData(commandHeader, bufferedInputStream, bufferedOutputStream);

        } // we forward the request through Remote Operation with Dispatcher
        else if (specifyDispatcherLength > 0 || transmitMode == TRANSMIT_I2C || transmitMode == TRANSMIT_UART || transmitMode == TRANSMIT_ZIGBEE) {

            // Find dispatcher
            DriverDataDispatcher* dispatcher = NULL;

            if (specifyDispatcherLength > 0) {
                bufferClearLastChars(inputBuffer, DEVICE_HEADER_LENGTH);
                unsigned char dispatcherIndex = readHex2(bufferedInputStream);

                dispatcher = getDriverDataDispatcherByIndex(dispatcherIndex);
                if (dispatcher == NULL) {
                    writeError(NO_DISPATCHER_FOUND);
                    OutputStream* errorOutputStream = getErrorOutputStreamLogger();
                    appendStringAndDec(errorOutputStream, ", dispatcherIndex=", dispatcherIndex);
                    return false;
                }
            }
            else {
                TransmitMode transmitMode = device->transmitMode;
                int address = device->address;

                dispatcher = getDriverDataDispatcherByTransmitMode(transmitMode, address);
                
                if (dispatcher == NULL) {
                    writeError(NO_DISPATCHER_FOUND);
                    OutputStream* errorOutputStream = getErrorOutputStreamLogger();
                    appendStringAndDec(errorOutputStream, ", transmitMode=", transmitMode);
                    append(errorOutputStream, '(');
                    appendString(errorOutputStream, getTransmitModeAsString(transmitMode));
                    append(errorOutputStream, ')');
                    appendStringAndDec(errorOutputStream, ", addr=", address);
                    return false;
                }
            }

            // copy Driver buffer with remote Call
            dispatcher->driverDataDispatcherTransmitData(dispatcher,
                    inputBuffer,
                    outputBuffer,
                    dataToTransferCount,
                    dataToReceiveCount
                    );
        }
        
        // In All Cases (Local / I2C / UART / Zigbee ...)

        // Copy the data from bufferOutputStream to the outputStream
        if (outputStream != NULL) {
            copyInputToOutputStream(&(outputBuffer->inputStream), outputStream, outputFilterChar, dataToReceiveCount);
        }
        return true;
    }
    return false;
}