1 //
2 // Copyright (c) 2017 The Khronos Group Inc.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 #ifndef test_conformance_checker_Image_MEM_HOST_WRITE_ONLY_h
17 #define test_conformance_checker_Image_MEM_HOST_WRITE_ONLY_h
18
19 #include "checker_image_mem_host_read_only.hpp"
20
21 template < class T> class cImage_check_mem_host_write_only : public cImage_check_mem_host_read_only<T>
22 {
23
24 public:
cImage_check_mem_host_write_only(cl_device_id deviceID,cl_context context,cl_command_queue queue)25 cImage_check_mem_host_write_only(cl_device_id deviceID, cl_context context, cl_command_queue queue)
26 : cImage_check_mem_host_read_only <T> (deviceID, context, queue)
27 {
28 }
29
~cImage_check_mem_host_write_only()30 ~cImage_check_mem_host_write_only() {};
31
32 clMemWrapper m_Image_2;
33
34 cl_int verify_RW_Image();
35 cl_int verify_RW_Image_Mapping();
36
37 cl_int Setup_Test_Environment();
38 cl_int update_host_mem_2();
39
40 cl_int verify_data();
41 };
42
43 template < class T >
Setup_Test_Environment()44 cl_int cImage_check_mem_host_write_only<T>::Setup_Test_Environment()
45 {
46 int all= this->get_image_elements();
47
48 T vv2 = 0;
49 this->host_m_2.Init( all, vv2);
50 vv2 = TEST_VALUE;
51 this->host_m_0.Init( all, vv2);
52
53 cl_int err = CL_SUCCESS;
54 this->m_Image_2 = clCreateImage(this->m_context,
55 CL_MEM_READ_WRITE | CL_MEM_HOST_READ_ONLY | CL_MEM_COPY_HOST_PTR,
56 &( this-> m_cl_image_format), &(this->m_cl_Image_desc),
57 this->host_m_2.pData, &err);
58 test_error(err, "clCreateImage error");
59
60 return err;
61 }
62
63 // Copy image data from a write_only image to a read_write image and read the
64 // contents.
65 template < class T >
update_host_mem_2()66 cl_int cImage_check_mem_host_write_only< T >::update_host_mem_2()
67 {
68 size_t orig[3] = {0, 0, 0};
69 size_t img_region[3] = {0, 0, 0};
70 img_region[0] = this->m_cl_Image_desc.image_width;
71 img_region[1] = this->m_cl_Image_desc.image_height;
72 img_region[2] = this->m_cl_Image_desc.image_depth;
73
74 cl_event event;
75 cl_int err = CL_SUCCESS;
76 err = clEnqueueCopyImage(this->m_queue,
77 this->m_Image,
78 this->m_Image_2,
79 orig,
80 orig,
81 img_region,
82 0, NULL, &event);
83 test_error(err, "clEnqueueCopyImage error");
84
85 if (!this->m_blocking) {
86 err = clWaitForEvents(1, &event);
87 test_error(err, "clWaitForEvents error");
88 }
89
90 err = clReleaseEvent(event);
91 test_error(err, "clReleaseEvent error");
92
93 this->host_m_2.Set_to_zero();
94
95 err = clEnqueueReadImage(this->m_queue, this->m_Image_2, this->m_blocking,
96 this->buffer_origin, this->region,
97 this->buffer_row_pitch_bytes, this->buffer_slice_pitch_bytes,
98 this->host_m_2.pData, 0, NULL, &event);
99 test_error(err, "clEnqueueReadImage error");
100
101 if (!this->m_blocking) {
102 err = clWaitForEvents(1, &event);
103 test_error(err, "clWaitForEvents error");
104 }
105
106 err = clReleaseEvent(event);
107 test_error(err, "clReleaseEvent error");
108
109 return err;
110 }
111
112 template < class T >
verify_data()113 cl_int cImage_check_mem_host_write_only<T>::verify_data()
114 {
115 cl_int err = CL_SUCCESS;
116 if (!this->host_m_1.Equal_rect_from_orig(this->host_m_2, this->buffer_origin,
117 this->region, this->host_row_pitch,
118 this->host_slice_pitch)) {
119 log_error("Image and host data difference found\n");
120 return FAILURE;
121 }
122
123 int total = (int)(this->region[0] * this->region[1] * this->region[2]);
124 T v = TEST_VALUE;
125 int tot = (int)(this->host_m_2.Count(v));
126 if(tot != total) {
127 log_error("Image data content difference found\n");
128 return FAILURE;
129 }
130
131 return err;
132 }
133
134 template < class T >
verify_RW_Image()135 cl_int cImage_check_mem_host_write_only<T>::verify_RW_Image()
136 {
137 cl_int err = CL_SUCCESS;
138
139 this->Init_rect();
140
141 cl_event event;
142 size_t img_orig[3] = {0, 0, 0};
143 size_t img_region[3] = {0, 0, 0};
144 img_region[0] = this->m_cl_Image_desc.image_width;
145 img_region[1] = this->m_cl_Image_desc.image_height;
146 img_region[2] = this->m_cl_Image_desc.image_depth;
147
148 int color[4] = {0xFF, 0xFF, 0xFF, 0xFF};
149 err = clEnqueueFillImage(this->m_queue,
150 this->m_Image,
151 &color,
152 img_orig, img_region,
153 0, NULL, &event); // Fill the buffer with data
154
155 if (!this->m_blocking) {
156 err = clWaitForEvents(1, &event);
157 test_error(err, "clWaitForEvents error");
158 }
159 test_error(err, "clEnqueueFillImage error");
160
161 err = clReleaseEvent(event);
162 test_error(err, "clReleaseEvent error");
163
164 T v = TEST_VALUE;
165
166 err= clEnqueueWriteImage(this->m_queue, this->m_Image, this->m_blocking,
167 this->buffer_origin, this->region,
168 this->buffer_row_pitch_bytes, this->buffer_slice_pitch_bytes,
169 this->host_m_0.pData, 0, NULL, &event);
170 test_error(err, "clEnqueueWriteImage error"); // Test writing to buffer
171
172 if (!this->m_blocking) {
173 err = clWaitForEvents(1, &event);
174 test_error(err, "clWaitForEvents error");
175 }
176
177 err = clReleaseEvent(event);
178 test_error(err, "clReleaseEvent error");
179
180 update_host_mem_2(); // Read buffer contents into mem_2
181
182 err = this->verify_data(); // Compare the contents of mem_2 and mem_1,
183 // mem_1 is same as mem_0 in setup test environment
184 test_error(err, "verify_data error");
185
186 v = 0;
187 this->host_m_2.Set_to(v);
188 err = clEnqueueReadImage(this->m_queue, this->m_Image, this->m_blocking,
189 this->buffer_origin, this->region,
190 this->buffer_row_pitch_bytes, this->buffer_slice_pitch_bytes,
191 this->host_m_1.pData, 0, NULL, &event);
192
193 if (err == CL_SUCCESS){
194 log_error("Calling clEnqueueReadImage on a memory object created with the CL_MEM_HOST_WRITE_ONLY flag should not return CL_SUCCESS\n");
195 err = FAILURE;
196 return FAILURE;
197
198 } else {
199 log_info("Test succeeded\n\n");
200 err = CL_SUCCESS;
201 }
202
203 /* Qualcomm fix: 12506 Do not wait on invalid event/ no need for syncronization calls after clEnqueueReadImage fails
204 *
205 * The call to clEnqueueReadImage fails as expected and returns an invalid event on
206 * which clWaitForEvents cannot be called. (It will rightly fail with a CL_INVALID_EVENT error)
207 * Further, we don't need to do any additional flushes or finishes here since we were in sync
208 * before the (failing) call to clEnqueueReadImage
209
210 if (!this->m_blocking) {
211 err = clWaitForEvents(1, &event);
212 test_error(err, " clWaitForEvents error")
213 }
214 Qualcomm fix: end*/
215
216 return err;
217 }
218
219 template < class T >
verify_RW_Image_Mapping()220 cl_int cImage_check_mem_host_write_only<T>::verify_RW_Image_Mapping()
221 {
222 this->Init_rect();
223
224 cl_event event;
225 size_t img_orig[3] = {0, 0, 0};
226 size_t img_region[3] = {0, 0, 0};
227 img_region[0] = this->m_cl_Image_desc.image_width;
228 img_region[1] = this->m_cl_Image_desc.image_height;
229 img_region[2] = this->m_cl_Image_desc.image_depth;
230
231 int color[4] = {0xFF, 0xFF, 0xFF, 0xFF};
232 cl_int err = CL_SUCCESS;
233
234
235 // Fill image with pattern
236 err = clEnqueueFillImage(this->m_queue, this->m_Image,
237 &color, img_orig, img_region,
238 0, NULL, &event);
239
240 if (!this->m_blocking) {
241 err = clWaitForEvents(1, &event);
242 test_error(err, "clWaitForEvents error");
243 }
244
245 err = clReleaseEvent(event);
246 test_error(err, "clReleaseEvent error");
247
248 // Map image for writing
249 T* dataPtr = (T*) clEnqueueMapImage(this->m_queue, this->m_Image,
250 this->m_blocking, CL_MAP_WRITE,
251 this->buffer_origin, this->region,
252 &(this->buffer_row_pitch_bytes),
253 &(this->buffer_slice_pitch_bytes),
254 0, NULL, &event, &err);
255 test_error(err, "clEnqueueMapImage CL_MAP_WRITE pointer error");
256
257 if (!this->m_blocking) {
258 err = clWaitForEvents(1, &event);
259 test_error(err, "clWaitForEvents error");
260 }
261
262 err = clReleaseEvent(event);
263 test_error(err, "clReleaseEvent error");
264
265 // Verify map pointer
266 err = this->verify_mapping_ptr(dataPtr);
267 test_error(err, "clEnqueueMapImage CL_MAP_WRITE pointer error");
268
269 // Verify mapped data
270
271 // The verify_data_with_offset method below compares dataPtr against
272 // this->host_m_2.pData. The comparison should start at origin {0, 0, 0}.
273 update_host_mem_2();
274
275 // Check the content of mem and host_ptr
276 size_t offset[3] = {0, 0, 0};
277 err = cImage_check_mem_host_read_only<T>::verify_data_with_offset(dataPtr,
278 offset);
279 test_error(err, "verify_data error");
280
281 // Unmap memory object
282 err = clEnqueueUnmapMemObject(this->m_queue, this->m_Image, dataPtr,
283 0, NULL, &event);
284 test_error(err, "clEnqueueUnmapMemObject error");
285
286 if (!this->m_blocking) {
287 err = clWaitForEvents(1, &event);
288 test_error(err, "clWaitForEvents error");
289 }
290
291 err = clReleaseEvent(event);
292 test_error(err, "clReleaseEvent error");
293
294 dataPtr = (T*) clEnqueueMapImage(this->m_queue, this->m_Image, this->m_blocking,
295 CL_MAP_READ,
296 this->buffer_origin, this->region,
297 &(this->buffer_row_pitch_bytes),
298 &(this->buffer_slice_pitch_bytes),
299 0, NULL, &event, &err);
300
301 if (err == CL_SUCCESS) {
302 log_error("Calling clEnqueueMapImage (CL_MAP_READ) on a memory object created with the CL_MEM_HOST_WRITE_ONLY flag should not return CL_SUCCESS\n");
303 err = FAILURE;
304 return FAILURE;
305
306 } else {
307 log_info("Test succeeded\n\n");
308 err = CL_SUCCESS;
309 }
310
311 return err;
312 }
313
314 #endif
315