Merge lp:~viitanet/pocl/ImageSupport into lp:~pocl/pocl/trunk

Proposed by Timo Viitanen
Status: Merged
Merged at revision: 306
Proposed branch: lp:~viitanet/pocl/ImageSupport
Merge into: lp:~pocl/pocl/trunk
Diff against target: 1394 lines (+900/-95)
32 files modified
TODO (+0/-3)
examples/opencl-book-samples/ImageFilter2D.cl (+34/-0)
examples/opencl-book-samples/Makefile.am (+1/-0)
include/_kernel.h (+36/-0)
include/pocl_device.h (+2/-0)
lib/CL/Makefile.am (+14/-13)
lib/CL/clCreateBuffer.c (+1/-0)
lib/CL/clCreateImage2D.c (+108/-4)
lib/CL/clCreateKernel.c (+2/-0)
lib/CL/clCreateSampler.c (+30/-10)
lib/CL/clEnqueueCopyBufferToImage.c (+46/-13)
lib/CL/clEnqueueReadBufferRect.c (+2/-0)
lib/CL/clEnqueueReadImage.c (+23/-16)
lib/CL/clEnqueueWriteImage.c (+22/-16)
lib/CL/clGetDeviceInfo.c (+1/-2)
lib/CL/clGetSupportedImageFormats.c (+49/-10)
lib/CL/clReleaseSampler.c (+3/-5)
lib/CL/devices/basic/basic.c (+25/-0)
lib/CL/devices/dev_image.h (+17/-0)
lib/CL/devices/pthread/pthread.c (+39/-1)
lib/CL/pocl_cl.h (+17/-1)
lib/CL/pocl_image_util.c (+228/-0)
lib/CL/pocl_image_util.h (+50/-0)
lib/kernel/get_image_height.cl (+7/-0)
lib/kernel/get_image_width.cl (+7/-0)
lib/kernel/image.h (+15/-0)
lib/kernel/read_image.cl (+30/-0)
lib/kernel/sources.mk (+5/-1)
lib/kernel/write_image.cl (+17/-0)
lib/llvmopencl/GenerateHeader.cc (+39/-0)
scripts/pocl-kernel.in (+4/-0)
tests/testsuite-samples.at (+26/-0)
To merge this branch: bzr merge lp:~viitanet/pocl/ImageSupport
Reviewer Review Type Date Requested Status
pocl maintaners Pending
Review via email: mp+107929@code.launchpad.net

This proposal supersedes a proposal from 2012-05-28.

Description of the change

Implemented parts of OpenCL Image API:
clCreateImage2D
clCreateSampler
clReleaseSampler
clEnqueueCopyBufferToImage
clEnqueueWriteImage
clEnqueueReadImage
clGetSupportedImageFormats

read_imagef
write_imagef
get_image_width
get_image_height

Supported data types: CL_UNORM_INT8, CL_FLOAT
Supported channel orders: CL_RGBA, CL_R
Sampler always defaults to CLK_NORMALIZED_COORDINATES_FALSE | CLK_ADDRESS_NONE | CLK_FILTER_NEAREST.

Added a 'make check' test from opencl-book-samples, chapter 8, ImageFilter2D.
Other possible tests:
Chapter 14, histogram, requires atomics
Chapter 19, oclFlow, requires OpenCV
Rodinia-leukocyte crashes on compiler bug (https://bugs.launchpad.net/pocl/+bug/966992)
Rodinia-nn doesn't actually use images, but runs, TODO
Rodinia-gaussian doesn't actually use images; crashes
Rodinia-particlefilter crashes on another compiler bug

To post a comment you must log in.
lp:~viitanet/pocl/ImageSupport updated
306. By Pekka Jääskeläinen

Some image APIs from Timo.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'TODO'
--- TODO 2012-05-24 21:26:09 +0000
+++ TODO 2012-05-30 08:34:23 +0000
@@ -49,15 +49,12 @@
49* 5.2.1 Creating buffer objects49* 5.2.1 Creating buffer objects
50* 5.2.4 Mapping buffer objects50* 5.2.4 Mapping buffer objects
51* 5.3 Image objects51* 5.3 Image objects
52 * clCreateImage2D (deprecated in OpenCL 1.2) (*, R[gaussian, leukocyte, nn])
53* 5.3.3 Reading, Writing and Copying Image Objects52* 5.3.3 Reading, Writing and Copying Image Objects
54 * clEnqueueReadImage (*, R[nn])
55* 5.4 Querying, Umapping, Migrating, ... Mem objects53* 5.4 Querying, Umapping, Migrating, ... Mem objects
56* 5.4.1 Retaining and Releasing Memory Objects54* 5.4.1 Retaining and Releasing Memory Objects
57* 5.4.2 Unmapping Mapped Memory Objects55* 5.4.2 Unmapping Mapped Memory Objects
58* 5.5 Sampler objects56* 5.5 Sampler objects
59* 5.5.1 Creating Sampler Objects57* 5.5.1 Creating Sampler Objects
60 * clCreateSampler (*)
61* 5.6.1 Creating Program Objects58* 5.6.1 Creating Program Objects
62* 5.7.1 Creating Kernel Objects59* 5.7.1 Creating Kernel Objects
63* 5.9 Event objects60* 5.9 Event objects
6461
=== added file 'examples/opencl-book-samples/ImageFilter2D.cl'
--- examples/opencl-book-samples/ImageFilter2D.cl 1970-01-01 00:00:00 +0000
+++ examples/opencl-book-samples/ImageFilter2D.cl 2012-05-30 08:34:23 +0000
@@ -0,0 +1,34 @@
1
2 // Gaussian Kernel is:
3 // 1 2 1
4 // 2 4 2
5 // 1 2 1
6float kernelWeights[9] = { 1.0f, 2.0f, 1.0f, 2.0f, 4.0f, 2.0f,1.0f, 2.0f, 1.0f };
7
8// Gaussian filter of image
9__kernel void gaussian_filter(__read_only image2d_t srcImg,
10 __write_only image2d_t dstImg,
11 sampler_t sampler,
12 int width, int height)
13{
14 int2 startImageCoord = (int2) (get_global_id(0) - 1, get_global_id(1) - 1);
15 int2 endImageCoord = (int2) (get_global_id(0) + 1, get_global_id(1) + 1);
16 int2 outImageCoord = (int2) (get_global_id(0), get_global_id(1));
17
18 if (outImageCoord.x < width && outImageCoord.y < height)
19 {
20 int weight = 0;
21 float4 outColor = (float4)(0.0f, 0.0f, 0.0f, 0.0f);
22 for( int y = startImageCoord.y; y <= endImageCoord.y; y++)
23 {
24 for( int x = startImageCoord.x; x <= endImageCoord.x; x++)
25 {
26 outColor += (read_imagef(srcImg, sampler, (int2)(x, y)) * (kernelWeights[weight] / 16.0f));
27 weight += 1;
28 }
29 }
30
31 // Write the output value to image
32 write_imagef(dstImg, outImageCoord, outColor);
33 }
34}
035
=== modified file 'examples/opencl-book-samples/Makefile.am'
--- examples/opencl-book-samples/Makefile.am 2012-05-21 08:51:32 +0000
+++ examples/opencl-book-samples/Makefile.am 2012-05-30 08:34:23 +0000
@@ -39,6 +39,7 @@
39 sed -i 's/size_t localWorkSize = maxWorkGroupSize/size_t localWorkSize = 2/g' src/Chapter_16/Dijkstra/oclDijkstraKernel.cpp; \39 sed -i 's/size_t localWorkSize = maxWorkGroupSize/size_t localWorkSize = 2/g' src/Chapter_16/Dijkstra/oclDijkstraKernel.cpp; \
40 sed -i 's/device.j..type == CL_DEVICE_TYPE_GPU/device[j].type \& CL_DEVICE_TYPE_GPU/g' src/Chapter_22/spmv.c; \40 sed -i 's/device.j..type == CL_DEVICE_TYPE_GPU/device[j].type \& CL_DEVICE_TYPE_GPU/g' src/Chapter_22/spmv.c; \
41 sed -i 's/context.CL_DEVICE_TYPE_GPU/context\(CL_DEVICE_TYPE_CPU/g' src/Chapter_12/VectorAdd/vecadd.cpp; \41 sed -i 's/context.CL_DEVICE_TYPE_GPU/context\(CL_DEVICE_TYPE_CPU/g' src/Chapter_12/VectorAdd/vecadd.cpp; \
42 rm src/Chapter_12/Sinewave/CMakeLists.txt; \
42 mkdir -p build; cd build; \43 mkdir -p build; cd build; \
43 cmake \44 cmake \
44 -D CMAKE_CXX_FLAGS:STRING='-g -O3 -DCL_USE_DEPRECATED_OPENCL_1_1_APIS -lGL -lglut ${PTHREAD_CFLAGS}' \45 -D CMAKE_CXX_FLAGS:STRING='-g -O3 -DCL_USE_DEPRECATED_OPENCL_1_1_APIS -lGL -lglut ${PTHREAD_CFLAGS}' \
4546
=== modified file 'include/_kernel.h'
--- include/_kernel.h 2012-03-06 23:17:03 +0000
+++ include/_kernel.h 2012-05-30 08:34:23 +0000
@@ -1772,3 +1772,39 @@
1772_CL_DECLARE_ASYNC_COPY_FUNCS(float);1772_CL_DECLARE_ASYNC_COPY_FUNCS(float);
1773__IF_FP64(_CL_DECLARE_ASYNC_COPY_FUNCS(double));1773__IF_FP64(_CL_DECLARE_ASYNC_COPY_FUNCS(double));
17741774
1775// Image support
1776
1777typedef int sampler_t;
1778
1779#define CLK_ADDRESS_NONE 0x00
1780#define CLK_ADDRESS_MIRRORED_REPEAT 0x01
1781#define CLK_ADDRESS_REPEAT 0x02
1782#define CLK_ADDRESS_CLAMP_TO_EDGE 0x03
1783#define CLK_ADDRESS_CLAMP 0x04
1784
1785#define CLK_NORMALIZED_COORDS_FALSE 0x00
1786#define CLK_NORMALIZED_COORDS_TRUE 0x08
1787
1788#define CLK_FILTER_NEAREST 0x00
1789#define CLK_FILTER_LINEAR 0x10
1790
1791typedef struct image2d_t_* image2d_t;
1792
1793float4 _cl_overloadable read_imagef( image2d_t image,
1794 sampler_t sampler,
1795 int2 coord);
1796
1797float4 _cl_overloadable read_imagef( image2d_t image,
1798 sampler_t sampler,
1799 float2 coord);
1800
1801void _cl_overloadable write_imagef( image2d_t image,
1802 int2 coord,
1803 float4 color);
1804
1805void _cl_overloadable write_imagei( image2d_t image,
1806 int2 coord,
1807 int4 color);
1808
1809int get_image_width (image2d_t image);
1810int get_image_height (image2d_t image);
17751811
=== modified file 'include/pocl_device.h'
--- include/pocl_device.h 2012-05-08 17:37:35 +0000
+++ include/pocl_device.h 2012-05-30 08:34:23 +0000
@@ -51,6 +51,8 @@
51 unsigned short alocal_sizes[MAX_KERNEL_ARGS];51 unsigned short alocal_sizes[MAX_KERNEL_ARGS];
52 char arg_is_local[MAX_KERNEL_ARGS];52 char arg_is_local[MAX_KERNEL_ARGS];
53 char arg_is_pointer[MAX_KERNEL_ARGS];53 char arg_is_pointer[MAX_KERNEL_ARGS];
54 char arg_is_image[MAX_KERNEL_ARGS];
55 char arg_is_sampler[MAX_KERNEL_ARGS];
54 pocl_workgroup work_group_func;56 pocl_workgroup work_group_func;
55} __kernel_metadata;57} __kernel_metadata;
5658
5759
=== modified file 'lib/CL/Makefile.am'
--- lib/CL/Makefile.am 2012-05-28 12:03:51 +0000
+++ lib/CL/Makefile.am 2012-05-30 08:34:23 +0000
@@ -38,9 +38,9 @@
38 clGetCommandQueueInfo.c \38 clGetCommandQueueInfo.c \
39 clCreateBuffer.c \39 clCreateBuffer.c \
40 clCreateSubBuffer.c \40 clCreateSubBuffer.c \
41 clEnqueueReadBuffer.c \41 clEnqueueReadBuffer.c \
42 clEnqueueReadBufferRect.c \42 clEnqueueReadBufferRect.c \
43 clEnqueueMapBuffer.c \43 clEnqueueMapBuffer.c \
44 clEnqueueUnmapMemObject.c \44 clEnqueueUnmapMemObject.c \
45 clReleaseMemObject.c \45 clReleaseMemObject.c \
46 clRetainMemObject.c \46 clRetainMemObject.c \
@@ -89,23 +89,24 @@
89 clEnqueueTask.c \89 clEnqueueTask.c \
90 clCreateImage2D.c \90 clCreateImage2D.c \
91 clCreateImage3D.c \91 clCreateImage3D.c \
92 clEnqueueReadImage.c \92 clEnqueueReadImage.c \
93 clEnqueueWriteImage.c \93 clEnqueueWriteImage.c \
94 clCreateSampler.c \
95 clReleaseSampler.c \
96 clRetainSampler.c \
97 clGetSamplerInfo.c \
94 clEnqueueCopyImage.c \98 clEnqueueCopyImage.c \
95 clEnqueueMapImage.c \99 clEnqueueMapImage.c \ \
96 clGetSupportedImageFormats.c \
97 clGetImageInfo.c \100 clGetImageInfo.c \
98 clCreateFromGLTexture2D.c \101 clCreateFromGLTexture2D.c \
99 clCreateFromGLTexture3D.c \102 clCreateFromGLTexture3D.c \
100 clUnloadCompiler.c \103 clUnloadCompiler.c \
104 clGetSupportedImageFormats.c \
101 clGetExtensionFunctionAddress.c \105 clGetExtensionFunctionAddress.c \
102 clIcdGetPlatformIDsKHR.c \106 clIcdGetPlatformIDsKHR.c \
103 clCreateSampler.c \107 pocl_cl.h \
104 clReleaseSampler.c \108 pocl_util.c pocl_util.h \
105 clRetainSampler.c \109 pocl_image_util.c pocl_image_util.h
106 clGetSamplerInfo.c \
107 pocl_cl.h \
108 pocl_util.c pocl_util.h
109110
110111
111112
112113
=== modified file 'lib/CL/clCreateBuffer.c'
--- lib/CL/clCreateBuffer.c 2012-05-24 20:46:33 +0000
+++ lib/CL/clCreateBuffer.c 2012-05-30 08:34:23 +0000
@@ -49,6 +49,7 @@
49 mem->map_count = 0;49 mem->map_count = 0;
50 mem->mappings = NULL;50 mem->mappings = NULL;
51 mem->flags = flags;51 mem->flags = flags;
52 mem->is_image = CL_FALSE;
52 POCL_INIT_ICD_OBJECT(mem);53 POCL_INIT_ICD_OBJECT(mem);
5354
54 /* Store the per device buffer pointers always to a known55 /* Store the per device buffer pointers always to a known
5556
=== modified file 'lib/CL/clCreateImage2D.c'
--- lib/CL/clCreateImage2D.c 2012-01-30 12:21:12 +0000
+++ lib/CL/clCreateImage2D.c 2012-05-30 08:34:23 +0000
@@ -1,17 +1,121 @@
1#include "pocl_cl.h"1#include "pocl_cl.h"
2#include "assert.h"
3#include "pocl_image_util.h"
4
2CL_API_ENTRY cl_mem CL_API_CALL5CL_API_ENTRY cl_mem CL_API_CALL
3clCreateImage2D(cl_context context,6clCreateImage2D(cl_context context,
4 cl_mem_flags flags,7 cl_mem_flags flags,
5 const cl_image_format * image_format,8 const cl_image_format * image_format,
6 size_t image_width,9 size_t width,
7 size_t image_height,10 size_t height,
8 size_t image_row_pitch, 11 size_t image_row_pitch,
9 void * host_ptr,12 void * host_ptr,
10 cl_int * errcode_ret)13 cl_int * errcode_ret)
11CL_API_SUFFIX__VERSION_1_014CL_API_SUFFIX__VERSION_1_0
12{15{
13 POCL_ABORT_UNIMPLEMENTED();16 cl_mem mem;
14 return CL_SUCCESS;17 cl_device_id device_id;
18 void *device_ptr;
19 unsigned i, j;
20 int size;
21
22 if (context == NULL)
23 POCL_ERROR(CL_INVALID_CONTEXT);
24
25 mem = (cl_mem) malloc(sizeof(struct _cl_mem));
26 if (mem == NULL)
27 POCL_ERROR(CL_OUT_OF_HOST_MEMORY);
28
29 POCL_INIT_OBJECT(mem);
30 mem->parent = NULL;
31 mem->map_count = 0;
32 mem->mappings = NULL;
33 mem->flags = flags;
34 mem->is_image = CL_TRUE;
35
36 cl_channel_order order = image_format->image_channel_order;
37 cl_channel_type type = image_format->image_channel_data_type;
38
39 int dev_elem_size = sizeof(cl_float); //TODO
40 int dev_channels = 4;
41
42 if (image_row_pitch == 0)
43 image_row_pitch = width;
44
45 if (image_row_pitch != width)
46 POCL_ABORT_UNIMPLEMENTED();
47
48 size = width * height * dev_elem_size * dev_channels;
49
50 mem->device_ptrs = (void **) malloc(context->num_devices * sizeof(void *));
51 if (mem->device_ptrs == NULL)
52 {
53 free(mem);
54 POCL_ERROR(CL_OUT_OF_HOST_MEMORY);
55 }
56
57 int host_channels;
58
59 if (order == CL_RGBA)
60 host_channels=4;
61 else if (order == CL_R)
62 host_channels=1;
63 else
64 POCL_ABORT_UNIMPLEMENTED();
65
66 mem->size = size;
67 mem->context = context;
68
69 mem->image_width = width;
70 mem->image_height = height;
71 mem->image_row_pitch = image_row_pitch;
72 mem->image_channel_data_type = type;
73 mem->image_channel_order = order;
74
75 for (i = 0; i < context->num_devices; ++i)
76 {
77 if (i > 0)
78 clRetainMemObject (mem);
79 device_id = context->devices[i];
80 device_ptr = device_id->malloc(device_id->data, 0, size, NULL);
81
82 if (device_ptr == NULL)
83 {
84 for (j = 0; j < i; ++j)
85 {
86 device_id = context->devices[j];
87 device_id->free(device_id->data, 0, mem->device_ptrs[j]);
88 }
89 free(mem);
90 POCL_ERROR(CL_MEM_OBJECT_ALLOCATION_FAILURE);
91 }
92 mem->device_ptrs[i] = device_ptr;
93 /* The device allocator allocated from a device-host shared memory. */
94 if (flags & CL_MEM_ALLOC_HOST_PTR ||
95 flags & CL_MEM_USE_HOST_PTR)
96 POCL_ABORT_UNIMPLEMENTED();
97
98 if (flags & CL_MEM_COPY_HOST_PTR)
99 {
100 size_t origin[3] = { 0, 0, 0 };
101 size_t region[3] = { width, height, 1 };
102 pocl_write_image( mem,
103 context->devices[i],
104 origin,
105 region,
106 0,
107 1,
108 host_ptr );
109 }
110 }
111
112 POCL_RETAIN_OBJECT(context);
113
114
115 if (errcode_ret != NULL)
116 *errcode_ret = CL_SUCCESS;
117
118 return mem;
15}119}
16 120
17 121
18122
=== modified file 'lib/CL/clCreateKernel.c'
--- lib/CL/clCreateKernel.c 2012-05-23 08:38:12 +0000
+++ lib/CL/clCreateKernel.c 2012-05-30 08:34:23 +0000
@@ -143,6 +143,8 @@
143 kernel->dlhandle = dlhandle; /* TODO: why is this stored? */143 kernel->dlhandle = dlhandle; /* TODO: why is this stored? */
144 kernel->arg_is_pointer = lt_dlsym(dlhandle, "_arg_is_pointer");144 kernel->arg_is_pointer = lt_dlsym(dlhandle, "_arg_is_pointer");
145 kernel->arg_is_local = lt_dlsym(dlhandle, "_arg_is_local");145 kernel->arg_is_local = lt_dlsym(dlhandle, "_arg_is_local");
146 kernel->arg_is_image = lt_dlsym(dlhandle, "_arg_is_image");
147 kernel->arg_is_sampler = lt_dlsym(dlhandle, "_arg_is_sampler");
146 kernel->num_locals = *(cl_uint *) lt_dlsym(dlhandle, "_num_locals");148 kernel->num_locals = *(cl_uint *) lt_dlsym(dlhandle, "_num_locals");
147 kernel->arguments =149 kernel->arguments =
148 (struct pocl_argument *) malloc ((kernel->num_args + kernel->num_locals) *150 (struct pocl_argument *) malloc ((kernel->num_args + kernel->num_locals) *
149151
=== modified file 'lib/CL/clCreateSampler.c'
--- lib/CL/clCreateSampler.c 2012-05-22 21:26:29 +0000
+++ lib/CL/clCreateSampler.c 2012-05-30 08:34:23 +0000
@@ -1,13 +1,33 @@
1#include "pocl_cl.h"1#include "pocl_cl.h"
22extern CL_API_ENTRY cl_sampler CL_API_CALL
3CL_API_ENTRY cl_sampler CL_API_CALL3clCreateSampler(cl_context context,
4clCreateSampler(cl_context context ,4 cl_bool normalized_coords,
5 cl_bool normalized_coords , 5 cl_addressing_mode addressing_mode,
6 cl_addressing_mode addressing_mode , 6 cl_filter_mode filter_mode,
7 cl_filter_mode filter_mode ,7 cl_int * errcode_ret)
8 cl_int * errcode_ret ) CL_API_SUFFIX__VERSION_1_08CL_API_SUFFIX__VERSION_1_0
9{9{
10 POCL_ABORT_UNIMPLEMENTED();10 cl_sampler sampler;
11 return CL_SUCCESS;11
12 if (context == NULL)
13 POCL_ERROR(CL_INVALID_CONTEXT);
14
15 sampler = (cl_sampler) malloc(sizeof(struct _cl_sampler));
16 if (sampler == NULL)
17 POCL_ERROR(CL_OUT_OF_HOST_MEMORY);
18
19 if (normalized_coords == CL_TRUE)
20 POCL_ABORT_UNIMPLEMENTED();
21
22 if (addressing_mode != CL_ADDRESS_CLAMP_TO_EDGE)
23 POCL_ABORT_UNIMPLEMENTED();
24
25 if (filter_mode != CL_FILTER_NEAREST)
26 POCL_ABORT_UNIMPLEMENTED();
27
28 sampler->normalized_coords = normalized_coords;
29 sampler->addressing_mode = addressing_mode;
30 sampler->filter_mode = filter_mode;
31
32 return sampler;
12}33}
13
1434
=== modified file 'lib/CL/clEnqueueCopyBufferToImage.c'
--- lib/CL/clEnqueueCopyBufferToImage.c 2012-05-22 21:26:29 +0000
+++ lib/CL/clEnqueueCopyBufferToImage.c 2012-05-30 08:34:23 +0000
@@ -1,17 +1,50 @@
1#include "pocl_cl.h"1#include "pocl_cl.h"
22
3CL_API_ENTRY cl_int CL_API_CALL3extern CL_API_ENTRY cl_int CL_API_CALL
4clEnqueueCopyBufferToImage(cl_command_queue command_queue ,4clEnqueueCopyBufferToImage(cl_command_queue command_queue,
5 cl_mem src_buffer ,5 cl_mem buffer,
6 cl_mem dst_image , 6 cl_mem image,
7 size_t src_offset ,7 size_t src_offset,
8 const size_t * dst_origin ,8 const size_t * dst_origin, /*[3]*/
9 const size_t * region , 9 const size_t * region, /*[3]*/
10 cl_uint num_events_in_wait_list ,10 cl_uint num_events_in_wait_list,
11 const cl_event * event_wait_list ,11 const cl_event * event_wait_list,
12 cl_event * event ) CL_API_SUFFIX__VERSION_1_012 cl_event * event ) CL_API_SUFFIX__VERSION_1_0
13{13 {
14 POCL_ABORT_UNIMPLEMENTED();14 if (region == NULL)
15 return CL_SUCCESS;15 return CL_INVALID_VALUE;
16}16
17 if (region[2] != 1) //3D image
18 POCL_ABORT_UNIMPLEMENTED();
19
20 int dev_elem_size = sizeof(cl_float);
21 int dev_channels = 4;
22
23 int host_elem_size;
24 int host_channels;
25 pocl_get_image_information (image, &host_channels, &host_elem_size);
26
27 void* temp = malloc (image->size);
28
29 cl_device_id device_id = command_queue->device;
1730
31 device_id->read
32 (device_id->data,
33 temp,
34 image->device_ptrs[device_id->dev_id],
35 image->size);
36
37 cl_int ret_code = pocl_write_image
38 (image,
39 command_queue->device,
40 dst_origin,
41 region,
42 0,
43 0,
44 temp+src_offset);
45
46 free(temp);
47
48 return ret_code;
49 }
50
18\ No newline at end of file51\ No newline at end of file
1952
=== modified file 'lib/CL/clEnqueueReadBufferRect.c'
--- lib/CL/clEnqueueReadBufferRect.c 2012-05-14 11:45:48 +0000
+++ lib/CL/clEnqueueReadBufferRect.c 2012-05-30 08:34:23 +0000
@@ -23,6 +23,7 @@
2323
24#include "pocl_cl.h"24#include "pocl_cl.h"
25#include <assert.h>25#include <assert.h>
26#include <stdio.h>
2627
27CL_API_ENTRY cl_int CL_API_CALL28CL_API_ENTRY cl_int CL_API_CALL
28clEnqueueReadBufferRect(cl_command_queue command_queue,29clEnqueueReadBufferRect(cl_command_queue command_queue,
@@ -78,6 +79,7 @@
78 buffer_origin, host_origin, region,79 buffer_origin, host_origin, region,
79 buffer_row_pitch, buffer_slice_pitch,80 buffer_row_pitch, buffer_slice_pitch,
80 host_row_pitch, host_slice_pitch);81 host_row_pitch, host_slice_pitch);
82
8183
82 return CL_SUCCESS;84 return CL_SUCCESS;
83}85}
8486
=== modified file 'lib/CL/clEnqueueReadImage.c'
--- lib/CL/clEnqueueReadImage.c 2012-05-22 21:26:29 +0000
+++ lib/CL/clEnqueueReadImage.c 2012-05-30 08:34:23 +0000
@@ -1,19 +1,26 @@
1#include "pocl_cl.h"1#include "pocl_cl.h"
2#include "assert.h"
3#include "pocl_image_util.h"
24
3CL_API_ENTRY cl_int CL_API_CALL5extern CL_API_ENTRY cl_int CL_API_CALL
4clEnqueueReadImage(cl_command_queue command_queue ,6clEnqueueReadImage(cl_command_queue command_queue,
5 cl_mem image ,7 cl_mem image,
6 cl_bool blocking_read , 8 cl_bool blocking_read,
7 const size_t * origin ,9 const size_t * origin, /* [3] */
8 const size_t * region ,10 const size_t * region, /* [3] */
9 size_t row_pitch ,11 size_t host_row_pitch,
10 size_t slice_pitch , 12 size_t host_slice_pitch,
11 void * ptr ,13 void * ptr,
12 cl_uint num_events_in_wait_list ,14 cl_uint num_events_in_wait_list,
13 const cl_event * event_wait_list ,15 const cl_event * event_wait_list,
14 cl_event * event ) CL_API_SUFFIX__VERSION_1_016 cl_event * event)
17CL_API_SUFFIX__VERSION_1_0
15{18{
16 POCL_ABORT_UNIMPLEMENTED();19 return pocl_read_image(image,
17 return CL_SUCCESS;20 command_queue->device,
18}21 origin,
1922 region,
23 host_row_pitch,
24 host_slice_pitch,
25 ptr);
26}
20\ No newline at end of file27\ No newline at end of file
2128
=== modified file 'lib/CL/clEnqueueWriteImage.c'
--- lib/CL/clEnqueueWriteImage.c 2012-05-22 21:26:29 +0000
+++ lib/CL/clEnqueueWriteImage.c 2012-05-30 08:34:23 +0000
@@ -1,19 +1,25 @@
1#include "pocl_cl.h"1#include "pocl_cl.h"
2#include "pocl_image_util.h"
23
3CL_API_ENTRY cl_int CL_API_CALL4extern CL_API_ENTRY cl_int CL_API_CALL
4clEnqueueWriteImage(cl_command_queue command_queue ,5clEnqueueWriteImage(cl_command_queue command_queue,
5 cl_mem image ,6 cl_mem image,
6 cl_bool blocking_write , 7 cl_bool blocking_write,
7 const size_t * origin,8 const size_t * origin, /*[3]*/
8 const size_t * region,9 const size_t * region, /*[3]*/
9 size_t input_row_pitch ,10 size_t host_row_pitch,
10 size_t input_slice_pitch , 11 size_t host_slice_pitch,
11 const void * ptr ,12 const void * ptr,
12 cl_uint num_events_in_wait_list ,13 cl_uint num_events_in_wait_list,
13 const cl_event * event_wait_list ,14 const cl_event * event_wait_list,
14 cl_event * event ) CL_API_SUFFIX__VERSION_1_015 cl_event * event) CL_API_SUFFIX__VERSION_1_0
15{16 {
16 POCL_ABORT_UNIMPLEMENTED();17 return pocl_write_image(image,
17 return CL_SUCCESS;18 command_queue->device,
18}19 origin,
20 region,
21 host_row_pitch,
22 host_slice_pitch,
23 ptr);
24 }
1925
2026
=== modified file 'lib/CL/clGetDeviceInfo.c'
--- lib/CL/clGetDeviceInfo.c 2012-05-15 22:38:06 +0000
+++ lib/CL/clGetDeviceInfo.c 2012-05-30 08:34:23 +0000
@@ -62,8 +62,7 @@
62 switch (param_name)62 switch (param_name)
63 {63 {
64 case CL_DEVICE_IMAGE_SUPPORT: 64 case CL_DEVICE_IMAGE_SUPPORT:
65 /* Return CL_FALSE until the APIs are implemented. */65 POCL_RETURN_DEVICE_INFO(cl_bool, CL_TRUE);
66 POCL_RETURN_DEVICE_INFO(cl_bool, CL_FALSE);
67 case CL_DEVICE_TYPE:66 case CL_DEVICE_TYPE:
68 POCL_RETURN_DEVICE_INFO(cl_device_type, device->type); 67 POCL_RETURN_DEVICE_INFO(cl_device_type, device->type);
69 case CL_DEVICE_VENDOR_ID:68 case CL_DEVICE_VENDOR_ID:
7069
=== modified file 'lib/CL/clGetSupportedImageFormats.c'
--- lib/CL/clGetSupportedImageFormats.c 2012-05-22 21:26:29 +0000
+++ lib/CL/clGetSupportedImageFormats.c 2012-05-30 08:34:23 +0000
@@ -1,14 +1,53 @@
1#include "pocl_cl.h"1#include "pocl_cl.h"
22
3CL_API_ENTRY cl_int CL_API_CALL3extern CL_API_ENTRY cl_int CL_API_CALL
4clGetSupportedImageFormats(cl_context context ,4clGetSupportedImageFormats(cl_context context,
5 cl_mem_flags flags ,5 cl_mem_flags flags,
6 cl_mem_object_type image_type ,6 cl_mem_object_type image_type,
7 cl_uint num_entries ,7 cl_uint num_entries,
8 cl_image_format * image_formats ,8 cl_image_format * image_formats,
9 cl_uint * num_image_formats ) CL_API_SUFFIX__VERSION_1_09 cl_uint * num_image_formats) CL_API_SUFFIX__VERSION_1_0
10{10{
11 POCL_ABORT_UNIMPLEMENTED();11 if (context == NULL)
12 return CL_SUCCESS;12 return CL_INVALID_CONTEXT;
13
14 if (image_type != CL_MEM_OBJECT_IMAGE2D)
15 return CL_INVALID_VALUE;
16
17 if (num_entries==0 && image_formats!=NULL)
18 return CL_INVALID_VALUE;
19
20 int idx=0;
21
22 const int supported_order_count = 2;
23 cl_channel_order supported_orders[] =
24 {
25 CL_RGBA,
26 CL_R
27 };
28
29 const int supported_type_count = 2;
30 cl_channel_type supported_types[] =
31 {
32 CL_UNORM_INT8,
33 CL_FLOAT
34 };
35
36 int i, j;
37 for (i=0; i<supported_order_count; i++)
38 for (j=0; j<supported_type_count; j++)
39 {
40 if (idx >= num_entries)
41 return CL_SUCCESS;
42
43 image_formats[idx].image_channel_order = supported_orders[i];
44 image_formats[idx].image_channel_data_type = supported_types[j];
45
46 idx++;
47 }
48
49 // Add special cases here if a channel order is supported with only some types or vice versa.
50 *num_image_formats = idx;
51
52 return CL_SUCCESS;
13}53}
14
1554
=== modified file 'lib/CL/clReleaseSampler.c'
--- lib/CL/clReleaseSampler.c 2012-05-22 21:26:29 +0000
+++ lib/CL/clReleaseSampler.c 2012-05-30 08:34:23 +0000
@@ -1,9 +1,7 @@
1#include "pocl_cl.h"1#include "pocl_cl.h"
22extern CL_API_ENTRY cl_int CL_API_CALL
3CL_API_ENTRY cl_int CL_API_CALL3clReleaseSampler(cl_sampler sampler)
4clReleaseSampler(cl_sampler sampler) CL_API_SUFFIX__VERSION_1_04CL_API_SUFFIX__VERSION_1_0
5{5{
6 POCL_ABORT_UNIMPLEMENTED();
7 return CL_SUCCESS;6 return CL_SUCCESS;
8}7}
9
108
=== modified file 'lib/CL/devices/basic/basic.c'
--- lib/CL/devices/basic/basic.c 2012-05-28 16:17:57 +0000
+++ lib/CL/devices/basic/basic.c 2012-05-30 08:34:23 +0000
@@ -27,6 +27,7 @@
27#include <string.h>27#include <string.h>
28#include <stdlib.h>28#include <stdlib.h>
29#include <unistd.h>29#include <unistd.h>
30#include <../dev_image.h>
30#include <sys/time.h>31#include <sys/time.h>
3132
32#define max(a,b) (((a) > (b)) ? (a) : (b))33#define max(a,b) (((a) > (b)) ? (a) : (b))
@@ -235,6 +236,30 @@
235 {236 {
236 arguments[i] = &((*(cl_mem *) (p->value))->device_ptrs[device]);237 arguments[i] = &((*(cl_mem *) (p->value))->device_ptrs[device]);
237 }238 }
239 else if (kernel->arg_is_image[i])
240 {
241 dev_image2d_t di;
242 cl_mem mem = *(cl_mem*)p->value;
243 di.data = &((*(cl_mem *) (p->value))->device_ptrs[device]);
244 di.data = ((*(cl_mem *) (p->value))->device_ptrs[device]);
245 di.width = mem->image_width;
246 di.height = mem->image_height;
247 di.rowpitch = mem->image_row_pitch;
248 di.order = mem->image_channel_order;
249 di.data_type = mem->image_channel_data_type;
250 void* devptr = pocl_basic_malloc(data, 0, sizeof(dev_image2d_t), NULL);
251 arguments[i] = malloc (sizeof (void *));
252 *(void **)(arguments[i]) = devptr;
253 pocl_basic_write( data, &di, devptr, sizeof(dev_image2d_t) );
254 }
255 else if (kernel->arg_is_sampler[i])
256 {
257 dev_sampler_t ds;
258
259 arguments[i] = malloc (sizeof (void *));
260 *(void **)(arguments[i]) = pocl_basic_malloc(data, 0, sizeof(dev_sampler_t), NULL);
261 pocl_basic_write( data, &ds, *(void**)arguments[i], sizeof(dev_sampler_t) );
262 }
238 else263 else
239 {264 {
240 arguments[i] = p->value;265 arguments[i] = p->value;
241266
=== added file 'lib/CL/devices/dev_image.h'
--- lib/CL/devices/dev_image.h 1970-01-01 00:00:00 +0000
+++ lib/CL/devices/dev_image.h 2012-05-30 08:34:23 +0000
@@ -0,0 +1,17 @@
1#ifndef __X86_IMAGE_H__
2#define __X86_IMAGE_H__
3
4//Definition of the image datatype used on basic and pthread (and probably tce?)
5
6typedef cl_int dev_sampler_t;
7
8typedef struct dev_image2d_t {
9 void* data;
10 cl_int width;
11 cl_int height;
12 cl_int rowpitch;
13 cl_int order;
14 cl_int data_type;
15} dev_image2d_t;
16
17#endif
018
=== modified file 'lib/CL/devices/pthread/pthread.c'
--- lib/CL/devices/pthread/pthread.c 2012-05-29 12:16:56 +0000
+++ lib/CL/devices/pthread/pthread.c 2012-05-30 08:34:23 +0000
@@ -36,6 +36,7 @@
36#ifdef CUSTOM_BUFFER_ALLOCATOR36#ifdef CUSTOM_BUFFER_ALLOCATOR
3737
38#include "bufalloc.h"38#include "bufalloc.h"
39#include <../dev_image.h>
3940
40/* Instead of mallocing a buffer size for a region, try to allocate 41/* Instead of mallocing a buffer size for a region, try to allocate
41 this many times the buffer size to hopefully avoid mallocs for 42 this many times the buffer size to hopefully avoid mallocs for
@@ -651,6 +652,15 @@
651}652}
652653
653void *654void *
655pocl_pthread_map_mem (void *data, void *buf_ptr,
656 size_t offset, size_t size, void* host_ptr)
657{
658 /* All global pointers of the pthread/CPU device are in
659 the host address space already, and up to date. */
660 return buf_ptr + offset;
661}
662
663void *
654workgroup_thread (void *p)664workgroup_thread (void *p)
655{665{
656 struct thread_arguments *ta = (struct thread_arguments *) p;666 struct thread_arguments *ta = (struct thread_arguments *) p;
@@ -669,6 +679,30 @@
669 }679 }
670 else if (kernel->arg_is_pointer[i])680 else if (kernel->arg_is_pointer[i])
671 arguments[i] = &((*(cl_mem *) (al->value))->device_ptrs[ta->device]);681 arguments[i] = &((*(cl_mem *) (al->value))->device_ptrs[ta->device]);
682 else if (kernel->arg_is_image[i])
683 {
684 dev_image2d_t di;
685 cl_mem mem = *(cl_mem*)al->value;
686 di.data = &((*(cl_mem *) (al->value))->device_ptrs[ta->device]);
687 di.data = ((*(cl_mem *) (al->value))->device_ptrs[ta->device]);
688 di.width = mem->image_width;
689 di.height = mem->image_height;
690 di.rowpitch = mem->image_row_pitch;
691 di.order = mem->image_channel_order;
692 di.data_type = mem->image_channel_data_type;
693 void* devptr = pocl_pthread_malloc(ta->data, 0, sizeof(dev_image2d_t), NULL);
694 arguments[i] = malloc (sizeof (void *));
695 *(void **)(arguments[i]) = devptr;
696 pocl_pthread_write( ta->data, &di, devptr, sizeof(dev_image2d_t) );
697 }
698 else if (kernel->arg_is_sampler[i])
699 {
700 dev_sampler_t ds;
701
702 arguments[i] = malloc (sizeof (void *));
703 *(void **)(arguments[i]) = pocl_pthread_malloc(ta->data, 0, sizeof(dev_sampler_t), NULL);
704 pocl_pthread_write( ta->data, &ds, *(void**)arguments[i], sizeof(dev_sampler_t) );
705 }
672 else706 else
673 arguments[i] = al->value;707 arguments[i] = al->value;
674 }708 }
@@ -699,11 +733,15 @@
699733
700 for (i = 0; i < kernel->num_args; ++i)734 for (i = 0; i < kernel->num_args; ++i)
701 {735 {
702 if (kernel->arg_is_local[i])736 if (kernel->arg_is_local[i] )
703 {737 {
704 pocl_pthread_free(ta->data, 0, *(void **)(arguments[i]));738 pocl_pthread_free(ta->data, 0, *(void **)(arguments[i]));
705 free(arguments[i]);739 free(arguments[i]);
706 }740 }
741 else if( kernel->arg_is_sampler[i] || kernel->arg_is_image[i] )
742 {
743 free(arguments[i]);
744 }
707 }745 }
708 for (i = kernel->num_args;746 for (i = kernel->num_args;
709 i < kernel->num_args + kernel->num_locals;747 i < kernel->num_args + kernel->num_locals;
710748
=== modified file 'lib/CL/pocl_cl.h'
--- lib/CL/pocl_cl.h 2012-05-29 12:16:56 +0000
+++ lib/CL/pocl_cl.h 2012-05-30 08:34:23 +0000
@@ -303,6 +303,15 @@
303 /* in case this is a sub buffer, this points to the parent303 /* in case this is a sub buffer, this points to the parent
304 buffer */304 buffer */
305 cl_mem_t *parent;305 cl_mem_t *parent;
306 /* Image flags */
307 cl_bool is_image;
308 cl_channel_order image_channel_order;
309 cl_channel_type image_channel_data_type;
310 size_t image_width;
311 size_t image_height;
312 /*size_t image_depth;*/
313 size_t image_row_pitch;
314 /*size_t image_slice_pitch;*/
306};315};
307316
308struct _cl_program {317struct _cl_program {
@@ -337,6 +346,8 @@
337 lt_dlhandle dlhandle;346 lt_dlhandle dlhandle;
338 cl_int *arg_is_pointer;347 cl_int *arg_is_pointer;
339 cl_int *arg_is_local;348 cl_int *arg_is_local;
349 cl_int *arg_is_image;
350 cl_int *arg_is_sampler;
340 cl_uint num_locals;351 cl_uint num_locals;
341 struct pocl_argument *arguments;352 struct pocl_argument *arguments;
342 struct _cl_kernel *next;353 struct _cl_kernel *next;
@@ -359,8 +370,13 @@
359370
360};371};
361372
373typedef struct _cl_sampler cl_sampler_t;
374
362struct _cl_sampler {375struct _cl_sampler {
363 POCL_ICD_OBJECT376 POCL_ICD_OBJECT;
377 cl_bool normalized_coords;
378 cl_addressing_mode addressing_mode;
379 cl_filter_mode filter_mode;
364};380};
365381
366#define POCL_PROFILE_QUEUED \382#define POCL_PROFILE_QUEUED \
367383
=== added file 'lib/CL/pocl_image_util.c'
--- lib/CL/pocl_image_util.c 1970-01-01 00:00:00 +0000
+++ lib/CL/pocl_image_util.c 2012-05-30 08:34:23 +0000
@@ -0,0 +1,228 @@
1#include "pocl_cl.h"
2#include "pocl_image_util.h"
3#include "assert.h"
4
5extern void
6pocl_get_image_information (cl_mem image,
7 int* channels_out,
8 int* elem_size_out)
9 {
10 cl_channel_order order = image->image_channel_order;
11 cl_channel_type type = image->image_channel_data_type;
12
13 int host_elem_size;
14 if (type == CL_FLOAT)
15 host_elem_size=4;
16 else if (type==CL_UNORM_INT8)
17 host_elem_size=1;
18 else
19 POCL_ABORT_UNIMPLEMENTED();
20 if (elem_size_out != NULL)
21 *elem_size_out = host_elem_size;
22
23 int host_channels;
24 if (order == CL_RGBA)
25 host_channels=4;
26 else if (order == CL_R)
27 host_channels=1;
28 else
29 POCL_ABORT_UNIMPLEMENTED();
30 if (channels_out != NULL)
31 *channels_out = host_channels;
32 }
33extern cl_int
34pocl_write_image (cl_mem image,
35 cl_device_id device_id,
36 const size_t * origin_, /*[3]*/
37 const size_t * region_, /*[3]*/
38 size_t host_row_pitch,
39 size_t host_slice_pitch,
40 const void * ptr)
41 {
42 if (image == NULL)
43 return CL_INVALID_MEM_OBJECT;
44
45 if ((ptr == NULL) ||
46 (region_ == NULL))
47 return CL_INVALID_VALUE;
48
49 int width = image->image_width;
50 int height = image->image_height;
51 cl_channel_order order = image->image_channel_order;
52 cl_channel_type type = image->image_channel_data_type;
53
54 size_t dev_elem_size = sizeof(cl_float);
55 int dev_channels = 4;
56
57 int host_elem_size;
58 int host_channels;
59 pocl_get_image_information (image, &host_channels, &host_elem_size);
60
61 size_t origin[3] = { origin_[0]*dev_elem_size*dev_channels, origin_[1], origin_[2] };
62 size_t region[3] = { region_[0]*dev_elem_size*dev_channels, region_[1], region_[2] };
63
64 size_t image_row_pitch = width*dev_elem_size*dev_channels;
65 size_t image_slice_pitch = 0;
66
67 if ((region[0]*region[1]*region[2] > 0) &&
68 (region[0]-1 +
69 image_row_pitch * (region[1]-1) +
70 image_slice_pitch * (region[2]-1) >= image->size))
71 return CL_INVALID_VALUE;
72
73 cl_float* temp = malloc( width*height*dev_channels*dev_elem_size );
74
75 if (temp == NULL)
76 return CL_OUT_OF_HOST_MEMORY;
77
78 int x, y, k;
79
80 for (y=0; y<height; y++)
81 for (x=0; x<width*dev_channels; x++)
82 temp[x+y*width*dev_channels] = 0.f;
83
84 for (y=0; y<height; y++)
85 {
86 for (x=0; x<width; x++)
87 {
88 cl_float elem[4]; //TODO 0,0,0,0 for some modes?
89
90 for (k=0; k<host_channels; k++)
91 {
92 if (type == CL_FLOAT)
93 elem[k] = ((float*)ptr)[k+(x+y*width)*host_channels];
94 else if (type==CL_UNORM_INT8)
95 {
96 cl_uchar foo = ((cl_uchar*)ptr)[k+(x+y*width)*host_channels];
97 elem[k] = (float)(foo) * (1.f/255.f);
98 }
99 else
100 POCL_ABORT_UNIMPLEMENTED();
101 }
102
103 if (order == CL_RGBA)
104 for (k=0; k<4; k++)
105 temp[(x+y*width)*dev_channels+k] = elem[k];
106 else if (order == CL_R)
107 {
108 temp[(x+y*width)*dev_channels+0] = elem[0];
109 temp[(x+y*width)*dev_channels+1] = 0.f;
110 temp[(x+y*width)*dev_channels+2] = 0.f;
111 temp[(x+y*width)*dev_channels+3] = 1.f;
112 }
113 }
114 }
115
116
117 device_id->write_rect(device_id->data, temp,
118 image->device_ptrs[device_id->dev_id],
119 origin, origin, region,
120 image_row_pitch, image_slice_pitch,
121 image_row_pitch, image_slice_pitch);
122
123 free (temp);
124 return CL_SUCCESS;
125 }
126
127extern cl_int
128pocl_read_image (cl_mem image,
129 cl_device_id device_id,
130 const size_t * origin_, /*[3]*/
131 const size_t * region_, /*[3]*/
132 size_t host_row_pitch,
133 size_t host_slice_pitch,
134 void * ptr)
135 {
136
137 if (image == NULL)
138 return CL_INVALID_MEM_OBJECT;
139
140 if ((ptr == NULL) ||
141 (region_ == NULL))
142 return CL_INVALID_VALUE;
143
144 int width = image->image_width;
145 int height = image->image_height;
146 int dev_elem_size = sizeof(cl_float);
147 int dev_channels = 4;
148 size_t origin[3] = { origin_[0]*dev_elem_size*dev_channels, origin_[1], origin_[2] };
149 size_t region[3] = { region_[0]*dev_elem_size*dev_channels, region_[1], region_[2] };
150
151 size_t image_row_pitch = width*dev_elem_size*dev_channels;
152 size_t image_slice_pitch = 0;
153
154 if ((region[0]*region[1]*region[2] > 0) &&
155 (region[0]-1 +
156 image_row_pitch * (region[1]-1) +
157 image_slice_pitch * (region[2]-1) >= image->size))
158 return CL_INVALID_VALUE;
159
160
161 int i, j, k;
162
163 cl_channel_order order = image->image_channel_order;
164 cl_channel_type type = image->image_channel_data_type;
165
166 cl_float* temp = malloc( width*height*dev_channels*dev_elem_size );
167
168 if (temp == NULL)
169 return CL_OUT_OF_HOST_MEMORY;
170
171 int host_channels, host_elem_size;
172
173 pocl_get_image_information(image, &host_channels, &host_elem_size);
174
175 if (host_row_pitch == 0) {
176 host_row_pitch = width*host_channels;
177 }
178
179 size_t buffer_origin[3] = { 0, 0, 0 };
180
181 device_id->read_rect(device_id->data, temp,
182 image->device_ptrs[device_id->dev_id],
183 origin, origin, region,
184 image_row_pitch, image_slice_pitch,
185 image_row_pitch, image_slice_pitch);
186
187 for (j=0; j<height; j++) {
188 for (i=0; i<width; i++) {
189 cl_float elem[4];
190
191 for (k=0; k<4; k++)
192 elem[k]=0;
193
194 if (order == CL_RGBA) {
195 for (k=0; k<4; k++)
196 elem[k] = temp[i*dev_channels + j*width*dev_channels + k];
197 }
198 else if (order == CL_R) { // host_channels == 1
199 elem[0] = temp[i*dev_channels + j*width*dev_channels + 0];
200 }
201
202 if (type == CL_UNORM_INT8)
203 { // host_channels == 4
204 for (k=0; k<host_channels; k++)
205 {
206 ((cl_uchar*)ptr)[i*host_channels + j*host_row_pitch + k]
207 = (unsigned char)(255*elem[k]);
208 }
209 }
210 else if (type == CL_FLOAT)
211 {
212 for (k=0; k<host_channels; k++)
213 {
214 POCL_ABORT_UNIMPLEMENTED();
215 ((cl_float*)ptr)[i*host_channels + j*host_row_pitch + k]
216 = elem[k];
217 }
218 }
219 else
220 POCL_ABORT_UNIMPLEMENTED();
221 }
222 }
223
224 free (temp);
225
226 return CL_SUCCESS;
227 }
228
0\ No newline at end of file229\ No newline at end of file
1230
=== added file 'lib/CL/pocl_image_util.h'
--- lib/CL/pocl_image_util.h 1970-01-01 00:00:00 +0000
+++ lib/CL/pocl_image_util.h 2012-05-30 08:34:23 +0000
@@ -0,0 +1,50 @@
1/* OpenCL runtime library: pocl_image_util image utility functions
2
3 Copyright (c) 2012 Timo Viitanen / Tampere University of Technology
4
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"), to deal
7 in the Software without restriction, including without limitation the rights
8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 copies of the Software, and to permit persons to whom the Software is
10 furnished to do so, subject to the following conditions:
11
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 THE SOFTWARE.
22*/
23
24#ifndef POCL_IMAGE_UTIL_H
25#define POCL_IMAGE_UTIL_H
26
27extern cl_int
28pocl_write_image (cl_mem image,
29 cl_device_id device_id,
30 const size_t * origin_, /*[3]*/
31 const size_t * region_, /*[3]*/
32 size_t host_row_pitch,
33 size_t host_slice_pitch,
34 const void * ptr);
35
36extern cl_int
37pocl_read_image (cl_mem image,
38 cl_device_id device,
39 const size_t * origin, /*[3]*/
40 const size_t * region, /*[3]*/
41 size_t host_row_pitch,
42 size_t host_slice_pitch,
43 void * ptr);
44
45extern void
46pocl_get_image_information (cl_mem image,
47 int* host_channels,
48 int* host_elem_size);
49
50#endif
051
=== added file 'lib/kernel/get_image_height.cl'
--- lib/kernel/get_image_height.cl 1970-01-01 00:00:00 +0000
+++ lib/kernel/get_image_height.cl 2012-05-30 08:34:23 +0000
@@ -0,0 +1,7 @@
1#include "templates.h"
2#include "image.h"
3
4int get_image_width (image2d_t image)
5{
6 return image->height;
7}
0\ No newline at end of file8\ No newline at end of file
19
=== added file 'lib/kernel/get_image_width.cl'
--- lib/kernel/get_image_width.cl 1970-01-01 00:00:00 +0000
+++ lib/kernel/get_image_width.cl 2012-05-30 08:34:23 +0000
@@ -0,0 +1,7 @@
1#include "templates.h"
2#include "image.h"
3
4int get_image_width (image2d_t image)
5{
6 return image->width;
7}
0\ No newline at end of file8\ No newline at end of file
19
=== added file 'lib/kernel/image.h'
--- lib/kernel/image.h 1970-01-01 00:00:00 +0000
+++ lib/kernel/image.h 2012-05-30 08:34:23 +0000
@@ -0,0 +1,15 @@
1#ifndef __IMAGE_H__
2#define __IMAGE_H__
3
4#include "templates.h"
5
6typedef struct image2d_t_ {
7 uchar4* data;
8 int width;
9 int height;
10 int rowpitch;
11 int order;
12 int data_type;
13} image2d_t_;
14
15#endif
016
=== added file 'lib/kernel/read_image.cl'
--- lib/kernel/read_image.cl 1970-01-01 00:00:00 +0000
+++ lib/kernel/read_image.cl 2012-05-30 08:34:23 +0000
@@ -0,0 +1,30 @@
1#include "templates.h"
2
3#include "image.h"
4
5float4 _cl_overloadable read_imagef ( image2d_t image,
6 sampler_t sampler,
7 int2 coord) {
8 //TODO: Sampler options
9 if( coord.x<0 )
10 coord.x=0;
11 if( coord.y<0 )
12 coord.y=0;
13 if( coord.x>=image->width )
14 coord.x=image->width-1;
15 if( coord.y>=image->height )
16 coord.y=image->height-1;
17
18 float4 color = ((float4*)image->data)[ coord.x + coord.y*image->rowpitch ];
19
20 return color;
21}
22
23float4 _cl_overloadable read_imagef ( image2d_t image,
24 sampler_t sampler,
25 float2 coord) {
26
27 float4 color = ((float4*)image->data)[ (int)coord.x + (int)coord.y*image->rowpitch ];
28
29 return color;
30}
031
=== modified file 'lib/kernel/sources.mk'
--- lib/kernel/sources.mk 2012-03-05 15:33:38 +0000
+++ lib/kernel/sources.mk 2012-05-30 08:34:23 +0000
@@ -130,7 +130,11 @@
130 vload_half.cl \130 vload_half.cl \
131 vstore_half.cl \131 vstore_half.cl \
132 async_work_group_copy.cl \132 async_work_group_copy.cl \
133 wait_group_events.cl133 wait_group_events.cl \
134 read_image.cl \
135 write_image.cl \
136 get_image_width.cl \
137 get_image_height.cl
134138
135139
136140
137141
=== added file 'lib/kernel/write_image.cl'
--- lib/kernel/write_image.cl 1970-01-01 00:00:00 +0000
+++ lib/kernel/write_image.cl 2012-05-30 08:34:23 +0000
@@ -0,0 +1,17 @@
1#include "templates.h"
2
3#include "image.h"
4
5//typedef struct image2d_t_* image2d_t;
6
7void _cl_overloadable write_imagef ( image2d_t image,
8 int2 coord,
9 float4 color) {
10 ((float4*)image->data)[ coord.x + coord.y*image->rowpitch ] = color;
11}
12
13void _cl_overloadable write_imagei ( image2d_t image,
14 int2 coord,
15 int4 color) {
16 ((float4*)image->data)[ coord.x + coord.y*image->rowpitch ] = (float4)(color.x,color.y,color.z,color.w);
17}
018
=== modified file 'lib/llvmopencl/GenerateHeader.cc'
--- lib/llvmopencl/GenerateHeader.cc 2012-02-24 17:50:01 +0000
+++ lib/llvmopencl/GenerateHeader.cc 2012-05-30 08:34:23 +0000
@@ -123,6 +123,8 @@
123 return changed;123 return changed;
124}124}
125125
126#include <iostream>
127
126128
127129
128void130void
129GenerateHeader::ProcessPointers(Function *F,131GenerateHeader::ProcessPointers(Function *F,
@@ -134,12 +136,17 @@
134 136
135 bool is_pointer[num_args];137 bool is_pointer[num_args];
136 bool is_local[num_args];138 bool is_local[num_args];
139 bool is_image[num_args];
140 bool is_sampler[num_args];
137 141
138 int i = 0;142 int i = 0;
139 for (Function::const_arg_iterator ii = F->arg_begin(),143 for (Function::const_arg_iterator ii = F->arg_begin(),
140 ee = F->arg_end();144 ee = F->arg_end();
141 ii != ee; ++ii) {145 ii != ee; ++ii) {
142 Type *t = ii->getType();146 Type *t = ii->getType();
147
148 is_image[i] = false;
149 is_sampler[i] = false;
143 150
144 if (const PointerType *p = dyn_cast<PointerType> (t)) {151 if (const PointerType *p = dyn_cast<PointerType> (t)) {
145 is_pointer[i] = true;152 is_pointer[i] = true;
@@ -153,6 +160,22 @@
153 is_pointer[i] = false;160 is_pointer[i] = false;
154 is_local[i] = false;161 is_local[i] = false;
155 }162 }
163
164 if( t->isPointerTy() ) {
165 if( t->getPointerElementType()->isStructTy() ) {
166 string name = t->getPointerElementType()->getStructName().str();
167 if( name == "struct.image2d_t_" ) { // TODO image3d?
168 is_image[i] = true;
169 is_pointer[i] = false;
170 is_local[i] = false;
171 }
172 if( name == "struct.sampler_t_" ) {
173 is_sampler[i] = true;
174 is_pointer[i] = false;
175 is_local[i] = false;
176 }
177 }
178 }
156 179
157 ++i;180 ++i;
158 }181 }
@@ -172,6 +195,22 @@
172 out << ", " << is_local[i];195 out << ", " << is_local[i];
173 }196 }
174 out << "}\n";197 out << "}\n";
198
199 out << "#define _" << F->getName() << "_ARG_IS_IMAGE {";
200 if (num_args != 0) {
201 out << is_image[0];
202 for (i = 1; i < num_args; ++i)
203 out << ", " << is_image[i];
204 }
205 out << "}\n";
206
207 out << "#define _" << F->getName() << "_ARG_IS_SAMPLER {";
208 if (num_args != 0) {
209 out << is_sampler[0];
210 for (i = 1; i < num_args; ++i)
211 out << ", " << is_sampler[i];
212 }
213 out << "}\n";
175}214}
176215
177216
178217
179218
=== modified file 'scripts/pocl-kernel.in'
--- scripts/pocl-kernel.in 2012-05-14 17:44:09 +0000
+++ scripts/pocl-kernel.in 2012-05-30 08:34:23 +0000
@@ -60,6 +60,8 @@
60unsigned _num_args = _${kernel}_NUM_ARGS;60unsigned _num_args = _${kernel}_NUM_ARGS;
61int _arg_is_pointer[] = _${kernel}_ARG_IS_POINTER;61int _arg_is_pointer[] = _${kernel}_ARG_IS_POINTER;
62int _arg_is_local[] = _${kernel}_ARG_IS_LOCAL;62int _arg_is_local[] = _${kernel}_ARG_IS_LOCAL;
63int _arg_is_image[] = _${kernel}_ARG_IS_IMAGE;
64int _arg_is_sampler[] = _${kernel}_ARG_IS_SAMPLER;
63unsigned _num_locals = _${kernel}_NUM_LOCALS;65unsigned _num_locals = _${kernel}_NUM_LOCALS;
64#if _${kernel}_NUM_LOCALS != 066#if _${kernel}_NUM_LOCALS != 0
65unsigned _local_sizes[_${kernel}_NUM_LOCALS] = _${kernel}_LOCAL_SIZE;67unsigned _local_sizes[_${kernel}_NUM_LOCALS] = _${kernel}_LOCAL_SIZE;
@@ -93,6 +95,8 @@
93#endif95#endif
94 _${kernel}_ARG_IS_LOCAL,96 _${kernel}_ARG_IS_LOCAL,
95 _${kernel}_ARG_IS_POINTER,97 _${kernel}_ARG_IS_POINTER,
98 _${kernel}_ARG_IS_IMAGE,
99 _${kernel}_ARG_IS_SAMPLER,
96 _${kernel}_workgroup_fast100 _${kernel}_workgroup_fast
97};101};
98EOF102EOF
99103
=== modified file 'tests/testsuite-samples.at'
--- tests/testsuite-samples.at 2012-05-24 21:26:09 +0000
+++ tests/testsuite-samples.at 2012-05-30 08:34:23 +0000
@@ -73,6 +73,32 @@
73 73
74AT_CLEANUP74AT_CLEANUP
7575
76AT_SETUP([Run Chapter 8: ImageFilter2D])
77AT_KEYWORDS([booksamples imagefilter2d])
78AT_SKIP_IF([! test -e $abs_top_srcdir/examples/opencl-book-samples/checkout])
79AT_CHECK_UNQUOTED([
80cd ${abs_top_srcdir}/examples/opencl-book-samples/checkout/src/Chapter_8/ImageFilter2D ;
81#sed '13c\ ' -i ImageFilter2D.cl ;
82#sed '14c\ ' -i ImageFilter2D.cl ;
83#sed '15c\ ' -i ImageFilter2D.cl ;
84#sed "3c float kernelWeights[9] = { 1.0f, 2.0f, 1.0f, 2.0f, 4.0f, 2.0f,1.0f, 2.0f, 1.0f }; \ " -i ImageFilter2D.cl ;
85cp ${abs_top_srcdir}/examples/opencl-book-samples/ImageFilter2D.cl ./
86sed '418cclFinish(commandQueue);' -i ImageFilter2D.cpp ;
87cd ${abs_top_srcdir}/examples/opencl-book-samples/checkout/build/src/Chapter_8/ImageFilter2D ;
88make]
89, 0, [ignore], [ignore])
90
91AT_CHECK_UNQUOTED([
92cd $abs_top_srcdir/examples/opencl-book-samples/checkout/build/src/Chapter_8/ImageFilter2D
93./ImageFilter2D ../../../../src/Chapter_19/oclFlow/data/minicooper/frame10.png output.png
94], 0,
95[Could not create GPU context, trying CPU...
96
97Executed program succesfully.
98], [ignore])
99
100AT_CLEANUP
101
76AT_SETUP([Run Chapter 12: VectorAdd (C++ bindings)])102AT_SETUP([Run Chapter 12: VectorAdd (C++ bindings)])
77AT_KEYWORDS([booksamples])103AT_KEYWORDS([booksamples])
78AT_SKIP_IF([! test -e $abs_top_srcdir/examples/opencl-book-samples/checkout])104AT_SKIP_IF([! test -e $abs_top_srcdir/examples/opencl-book-samples/checkout])