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_check_mem_host_read_only_h
17 #define test_conformance_check_mem_host_read_only_h
18
19 #include "checker.h"
20
21 template <class T>
22 class cBuffer_check_mem_host_read_only : public cBuffer_checker<T> {
23 public:
cBuffer_check_mem_host_read_only(cl_device_id deviceID,cl_context context,cl_command_queue queue)24 cBuffer_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
~cBuffer_check_mem_host_read_only()28 ~cBuffer_check_mem_host_read_only(){};
29
30 virtual cl_int Check_GetMemObjectInfo(cl_mem_flags buffer_mem_flag);
31 virtual cl_int SetupBuffer();
32 virtual cl_int SetupASSubBuffer(cl_mem_flags flag_p);
33 virtual cl_int Setup_Test_Environment();
34
35 cl_int verifyData(cl_int err, cl_event &event);
36 cl_int verify_RW_Buffer();
37 cl_int verify_RW_Buffer_rect();
38 cl_int verify_RW_Buffer_mapping();
39 };
40
SetupBuffer()41 template <class T> cl_int cBuffer_check_mem_host_read_only<T>::SetupBuffer()
42 {
43 this->m_buffer_type = _BUFFER;
44
45 this->m_nNumber_elements = 888;
46 T vv1 = TEST_VALUE;
47 this->host_m_1.Init(this->m_nNumber_elements, vv1);
48 this->host_m_0.Init(this->m_nNumber_elements, vv1);
49
50 cl_int err = CL_SUCCESS;
51 int block_size_in_byte = (int)(this->m_nNumber_elements * sizeof(T));
52 this->m_buffer =
53 clCreateBuffer(this->m_context, this->buffer_mem_flag,
54 block_size_in_byte, this->host_m_1.pData, &err);
55 test_error(err, "clCreateBuffer error");
56
57 if (this->buffer_mem_flag & CL_MEM_USE_HOST_PTR)
58 {
59 this->pHost_ptr = (void *)this->host_m_1.pData;
60 }
61
62 return err;
63 }
64
65 template <class T>
66 cl_int
SetupASSubBuffer(cl_mem_flags flag_p)67 cBuffer_check_mem_host_read_only<T>::SetupASSubBuffer(cl_mem_flags flag_p)
68 {
69 return cBuffer_checker<T>::SetupASSubBuffer(flag_p);
70 }
71
72 template <class T>
Setup_Test_Environment()73 cl_int cBuffer_check_mem_host_read_only<T>::Setup_Test_Environment()
74 {
75 cBuffer_checker<T>::Setup_Test_Environment();
76 T vv2 = 0;
77 this->host_m_2.Init(this->m_nNumber_elements, vv2);
78
79 return CL_SUCCESS;
80 }
81
82 template <class T>
Check_GetMemObjectInfo(cl_mem_flags buffer_mem_flag)83 cl_int cBuffer_check_mem_host_read_only<T>::Check_GetMemObjectInfo(
84 cl_mem_flags buffer_mem_flag)
85 {
86 cl_int err = CL_SUCCESS;
87 cBuffer_checker<T>::Check_GetMemObjectInfo(buffer_mem_flag);
88
89 if (buffer_mem_flag & CL_MEM_ALLOC_HOST_PTR)
90 {
91 size_t size = 0;
92 err = clGetMemObjectInfo(this->m_buffer, CL_MEM_SIZE, sizeof(size),
93 &size, NULL);
94 void *pp = NULL;
95 err = clGetMemObjectInfo(this->m_buffer, CL_MEM_HOST_PTR, sizeof(pp),
96 &pp, NULL);
97
98 if (!this->host_m_1.Equal((T *)(this->pData), this->m_nNumber_elements))
99 {
100 log_error("Buffer data difference found\n");
101 return FAILURE;
102 }
103 }
104
105 return err;
106 }
107
108 template <class T>
verifyData(cl_int err,cl_event & event)109 cl_int cBuffer_check_mem_host_read_only<T>::verifyData(cl_int err,
110 cl_event &event)
111 {
112 if (err != CL_SUCCESS)
113 {
114 err = this->m_nERROR_RETURN_CODE;
115 test_error(err, "clEnqueueReadBuffer error");
116 }
117
118 if (!this->host_m_1.Equal(this->host_m_2))
119 {
120 err = this->m_nERROR_RETURN_CODE;
121 test_error(err, "clEnqueueReadBuffer data difference found");
122 }
123
124 return err;
125 }
126
127 template <class T>
verify_RW_Buffer()128 cl_int cBuffer_check_mem_host_read_only<T>::verify_RW_Buffer()
129 {
130 cl_event event;
131 cl_int err = CL_SUCCESS;
132
133 err = clEnqueueReadBuffer(this->m_queue, this->m_buffer, this->m_blocking,
134 0, this->get_block_size_bytes(),
135 this->host_m_2.pData, 0, NULL, &event);
136 test_error(err, "clEnqueueReadBuffer error");
137
138 if (!this->m_blocking)
139 {
140 err = clWaitForEvents(1, &event);
141 test_error(err, "clWaitForEvents error");
142 }
143
144 if (!this->host_m_1.Equal(this->host_m_2))
145 {
146 log_error("Buffer data difference found\n");
147 return FAILURE;
148 }
149 err = clReleaseEvent(event);
150 test_error(err, "clReleaseEvent error");
151
152 // test write
153 err = clEnqueueWriteBuffer(this->m_queue, this->m_buffer, this->m_blocking,
154 0, this->get_block_size_bytes(),
155 this->host_m_2.pData, 0, NULL, &event);
156
157 if (err == CL_SUCCESS)
158 {
159 log_error(
160 "Calling clEnqueueWriteBuffer on a memory object created with the "
161 "CL_MEM_HOST_READ_ONLY flag should not return CL_SUCCESS\n");
162 err = FAILURE;
163 return FAILURE;
164 }
165 else
166 {
167 log_info("Test succeeded\n\n");
168 err = CL_SUCCESS;
169 }
170
171 return err;
172 }
173
174 template <class T>
verify_RW_Buffer_rect()175 cl_int cBuffer_check_mem_host_read_only<T>::verify_RW_Buffer_rect()
176 {
177 this->Init_rect();
178
179 T vv2 = 0;
180 this->host_m_2.Set_to(vv2);
181 cl_event event;
182 cl_int err = CL_SUCCESS;
183
184 err = clEnqueueReadBufferRect(
185 this->m_queue, this->m_buffer, this->m_blocking,
186 this->buffer_origin_bytes, this->host_origin_bytes, this->region_bytes,
187 this->buffer_row_pitch_bytes, this->buffer_slice_pitch_bytes,
188 this->host_row_pitch_bytes, this->host_slice_pitch_bytes,
189 this->host_m_2.pData, 0, NULL, &event);
190 test_error(err, "clEnqueueReadBufferRect error");
191
192 if (!this->m_blocking)
193 {
194 err = clWaitForEvents(1, &event);
195 test_error(err, "clWaitForEvents error");
196 }
197
198 if (!this->host_m_1.Equal_rect(this->host_m_2, this->host_origin,
199 this->region, this->host_row_pitch,
200 this->host_slice_pitch))
201 {
202 log_error("Buffer data diffeence found\n");
203 return FAILURE;
204 }
205 err = clReleaseEvent(event);
206 test_error(err, "clReleaseEvent error");
207
208 // test blocking write rect
209 err = clEnqueueWriteBufferRect(
210 this->m_queue, this->m_buffer, this->m_blocking,
211 this->buffer_origin_bytes, this->host_origin_bytes, this->region_bytes,
212 this->buffer_row_pitch_bytes, this->buffer_slice_pitch_bytes,
213 this->host_row_pitch_bytes, this->host_slice_pitch_bytes,
214 this->host_m_2.pData, 0, NULL, &event);
215
216 if (err == CL_SUCCESS)
217 {
218 log_error(
219 "Calling clEnqueueWriteBufferRect on a memory object created with "
220 "the CL_MEM_HOST_READ_ONLY flag should not return CL_SUCCESS\n");
221 err = FAILURE;
222 return FAILURE;
223 }
224 else
225 {
226 log_info("Test succeeded\n\n");
227 err = CL_SUCCESS;
228 }
229
230 return err;
231 }
232
233 template <class T>
verify_RW_Buffer_mapping()234 cl_int cBuffer_check_mem_host_read_only<T>::verify_RW_Buffer_mapping()
235 {
236 cl_int err = CL_SUCCESS;
237 cl_event event;
238 void *dataPtr;
239 dataPtr = clEnqueueMapBuffer(
240 this->m_queue, this->m_buffer, this->m_blocking, CL_MAP_READ, 0,
241 this->get_block_size_bytes(), 0, NULL, &event, &err);
242 test_error(err, "clEnqueueMapBuffer error");
243
244 if (!this->m_blocking)
245 {
246 err = clWaitForEvents(1, &event);
247 test_error(err, "clWaitForEvents error");
248 }
249
250 if ((this->buffer_mem_flag & CL_MEM_USE_HOST_PTR)
251 && dataPtr != this->pHost_ptr)
252 {
253 log_error("Mapped host pointer difference found\n");
254 return FAILURE;
255 }
256
257 if (!this->host_m_1.Equal((T *)dataPtr, this->m_nNumber_elements))
258 {
259 log_error("Buffer content difference found\n");
260 return FAILURE;
261 }
262
263 err = clReleaseEvent(event);
264 test_error(err, "clReleaseEvent error");
265
266 err = clEnqueueUnmapMemObject(this->m_queue, this->m_buffer, dataPtr, 0,
267 nullptr, nullptr);
268 test_error(err, "clEnqueueUnmapMemObject error");
269
270 // test blocking map read
271 clEnqueueMapBuffer(this->m_queue, this->m_buffer, this->m_blocking,
272 CL_MAP_WRITE, 0, this->get_block_size_bytes(), 0, NULL,
273 &event, &err);
274
275 if (err == CL_SUCCESS)
276 {
277 log_error("Calling clEnqueueMapBuffer (CL_MAP_WRITE) on a memory "
278 "object created with the CL_MEM_HOST_READ_ONLY flag should "
279 "not return CL_SUCCESS\n");
280 err = FAILURE;
281 return FAILURE;
282 }
283 else
284 {
285 log_info("Test succeeded\n\n");
286 err = CL_SUCCESS;
287 }
288
289 return err;
290 }
291
292 #endif
293