• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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