Bonjour,

Voici le problème que j'ai, j'essaie de lire une image avec la fonction openCL read_imagef dans un kernel. Voici comment a été charger l'image avec la librairie FreeImage:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/**
* Load an image from file using the FreeImage Library
* @param context : OpenCL context
* @param filename: Absolute or relative path to the file containing the image
* @param width   : Width of the image
* @param height  : Height of the image
* @return        : the loaded image object if success and 0 otherwise
*/
cl_mem LoadImage (const cl_context context, const char* filename, int& width, int& height)
{
	FREE_IMAGE_FORMAT format = FreeImage_GetFileType (filename, 0);
	FIBITMAP* image = FreeImage_Load (format, filename);
 
	// Convert to 32-bit image
	FIBITMAP* temp = image;
	image = FreeImage_ConvertTo32Bits (image);
	FreeImage_Unload (temp);
	width = FreeImage_GetWidth (image);
	height = FreeImage_GetHeight (image);
 
 
	// Allocate a buffer containing 4 * width * height characters (one pixel will be coded with a 32-bit value <=> 8-bit for each of the four components R, G, B and A)
	char* buffer = new char[width * height * 4];
	memcpy (buffer, FreeImage_GetBits (image), width * height * 4);
	FreeImage_Unload (image);
 
 
	// Create OpenCL image
	// Create a format that precise how the individual pixels of the image are laid out in memory 
	// and how the results will be interpreted when read inside of a kernel
	cl_image_format clImageFormat;
	clImageFormat.image_channel_order = CL_RGBA; // Four channels of image data that will be read into the R, G, B and A components in the kernel
	clImageFormat.image_channel_data_type = CL_UNORM_INT8; // Each 8-bit integer value will be mapped to the range [0.0, 1.0]
 
	cl_int err;
	cl_mem clImage;
 
	// Flag CL_MEM_COPY_HOST_PTR to specify that OpenCL must allocate memory for the memory object and copy the data from memory referenced by host_ptr argument 
	// (host_ptr is the last-but-one argument in the clCreateImage2D function)
	// If the flag CL_MEM_COPY_HOST_PTR is set, there will be no need to use clEnqueueWriteImage (cl->get_commandQueueGPU (), cl_image_input, CL_TRUE, origin, region, 0, 0, buffer_, 0, NULL, NULL);
	// at line 208
	clImage = clCreateImage2D (context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, &clImageFormat, width, height, 0, buffer, &err);
	if (err != CL_SUCCESS)
	{
		if (err == CL_INVALID_CONTEXT)
			cout << "Invalid context" << endl;
		if (err == CL_INVALID_VALUE)
			cout << "Invalid value" << endl;
		if (err == CL_INVALID_IMAGE_FORMAT_DESCRIPTOR)
			cout << "Invalid image format descriptor" << endl;
		if (err == CL_INVALID_IMAGE_SIZE)
			cout << "Invalid image size" << endl;
		if (err == CL_INVALID_HOST_PTR)
			cout << "Invalid host ptr" << endl;
		if (err == CL_IMAGE_FORMAT_NOT_SUPPORTED)
			cout << "Invalid image format not supported" << endl;
		if (err == CL_MEM_OBJECT_ALLOCATION_FAILURE)
			cout << "Invalid allocation failure" << endl;
		if (err == CL_INVALID_OPERATION)
			cout << "Invalid operation" << endl;
		if (err == CL_OUT_OF_HOST_MEMORY)
			cout << "OUT of host memeoru" << endl;
		return NULL;
	}
	err_check (err, "Unable to create the input 2D image with clCreateImage2D from file " + (string)filename);
 
	return clImage;
}

On y voit que je demande à OpenCL de créer un buffer pour l'image avec RGBA comme canaux.

Lorsque je lis une image toute rouge par exemple avec le kernel ci-dessous:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/** 
* Gaussian filter that is a kernel that is used to smooth or blur an image, by reducing high-frequency noise in the image.
* @param srcImage     : Source image object to be filtered
* @param dstImage     : Destination image object where the filtered results will be written
* @param sampler      : Sampler object specifying the addressing, coordinate and filter mode used by function read_imagef () function
* @param image_width  : Width of the image objects (source and destination image objects are created to be the same size)
* @param image_height : Height of the image objects
* @return             : none
*/
__kernel void gaussian_filter (__read_only image2d_t srcImage,
							   __write_only image2d_t dstImage,
							   sampler_t sampler,
							   const int image_width,
							   const int image_height,
							   __global float* test)
{
	int2 outImageCoord   = (int2) (get_global_id (0)    , get_global_id (1));
 
	if (outImageCoord.x == 0 && outImageCoord.y == 0)
	{
		float4 outColor = (0.0f, 0.0f, 0.0f, 0.0f);
		outColor += read_imagef (srcImage, sampler, outImageCoord);
 
		test[0] = outColor.x;
		test[1] = outColor.y;
		test[2] = outColor.z;
		test[3] = outColor.w;
	}
	else
		return;
}
où je demande de stocker dans le tableau de 4 float nommé "test", la valeur du pixel (0, 0), en l'affichant depuis le Host, j'obtiens 0.0 0.0 1.0 0.0 <=> BLEU alors que mon image est rouge.

J'ai cherché sur internet mais je n'ai rien trouvé, si quelqu'un aurait une idée, merci pour son aide de m'explique pourquoi je n'obtiens pas 1.0 0.0 0.0 0.0

Algernon