1%%% @author Tony Rogvall <tony@rogvall.se>
2%%% @copyright (C) 2014, Tony Rogvall
3%%% @doc
4%%%     cl_image test
5%%% @end
6%%% Created :  9 May 2014 by Tony Rogvall <tony@rogvall.se>
7
8-module(cl_image).
9
10-export([init_per_suite/1, end_per_suite/1]).
11-export([all/0,
12	 create_image2d_a/1,
13	 create_image2d_b/1,
14	 create_image2d_c/1,
15	 create_image2d_d/1,
16	 create_image3d_a/1,
17	 create_image3d_b/1,
18	 create_image3d_c/1,
19	 create_image3d_d/1,
20	 pixop/1]).
21
22-include_lib("cl/include/cl.hrl").
23
24-spec init_per_suite(Config0::list(tuple())) ->
25                            (Config1::list(tuple())) |
26                            {skip,Reason::term()} |
27                            {skip_and_save,Reason::term(),
28			     Config1::list(tuple())}.
29
30init_per_suite(Config) -> cl_SUITE:init_per_suite(Config).
31
32-spec end_per_suite(Config::list(tuple())) -> ok.
33
34end_per_suite(_Config) ->
35    ok.
36
37
38all() ->
39    [create_image2d_a, create_image2d_b, create_image2d_c, create_image2d_d,
40     create_image3d_a, create_image3d_b, create_image3d_c, create_image3d_d,
41     pixop
42    ].
43
44
45create_image2d_a(Config) ->
46    C = clu:setup(proplists:get_value(type,Config,gpu)),
47    cl:create_image2d(clu:context(C),[read_write],
48		      #cl_image_format { cl_channel_order = rgba,
49					 cl_channel_type  = unorm_int8 },
50		      64,
51		      64,
52		      0,
53		      <<>>).
54
55create_image2d_b(Config) ->
56    C = clu:setup(proplists:get_value(type,Config,gpu)),
57    ImageData = create_image2d_data(64, 64, 4),
58    cl:create_image2d(clu:context(C),[read_write],
59		      #cl_image_format { cl_channel_order = rgba,
60					 cl_channel_type  = unorm_int8 },
61		      64,
62		      64,
63		      64*4,
64		      ImageData).
65
66create_image2d_c(Config) ->
67    true = lists:member({1,2},cl:versions()),
68    C = clu:setup(proplists:get_value(type,Config,gpu)),
69    cl:create_image(clu:context(C),[read_write],
70		    #cl_image_format { cl_channel_order = rgba,
71				       cl_channel_type  = unorm_int8 },
72		    #cl_image_desc {
73		       image_type = image2d,
74		       image_width = 64,
75		       image_height = 64,
76		       image_depth = 1,
77		       image_array_size = 1,
78		       image_row_pitch = 0 },
79		    <<>>).
80
81create_image2d_d(Config) ->
82    true = lists:member({1,2},cl:versions()),
83    C = clu:setup(proplists:get_value(type,Config,gpu)),
84    ImageData = create_image2d_data(64, 64, 4),
85    cl:create_image(clu:context(C),[read_write],
86		    #cl_image_format { cl_channel_order = rgba,
87				       cl_channel_type  = unorm_int8 },
88		    #cl_image_desc {
89		       image_type = image2d,
90		       image_width = 64,
91		       image_height = 64,
92		       image_depth = 1,
93		       image_array_size = 1,
94		       image_row_pitch = 64*4 },
95		    ImageData).
96
97create_image2d_data(W,H,BytesPerPixel) ->
98    << <<1234:BytesPerPixel/unit:8>> ||
99	_ <- lists:seq(1,W),
100	_ <- lists:seq(1,H) >>.
101
102
103create_image3d_a(Config) ->
104    C = clu:setup(proplists:get_value(type,Config,gpu)),
105    cl:create_image3d(clu:context(C),[read_write],
106		      #cl_image_format { cl_channel_order = rgba,
107					 cl_channel_type  = unorm_int8 },
108		      64,
109		      64,
110		      64,
111		      0,
112		      0,
113		      <<>>).
114
115create_image3d_b(Config) ->
116    C = clu:setup(proplists:get_value(type,Config,gpu)),
117    ImageData = create_image3d_data(64, 64, 64, 4),
118    cl:create_image3d(clu:context(C),[read_write],
119		      #cl_image_format { cl_channel_order = rgba,
120					 cl_channel_type  = unorm_int8 },
121		      64,
122		      64,
123		      64,
124		      64*4,
125		      64*64*4,
126		      ImageData).
127
128create_image3d_c(Config) ->
129    true = lists:member({1,2},cl:versions()),
130    C = clu:setup(proplists:get_value(type,Config,gpu)),
131    cl:create_image(clu:context(C),[read_write],
132		    #cl_image_format { cl_channel_order = rgba,
133				       cl_channel_type  = unorm_int8 },
134		    #cl_image_desc {
135		       image_type = image3d,
136		       image_width = 64,
137		       image_height = 64,
138		       image_depth = 64,
139		       image_array_size = 1,
140		       image_row_pitch = 0,
141		       image_slice_pitch = 0
142		      },
143		    <<>>).
144
145create_image3d_d(Config) ->
146    true = lists:member({1,2},cl:versions()),
147    C = clu:setup(proplists:get_value(type,Config,gpu)),
148    ImageData = create_image3d_data(64, 64, 64, 4),
149    cl:create_image(clu:context(C),[read_write],
150		    #cl_image_format { cl_channel_order = rgba,
151				       cl_channel_type  = unorm_int8 },
152		    #cl_image_desc {
153		       image_type = image3d,
154		       image_width = 64,
155		       image_height = 64,
156		       image_depth = 64,
157		       image_array_size = 1,
158		       image_row_pitch = 64*4,
159		       image_slice_pitch = 64*64*4
160		      },
161		    ImageData).
162
163
164create_image3d_data(W,H,D,BytesPerPixel) ->
165    << <<Di:BytesPerPixel/unit:8>> ||
166	Di <- lists:seq(1,D),
167	_ <- lists:seq(1,H),
168	_ <- lists:seq(1,W)
169    >>.
170
171%% test image pixel operations
172
173pixop(Config) ->
174    exit({skip, "Fails on linux machine"}),
175    Clu = clu:setup(proplists:get_value(type,Config,cpu)),
176    {ok,A} =
177	cl:create_image2d(clu:context(Clu),[read_write],
178			  #cl_image_format { cl_channel_order = rgba,
179					     cl_channel_type  = unorm_int8 },
180			  2,
181			  2,
182			  2*4,
183			  <<100,200,50,127, 25,255,50,100,
184			    30,64,10,20,    3,2,1,220>> ),
185    %% {ok,E1} = cl:enqueue_write_image(Q, A, [0,0], [2,2], 2*4, 0, Data, []),
186    {ok,B} =
187	cl:create_image2d(clu:context(Clu),[read_write],
188			  #cl_image_format { cl_channel_order = rgba,
189					     cl_channel_type  = unorm_int8 },
190			  2,
191			  2,
192			  2*4,
193			  <<50,100,25,255,  100,100,100,127,
194			    100,200,50,127, 1,2,3,20>>),
195    {ok,C} =
196	cl:create_image2d(clu:context(Clu),[read_write],
197			  #cl_image_format { cl_channel_order = rgba,
198					     cl_channel_type  = unorm_int8 },
199			  2,
200			  2,
201			  0,
202			  <<>>),
203
204    {ok,Q} = cl:create_queue(clu:context(Clu),clu:device(Clu),[]),
205    File =
206	case proplists:get_value(data_dir, Config) of
207	    false -> "pixop.cl";
208	    Dir -> filename:join(filename:dirname(filename:dirname(Dir)), "pixop.cl")
209	end,
210    io:format("File: ~p~n", [File]),
211    {ok,Program} = clu:build_source_file(Clu, File, ""),
212    {ok,Kernel} = cl:create_kernel(Program, "pixmap_blend"),
213    clu:apply_kernel_args(Kernel, [A,B,C,2,2]),
214    {ok,E1} = cl:enqueue_nd_range_kernel(Q, Kernel,
215					 [2,2], [],
216					 []),
217    cl:flush(Q),
218    {ok,completed} = cl:wait(E1),
219
220    {ok,E2}  = cl:enqueue_read_image(Q, C, [0,0], [2,2], 2*4, 0, []),
221    cl:flush(Q),
222    {ok,Data} = cl:wait(E2),
223    Data.
224