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>
22 class cImage_check_mem_host_write_only
23 : public cImage_check_mem_host_read_only<T> {
24
25 public:
cImage_check_mem_host_write_only(cl_device_id deviceID,cl_context context,cl_command_queue queue)26 cImage_check_mem_host_write_only(cl_device_id deviceID, cl_context context,
27 cl_command_queue queue)
28 : cImage_check_mem_host_read_only<T>(deviceID, context, queue)
29 {}
30
~cImage_check_mem_host_write_only()31 ~cImage_check_mem_host_write_only(){};
32
33 clMemWrapper m_Image_2;
34
35 cl_int verify_RW_Image();
36 cl_int verify_RW_Image_Mapping();
37
38 cl_int Setup_Test_Environment();
39 cl_int update_host_mem_2();
40
41 cl_int verify_data(T *pdtaIn);
42 };
43
44 template <class T>
Setup_Test_Environment()45 cl_int cImage_check_mem_host_write_only<T>::Setup_Test_Environment()
46 {
47 int all = this->get_image_elements();
48
49 T vv2 = 0;
50 this->host_m_2.Init(all, vv2);
51 vv2 = TEST_VALUE;
52 this->host_m_0.Init(all, vv2);
53
54 cl_int err = CL_SUCCESS;
55 this->m_Image_2 = clCreateImage(
56 this->m_context,
57 CL_MEM_READ_WRITE | CL_MEM_HOST_READ_ONLY | CL_MEM_COPY_HOST_PTR,
58 &(this->m_cl_image_format), &(this->m_cl_Image_desc),
59 this->host_m_2.pData, &err);
60 test_error(err, "clCreateImage error");
61
62 return err;
63 }
64
65 // Copy image data from a write_only image to a read_write image and read the
66 // contents.
67 template <class T>
update_host_mem_2()68 cl_int cImage_check_mem_host_write_only<T>::update_host_mem_2()
69 {
70 size_t orig[3] = { 0, 0, 0 };
71 size_t img_region[3] = { 0, 0, 0 };
72 img_region[0] = this->m_cl_Image_desc.image_width;
73 img_region[1] = this->m_cl_Image_desc.image_height;
74 img_region[2] = this->m_cl_Image_desc.image_depth;
75
76 cl_event event;
77 cl_int err = CL_SUCCESS;
78 err = clEnqueueCopyImage(this->m_queue, this->m_Image, this->m_Image_2,
79 orig, orig, img_region, 0, NULL, &event);
80 test_error(err, "clEnqueueCopyImage error");
81
82 if (!this->m_blocking)
83 {
84 err = clWaitForEvents(1, &event);
85 test_error(err, "clWaitForEvents error");
86 }
87
88 err = clReleaseEvent(event);
89 test_error(err, "clReleaseEvent error");
90
91 this->host_m_2.Set_to_zero();
92
93 err = clEnqueueReadImage(
94 this->m_queue, this->m_Image_2, this->m_blocking, this->buffer_origin,
95 this->region, this->buffer_row_pitch_bytes,
96 this->buffer_slice_pitch_bytes, this->host_m_2.pData, 0, NULL, &event);
97 test_error(err, "clEnqueueReadImage error");
98
99 if (!this->m_blocking)
100 {
101 err = clWaitForEvents(1, &event);
102 test_error(err, "clWaitForEvents error");
103 }
104
105 err = clReleaseEvent(event);
106 test_error(err, "clReleaseEvent error");
107
108 return err;
109 }
110
111 template <class T>
verify_data(T * pdtaIn)112 cl_int cImage_check_mem_host_write_only<T>::verify_data(T *pdtaIn)
113 {
114 cl_int err = CL_SUCCESS;
115 if (!this->host_m_1.Equal_rect_from_orig(pdtaIn, this->buffer_origin,
116 this->region, this->host_row_pitch,
117 this->host_slice_pitch))
118 {
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 {
128 log_error("Image data content difference found\n");
129 return FAILURE;
130 }
131
132 return err;
133 }
134
verify_RW_Image()135 template <class T> 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, this->m_Image, &color, img_orig,
150 img_region, 0, NULL,
151 &event); // Fill the buffer with data
152
153 if (!this->m_blocking)
154 {
155 err = clWaitForEvents(1, &event);
156 test_error(err, "clWaitForEvents error");
157 }
158 test_error(err, "clEnqueueFillImage error");
159
160 err = clReleaseEvent(event);
161 test_error(err, "clReleaseEvent error");
162
163 T v = TEST_VALUE;
164
165 err = clEnqueueWriteImage(
166 this->m_queue, this->m_Image, this->m_blocking, this->buffer_origin,
167 this->region, this->buffer_row_pitch_bytes,
168 this->buffer_slice_pitch_bytes, this->host_m_0.pData, 0, NULL, &event);
169 test_error(err, "clEnqueueWriteImage error"); // Test writing to buffer
170
171 if (!this->m_blocking)
172 {
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(
183 this->host_m_2
184 .pData); // Compare the contents of mem_2 and mem_1,
185 // mem_1 is same as mem_0 in setup test environment
186 test_error(err, "verify_data error");
187
188 v = 0;
189 this->host_m_2.Set_to(v);
190 err = clEnqueueReadImage(
191 this->m_queue, this->m_Image, this->m_blocking, this->buffer_origin,
192 this->region, this->buffer_row_pitch_bytes,
193 this->buffer_slice_pitch_bytes, this->host_m_1.pData, 0, NULL, &event);
194
195 if (err == CL_SUCCESS)
196 {
197 log_error(
198 "Calling clEnqueueReadImage on a memory object created with the "
199 "CL_MEM_HOST_WRITE_ONLY flag should not return CL_SUCCESS\n");
200 err = FAILURE;
201 return FAILURE;
202 }
203 else
204 {
205 log_info("Test succeeded\n\n");
206 err = CL_SUCCESS;
207 }
208
209 /* Qualcomm fix: 12506 Do not wait on invalid event/ no need for
210 syncronization calls after clEnqueueReadImage fails
211 *
212 * The call to clEnqueueReadImage fails as expected and returns an invalid
213 event on
214 * which clWaitForEvents cannot be called. (It will rightly fail with a
215 CL_INVALID_EVENT error)
216 * Further, we don't need to do any additional flushes or finishes here
217 since we were in sync
218 * before the (failing) call to clEnqueueReadImage
219
220 if (!this->m_blocking) {
221 err = clWaitForEvents(1, &event);
222 test_error(err, " clWaitForEvents error")
223 }
224 Qualcomm fix: end*/
225
226 return err;
227 }
228
229 template <class T>
verify_RW_Image_Mapping()230 cl_int cImage_check_mem_host_write_only<T>::verify_RW_Image_Mapping()
231 {
232 this->Init_rect();
233
234 cl_event event;
235 size_t img_orig[3] = { 0, 0, 0 };
236 size_t img_region[3] = { 0, 0, 0 };
237 img_region[0] = this->m_cl_Image_desc.image_width;
238 img_region[1] = this->m_cl_Image_desc.image_height;
239 img_region[2] = this->m_cl_Image_desc.image_depth;
240
241 int color[4] = { 0xFF, 0xFF, 0xFF, 0xFF };
242 cl_int err = CL_SUCCESS;
243
244
245 // Fill image with pattern
246 err = clEnqueueFillImage(this->m_queue, this->m_Image, &color, img_orig,
247 img_region, 0, NULL, &event);
248
249 if (!this->m_blocking)
250 {
251 err = clWaitForEvents(1, &event);
252 test_error(err, "clWaitForEvents error");
253 }
254
255 err = clReleaseEvent(event);
256 test_error(err, "clReleaseEvent error");
257
258 // Map image for writing
259 T* dataPtr = (T*)clEnqueueMapImage(
260 this->m_queue, this->m_Image, this->m_blocking, CL_MAP_WRITE,
261 this->buffer_origin, this->region, &(this->buffer_row_pitch_bytes),
262 &(this->buffer_slice_pitch_bytes), 0, NULL, &event, &err);
263 test_error(err, "clEnqueueMapImage CL_MAP_WRITE pointer error");
264
265 if (!this->m_blocking)
266 {
267 err = clWaitForEvents(1, &event);
268 test_error(err, "clWaitForEvents error");
269 }
270
271 err = clReleaseEvent(event);
272 test_error(err, "clReleaseEvent error");
273
274 // Verify map pointer
275 err = this->verify_mapping_ptr(dataPtr);
276 test_error(err, "clEnqueueMapImage CL_MAP_WRITE pointer error");
277
278 // Verify mapped data
279
280 // The verify_data_with_offset method below compares dataPtr against
281 // this->host_m_2.pData. The comparison should start at origin {0, 0, 0}.
282 update_host_mem_2();
283
284 // Check the content of mem and host_ptr
285 size_t offset[3] = { 0, 0, 0 };
286 err = cImage_check_mem_host_read_only<T>::verify_data_with_offset(dataPtr,
287 offset);
288 test_error(err, "verify_data error");
289
290 // Unmap memory object
291 err = clEnqueueUnmapMemObject(this->m_queue, this->m_Image, dataPtr, 0,
292 NULL, &event);
293 test_error(err, "clEnqueueUnmapMemObject error");
294
295 if (!this->m_blocking)
296 {
297 err = clWaitForEvents(1, &event);
298 test_error(err, "clWaitForEvents error");
299 }
300
301 err = clReleaseEvent(event);
302 test_error(err, "clReleaseEvent error");
303
304 dataPtr = (T*)clEnqueueMapImage(
305 this->m_queue, this->m_Image, this->m_blocking, CL_MAP_READ,
306 this->buffer_origin, this->region, &(this->buffer_row_pitch_bytes),
307 &(this->buffer_slice_pitch_bytes), 0, NULL, &event, &err);
308
309 if (err == CL_SUCCESS)
310 {
311 log_error("Calling clEnqueueMapImage (CL_MAP_READ) on a memory object "
312 "created with the CL_MEM_HOST_WRITE_ONLY flag should not "
313 "return CL_SUCCESS\n");
314 err = FAILURE;
315 return FAILURE;
316 }
317 else
318 {
319 log_info("Test succeeded\n\n");
320 err = CL_SUCCESS;
321 }
322
323 return err;
324 }
325
326 #endif
327