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_READ_ONLY_h
17 #define test_conformance_checker_Image_MEM_HOST_READ_ONLY_h
18 
19 #include "checker.h"
20 
21 template <class T>
22 class cImage_check_mem_host_read_only : public cBuffer_checker<T> {
23 public:
cImage_check_mem_host_read_only(cl_device_id deviceID,cl_context context,cl_command_queue queue)24     cImage_check_mem_host_read_only(cl_device_id deviceID, cl_context context,
25                                     cl_command_queue queue)
26         : cBuffer_checker<T>(deviceID, context, queue)
27     {
28         m_cl_image_format.image_channel_order = CL_RGBA;
29         m_cl_image_format.image_channel_data_type = CL_UNSIGNED_INT8;
30 
31         m_cl_Image_desc.image_type = CL_MEM_OBJECT_IMAGE1D;
32         m_cl_Image_desc.image_width = 0;
33         m_cl_Image_desc.image_height = 0;
34         m_cl_Image_desc.image_depth = 0;
35         m_cl_Image_desc.image_array_size = 0;
36         m_cl_Image_desc.image_row_pitch = 0;
37         m_cl_Image_desc.image_slice_pitch = 0;
38         m_cl_Image_desc.num_mip_levels = 0;
39         m_cl_Image_desc.num_samples = 0;
40         m_cl_Image_desc.mem_object = NULL;
41 
42         m_Image = NULL;
43     };
44 
~cImage_check_mem_host_read_only()45     ~cImage_check_mem_host_read_only(){};
46 
47     cl_int get_image_elements();
48 
49     cl_image_format m_cl_image_format;
50     cl_image_desc m_cl_Image_desc;
51     clMemWrapper m_Image;
52 
53     virtual cl_int SetupImage();
54     virtual cl_int SetupBuffer();
55     virtual cl_int verify_RW_Image();
56 
57     virtual cl_int verify_RW_Image_Mapping();
58     virtual cl_int verify_data(T *pdtaIn);
59     virtual cl_int verify_data_with_offset(T *pdtaIn, size_t *offset);
60 
61     cl_int get_image_content_size();
62     cl_int get_image_data_size();
63 
64     virtual cl_int verify_RW_Buffer();
65     virtual cl_int verify_RW_Buffer_rect();
66     virtual cl_int verify_RW_Buffer_mapping();
67     cl_int verify_mapping_ptr(T *ptr);
68 };
69 
70 template <class T>
verify_mapping_ptr(T * dataPtr)71 cl_int cImage_check_mem_host_read_only<T>::verify_mapping_ptr(T *dataPtr)
72 {
73     int offset_pixel = (int)(this->buffer_origin[0]
74                              + this->buffer_origin[1]
75                                  * this->buffer_row_pitch_bytes / sizeof(T)
76                              + this->buffer_origin[2]
77                                  * this->buffer_slice_pitch_bytes / sizeof(T));
78 
79     dataPtr = dataPtr - offset_pixel;
80 
81     cl_int err = CL_SUCCESS;
82 
83     if (this->buffer_mem_flag & CL_MEM_USE_HOST_PTR)
84     {
85         if (this->pHost_ptr != this->host_m_1.pData)
86         {
87             log_error("Host memory pointer difference found\n");
88             return FAILURE;
89         }
90 
91         if (dataPtr != this->host_m_1.pData)
92         {
93             log_error("Mapped host pointer difference found\n");
94             return FAILURE;
95         }
96     }
97 
98     return err;
99 }
100 
verify_RW_Buffer()101 template <class T> cl_int cImage_check_mem_host_read_only<T>::verify_RW_Buffer()
102 {
103     return CL_SUCCESS;
104 };
105 
106 template <class T>
verify_RW_Buffer_rect()107 cl_int cImage_check_mem_host_read_only<T>::verify_RW_Buffer_rect()
108 {
109     return CL_SUCCESS;
110 };
111 
112 template <class T>
verify_RW_Buffer_mapping()113 cl_int cImage_check_mem_host_read_only<T>::verify_RW_Buffer_mapping()
114 {
115     return CL_SUCCESS;
116 };
117 
SetupBuffer()118 template <class T> cl_int cImage_check_mem_host_read_only<T>::SetupBuffer()
119 {
120     return cBuffer_checker<T>::SetupBuffer();
121 }
122 
123 template <class T>
get_image_content_size()124 cl_int cImage_check_mem_host_read_only<T>::get_image_content_size()
125 {
126     return ((cl_int)(m_cl_Image_desc.image_width * m_cl_Image_desc.image_height
127                      * m_cl_Image_desc.image_depth
128                      * m_cl_Image_desc.image_array_size));
129 }
130 
131 template <class T>
get_image_data_size()132 cl_int cImage_check_mem_host_read_only<T>::get_image_data_size()
133 {
134     size_t slice_pitch = m_cl_Image_desc.image_slice_pitch
135         ? m_cl_Image_desc.image_slice_pitch
136         : (m_cl_Image_desc.image_height * m_cl_Image_desc.image_width);
137     return (slice_pitch * m_cl_Image_desc.image_depth
138             * m_cl_Image_desc.image_array_size);
139 }
140 
141 template <class T>
get_image_elements()142 cl_int cImage_check_mem_host_read_only<T>::get_image_elements()
143 {
144     return ((cl_int)(m_cl_Image_desc.image_width * m_cl_Image_desc.image_height
145                      * m_cl_Image_desc.image_depth
146                      * m_cl_Image_desc.image_array_size));
147 }
148 
SetupImage()149 template <class T> cl_int cImage_check_mem_host_read_only<T>::SetupImage()
150 {
151     int all =
152         (int)(m_cl_Image_desc.image_width * m_cl_Image_desc.image_height
153               * m_cl_Image_desc.image_depth * m_cl_Image_desc.image_array_size);
154 
155     T v = TEST_VALUE;
156     this->host_m_1.Init(all, v);
157 
158     cl_int err = CL_SUCCESS;
159     this->m_Image = clCreateImage(
160         this->m_context, this->buffer_mem_flag, &(this->m_cl_image_format),
161         &(this->m_cl_Image_desc), this->host_m_1.pData, &err);
162     test_error(err, "clCreateImage error");
163 
164     this->pHost_ptr = (void *)(this->host_m_1.pData);
165 
166     return err;
167 }
168 
169 template <class T>
verify_data(T * pDataIN)170 cl_int cImage_check_mem_host_read_only<T>::verify_data(T *pDataIN)
171 {
172     cl_int err = CL_SUCCESS;
173     if (!this->host_m_1.Equal_rect_from_orig(pDataIN, this->buffer_origin,
174                                              this->region, this->host_row_pitch,
175                                              this->host_slice_pitch))
176     {
177         log_error("Buffer data difference found\n");
178         return FAILURE;
179     }
180 
181     return err;
182 }
183 
184 template <class T>
185 cl_int
verify_data_with_offset(T * pDataIN,size_t * offset)186 cImage_check_mem_host_read_only<T>::verify_data_with_offset(T *pDataIN,
187                                                             size_t *offset)
188 {
189     cl_int err = CL_SUCCESS;
190     if (!this->host_m_2.Equal_rect_from_orig(pDataIN, offset, this->region,
191                                              this->host_row_pitch,
192                                              this->host_slice_pitch))
193     {
194         log_error("Buffer data difference found\n");
195         return FAILURE;
196     }
197 
198     return err;
199 }
200 
verify_RW_Image()201 template <class T> cl_int cImage_check_mem_host_read_only<T>::verify_RW_Image()
202 {
203     this->Init_rect();
204 
205     int imge_content_size = this->get_image_content_size();
206     T v = 0;
207     this->host_m_2.Init(imge_content_size, v);
208 
209     cl_event event;
210     cl_int err = CL_SUCCESS;
211     err = clEnqueueReadImage(
212         this->m_queue, this->m_Image, this->m_blocking, this->buffer_origin,
213         this->region, this->buffer_row_pitch_bytes,
214         this->buffer_slice_pitch_bytes, this->host_m_2.pData, 0, NULL, &event);
215 
216     test_error(err, "clEnqueueReadImage error");
217 
218     if (!this->m_blocking)
219     {
220         err = clWaitForEvents(1, &event);
221         test_error(err, "clWaitForEvents error");
222     }
223 
224     err = clReleaseEvent(event);
225     test_error(err, "clReleaseEvent error");
226 
227     err = this->verify_data(this->host_m_2.pData);
228     test_error(err, "verify_data error");
229 
230     err = clEnqueueWriteImage(
231         this->m_queue, this->m_Image, this->m_blocking, this->buffer_origin,
232         this->region, this->buffer_row_pitch_bytes,
233         this->buffer_slice_pitch_bytes, this->host_m_2.pData, 0, NULL, &event);
234 
235     if (err == CL_SUCCESS)
236     {
237         log_error(
238             "Calling clEnqueueWriteImage on a memory object created with the "
239             "CL_MEM_HOST_READ_ONLY flag should not return CL_SUCCESS\n");
240         err = FAILURE;
241         return FAILURE;
242     }
243     else
244     {
245         log_info("Test succeeded\n\n");
246         err = CL_SUCCESS;
247     }
248 
249     return err;
250 }
251 
252 template <class T>
verify_RW_Image_Mapping()253 cl_int cImage_check_mem_host_read_only<T>::verify_RW_Image_Mapping()
254 {
255     cl_event event;
256     cl_int err = CL_SUCCESS;
257 
258     T *dataPtr = (T *)clEnqueueMapImage(
259         this->m_queue, this->m_Image, this->m_blocking, CL_MAP_READ,
260         this->buffer_origin, this->region, &(this->buffer_row_pitch_bytes),
261         &(this->buffer_slice_pitch_bytes), 0, NULL, &event, &err);
262 
263     if (!this->m_blocking)
264     {
265         err = clWaitForEvents(1, &event);
266         test_error(err, "clWaitForEvents error");
267     }
268 
269     err = clReleaseEvent(event);
270     test_error(err, "clReleaseEvent error");
271 
272     err = this->verify_mapping_ptr(dataPtr);
273     test_error(err, "clEnqueueMapImage error");
274 
275     err = this->verify_data(dataPtr);
276     test_error(err, "verify_data error");
277 
278     err = clEnqueueUnmapMemObject(this->m_queue, this->m_Image, dataPtr, 0,
279                                   NULL, &event);
280     test_error(err, "clEnqueueUnmapMemObject error");
281 
282     err = clWaitForEvents(1, &event);
283     test_error(err, "clWaitForEvents error");
284 
285     err = clReleaseEvent(event);
286     test_error(err, "clReleaseEvent error");
287 
288     dataPtr = (T *)clEnqueueMapImage(
289         this->m_queue, this->m_Image, this->m_blocking, CL_MAP_WRITE,
290         this->buffer_origin, this->region, &(this->buffer_row_pitch_bytes),
291         &(this->buffer_slice_pitch_bytes), 0, NULL, &event, &err);
292 
293     if (err == CL_SUCCESS)
294     {
295         log_error("Calling clEnqueueMapImage (CL_MAP_WRITE) on a memory object "
296                   "created with the CL_MEM_HOST_READ_ONLY flag should not "
297                   "return CL_SUCCESS\n");
298         err = FAILURE;
299         return FAILURE;
300     }
301     else
302     {
303         log_info("Test succeeded\n\n");
304         err = CL_SUCCESS;
305     }
306 
307     return err;
308 }
309 
310 #endif
311