• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2014-2016 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */ /*!
20  * \file
21  * \brief
22  */ /*-------------------------------------------------------------------*/
23 
24 /*!
25  * \file  esextcTextureBufferTextureBufferRange.cpp
26  * \brief Texture Buffer Range Test (Test 3)
27  */ /*-------------------------------------------------------------------*/
28 
29 #include "esextcTextureBufferTextureBufferRange.hpp"
30 #include "gluContextInfo.hpp"
31 #include "gluDefs.hpp"
32 #include "gluStrUtil.hpp"
33 #include "glwEnums.hpp"
34 #include "glwFunctions.hpp"
35 #include "tcuPixelFormat.hpp"
36 #include "tcuTestLog.hpp"
37 #include <vector>
38 
39 namespace glcts
40 {
41 
42 /** Constructor
43  *
44  **/
FormatInfo()45 FormatInfo::FormatInfo()
46 	: m_aligned_size(0)
47 	, m_not_aligned_size(0)
48 	, m_ssbo_value_size(0)
49 	, m_internal_format(GL_NONE)
50 	, m_offset_alignment(0)
51 	, m_n_components(0)
52 	, m_input_type(GL_NONE)
53 	, m_output_type(GL_NONE)
54 	, m_is_image_supported(false)
55 {
56 }
57 
58 /** Constructor
59  *
60  *  @param internalFormat  texture internal format
61  *  @param offsetAlignment value of GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_EXT
62  **/
FormatInfo(glw::GLenum internalFormat,glw::GLuint offsetAlignment)63 FormatInfo::FormatInfo(glw::GLenum internalFormat, glw::GLuint offsetAlignment)
64 	: m_aligned_size(0)
65 	, m_not_aligned_size(0)
66 	, m_ssbo_value_size(0)
67 	, m_internal_format(internalFormat)
68 	, m_offset_alignment(offsetAlignment)
69 	, m_n_components(0)
70 	, m_input_type(GL_NONE)
71 	, m_output_type(GL_NONE)
72 	, m_is_image_supported(false)
73 {
74 	configure();
75 }
76 
77 /** Configure test parameters according to internal format and offsetAlignment
78  */
configure()79 void FormatInfo::configure()
80 {
81 	/* Check internal format */
82 	switch (m_internal_format)
83 	{
84 	case GL_R8:
85 		m_n_components		 = 1;
86 		m_is_image_supported = false;
87 		m_input_type		 = GL_UNSIGNED_BYTE;
88 		m_output_type		 = GL_FLOAT;
89 		m_not_aligned_size   = static_cast<glw::GLuint>(sizeof(glw::GLubyte) * m_n_components);
90 		m_ssbo_value_size	= static_cast<glw::GLuint>(sizeof(glw::GLfloat) * m_n_components);
91 		m_aligned_size		 = countAlignedSize(m_offset_alignment, m_not_aligned_size);
92 		m_image_format_name  = "";
93 		m_image_type_name	= "";
94 		m_sampler_type_name  = "samplerBuffer";
95 		m_output_type_name   = "float";
96 		m_value_selector	 = ".x";
97 		break;
98 
99 	case GL_R16F:
100 		m_n_components		 = 1;
101 		m_is_image_supported = false;
102 		m_input_type		 = GL_HALF_FLOAT;
103 		m_output_type		 = GL_FLOAT;
104 		m_not_aligned_size   = static_cast<glw::GLuint>(sizeof(glw::GLhalf) * m_n_components);
105 		m_ssbo_value_size	= static_cast<glw::GLuint>(sizeof(glw::GLfloat) * m_n_components);
106 		m_aligned_size		 = countAlignedSize(m_offset_alignment, m_not_aligned_size);
107 		m_image_format_name  = "";
108 		m_image_type_name	= "";
109 		m_sampler_type_name  = "samplerBuffer";
110 		m_output_type_name   = "float";
111 		m_value_selector	 = ".x";
112 		break;
113 
114 	case GL_R32F:
115 		m_n_components		 = 1;
116 		m_is_image_supported = true;
117 		m_input_type		 = GL_FLOAT;
118 		m_output_type		 = GL_FLOAT;
119 		m_not_aligned_size   = static_cast<glw::GLuint>(sizeof(glw::GLfloat) * m_n_components);
120 		m_ssbo_value_size	= static_cast<glw::GLuint>(sizeof(glw::GLfloat) * m_n_components);
121 		m_aligned_size		 = countAlignedSize(m_offset_alignment, m_not_aligned_size);
122 		m_image_format_name  = "r32f";
123 		m_image_type_name	= "imageBuffer";
124 		m_sampler_type_name  = "samplerBuffer";
125 		m_output_type_name   = "float";
126 		m_value_selector	 = ".x";
127 		break;
128 
129 	case GL_R8I:
130 		m_n_components		 = 1;
131 		m_is_image_supported = false;
132 		m_input_type		 = GL_BYTE;
133 		m_output_type		 = GL_INT;
134 		m_not_aligned_size   = static_cast<glw::GLuint>(sizeof(glw::GLbyte) * m_n_components);
135 		m_ssbo_value_size	= static_cast<glw::GLuint>(sizeof(glw::GLint) * m_n_components);
136 		m_aligned_size		 = countAlignedSize(m_offset_alignment, m_not_aligned_size);
137 		m_image_format_name  = "";
138 		m_image_type_name	= "";
139 		m_sampler_type_name  = "isamplerBuffer";
140 		m_output_type_name   = "int";
141 		m_value_selector	 = ".x";
142 		break;
143 
144 	case GL_R16I:
145 		m_n_components		 = 1;
146 		m_is_image_supported = false;
147 		m_input_type		 = GL_SHORT;
148 		m_output_type		 = GL_INT;
149 		m_not_aligned_size   = static_cast<glw::GLuint>(sizeof(glw::GLshort) * m_n_components);
150 		m_ssbo_value_size	= static_cast<glw::GLuint>(sizeof(glw::GLint) * m_n_components);
151 		m_aligned_size		 = countAlignedSize(m_offset_alignment, m_not_aligned_size);
152 		m_image_format_name  = "";
153 		m_image_type_name	= "";
154 		m_sampler_type_name  = "isamplerBuffer";
155 		m_output_type_name   = "int";
156 		m_value_selector	 = ".x";
157 		break;
158 
159 	case GL_R32I:
160 		m_n_components		 = 1;
161 		m_is_image_supported = true;
162 		m_input_type		 = GL_INT;
163 		m_output_type		 = GL_INT;
164 		m_not_aligned_size   = static_cast<glw::GLuint>(sizeof(glw::GLint) * m_n_components);
165 		m_ssbo_value_size	= static_cast<glw::GLuint>(sizeof(glw::GLint) * m_n_components);
166 		m_aligned_size		 = countAlignedSize(m_offset_alignment, m_not_aligned_size);
167 		m_image_format_name  = "r32i";
168 		m_image_type_name	= "iimageBuffer";
169 		m_sampler_type_name  = "isamplerBuffer";
170 		m_output_type_name   = "int";
171 		m_value_selector	 = ".x";
172 		break;
173 
174 	case GL_R8UI:
175 		m_n_components		 = 1;
176 		m_is_image_supported = false;
177 		m_input_type		 = GL_UNSIGNED_BYTE;
178 		m_output_type		 = GL_UNSIGNED_INT;
179 		m_not_aligned_size   = static_cast<glw::GLuint>(sizeof(glw::GLubyte) * m_n_components);
180 		m_ssbo_value_size	= static_cast<glw::GLuint>(sizeof(glw::GLuint) * m_n_components);
181 		m_aligned_size		 = countAlignedSize(m_offset_alignment, m_not_aligned_size);
182 		m_image_format_name  = "";
183 		m_image_type_name	= "";
184 		m_sampler_type_name  = "usamplerBuffer";
185 		m_output_type_name   = "uint";
186 		m_value_selector	 = ".x";
187 		break;
188 
189 	case GL_R16UI:
190 		m_n_components		 = 1;
191 		m_is_image_supported = false;
192 		m_input_type		 = GL_UNSIGNED_SHORT;
193 		m_output_type		 = GL_UNSIGNED_INT;
194 		m_not_aligned_size   = static_cast<glw::GLuint>(sizeof(glw::GLushort) * m_n_components);
195 		m_ssbo_value_size	= static_cast<glw::GLuint>(sizeof(glw::GLuint) * m_n_components);
196 		m_aligned_size		 = countAlignedSize(m_offset_alignment, m_not_aligned_size);
197 		m_image_format_name  = "";
198 		m_image_type_name	= "";
199 		m_sampler_type_name  = "usamplerBuffer";
200 		m_output_type_name   = "uint";
201 		m_value_selector	 = ".x";
202 		break;
203 
204 	case GL_R32UI:
205 		m_n_components		 = 1;
206 		m_is_image_supported = true;
207 		m_input_type		 = GL_UNSIGNED_INT;
208 		m_output_type		 = GL_UNSIGNED_INT;
209 		m_not_aligned_size   = static_cast<glw::GLuint>(sizeof(glw::GLuint) * m_n_components);
210 		m_ssbo_value_size	= static_cast<glw::GLuint>(sizeof(glw::GLuint) * m_n_components);
211 		m_aligned_size		 = countAlignedSize(m_offset_alignment, m_not_aligned_size);
212 		m_image_format_name  = "r32ui";
213 		m_image_type_name	= "uimageBuffer";
214 		m_sampler_type_name  = "usamplerBuffer";
215 		m_output_type_name   = "uint";
216 		m_value_selector	 = ".x";
217 		break;
218 
219 	case GL_RG8:
220 		m_n_components		 = 2;
221 		m_is_image_supported = false;
222 		m_input_type		 = GL_UNSIGNED_BYTE;
223 		m_output_type		 = GL_FLOAT;
224 		m_not_aligned_size   = static_cast<glw::GLuint>(sizeof(glw::GLubyte) * m_n_components);
225 		m_ssbo_value_size	= static_cast<glw::GLuint>(sizeof(glw::GLfloat) * m_n_components);
226 		m_aligned_size		 = countAlignedSize(m_offset_alignment, m_not_aligned_size);
227 		m_image_format_name  = "";
228 		m_image_type_name	= "";
229 		m_sampler_type_name  = "samplerBuffer";
230 		m_output_type_name   = "vec2";
231 		m_value_selector	 = ".xy";
232 		break;
233 
234 	case GL_RG16F:
235 		m_n_components		 = 2;
236 		m_is_image_supported = false;
237 		m_input_type		 = GL_HALF_FLOAT;
238 		m_output_type		 = GL_FLOAT;
239 		m_not_aligned_size   = static_cast<glw::GLuint>(sizeof(glw::GLhalf) * m_n_components);
240 		m_ssbo_value_size	= static_cast<glw::GLuint>(sizeof(glw::GLfloat) * m_n_components);
241 		m_aligned_size		 = countAlignedSize(m_offset_alignment, m_not_aligned_size);
242 		m_image_format_name  = "";
243 		m_image_type_name	= "";
244 		m_sampler_type_name  = "samplerBuffer";
245 		m_output_type_name   = "vec2";
246 		m_value_selector	 = ".xy";
247 		break;
248 
249 	case GL_RG32F:
250 		m_n_components		 = 2;
251 		m_is_image_supported = false;
252 		m_input_type		 = GL_FLOAT;
253 		m_output_type		 = GL_FLOAT;
254 		m_not_aligned_size   = static_cast<glw::GLuint>(sizeof(glw::GLfloat) * m_n_components);
255 		m_ssbo_value_size	= static_cast<glw::GLuint>(sizeof(glw::GLfloat) * m_n_components);
256 		m_aligned_size		 = countAlignedSize(m_offset_alignment, m_not_aligned_size);
257 		m_image_format_name  = "";
258 		m_image_type_name	= "";
259 		m_sampler_type_name  = "samplerBuffer";
260 		m_output_type_name   = "vec2";
261 		m_value_selector	 = ".xy";
262 		break;
263 
264 	case GL_RG8I:
265 		m_n_components		 = 2;
266 		m_is_image_supported = false;
267 		m_input_type		 = GL_BYTE;
268 		m_output_type		 = GL_INT;
269 		m_not_aligned_size   = static_cast<glw::GLuint>(sizeof(glw::GLbyte) * m_n_components);
270 		m_ssbo_value_size	= static_cast<glw::GLuint>(sizeof(glw::GLint) * m_n_components);
271 		m_aligned_size		 = countAlignedSize(m_offset_alignment, m_not_aligned_size);
272 		m_image_format_name  = "";
273 		m_image_type_name	= "";
274 		m_sampler_type_name  = "isamplerBuffer";
275 		m_output_type_name   = "ivec2";
276 		m_value_selector	 = ".xy";
277 		break;
278 
279 	case GL_RG16I:
280 		m_n_components		 = 2;
281 		m_is_image_supported = false;
282 		m_input_type		 = GL_SHORT;
283 		m_output_type		 = GL_INT;
284 		m_not_aligned_size   = static_cast<glw::GLuint>(sizeof(glw::GLshort) * m_n_components);
285 		m_ssbo_value_size	= static_cast<glw::GLuint>(sizeof(glw::GLint) * m_n_components);
286 		m_aligned_size		 = countAlignedSize(m_offset_alignment, m_not_aligned_size);
287 		m_image_format_name  = "";
288 		m_image_type_name	= "";
289 		m_sampler_type_name  = "isamplerBuffer";
290 		m_output_type_name   = "ivec2";
291 		m_value_selector	 = ".xy";
292 		break;
293 
294 	case GL_RG32I:
295 		m_n_components		 = 2;
296 		m_is_image_supported = false;
297 		m_input_type		 = GL_INT;
298 		m_output_type		 = GL_INT;
299 		m_not_aligned_size   = static_cast<glw::GLuint>(sizeof(glw::GLint) * m_n_components);
300 		m_ssbo_value_size	= static_cast<glw::GLuint>(sizeof(glw::GLint) * m_n_components);
301 		m_aligned_size		 = countAlignedSize(m_offset_alignment, m_not_aligned_size);
302 		m_image_format_name  = "";
303 		m_image_type_name	= "";
304 		m_sampler_type_name  = "isamplerBuffer";
305 		m_output_type_name   = "ivec2";
306 		m_value_selector	 = ".xy";
307 		break;
308 
309 	case GL_RG8UI:
310 		m_n_components		 = 2;
311 		m_is_image_supported = false;
312 		m_input_type		 = GL_UNSIGNED_BYTE;
313 		m_output_type		 = GL_UNSIGNED_INT;
314 		m_not_aligned_size   = static_cast<glw::GLuint>(sizeof(glw::GLubyte) * m_n_components);
315 		m_ssbo_value_size	= static_cast<glw::GLuint>(sizeof(glw::GLuint) * m_n_components);
316 		m_aligned_size		 = countAlignedSize(m_offset_alignment, m_not_aligned_size);
317 		m_image_format_name  = "";
318 		m_image_type_name	= "";
319 		m_sampler_type_name  = "usamplerBuffer";
320 		m_output_type_name   = "uvec2";
321 		m_value_selector	 = ".xy";
322 		break;
323 
324 	case GL_RG16UI:
325 		m_n_components		 = 2;
326 		m_is_image_supported = false;
327 		m_input_type		 = GL_UNSIGNED_SHORT;
328 		m_output_type		 = GL_UNSIGNED_INT;
329 		m_not_aligned_size   = static_cast<glw::GLuint>(sizeof(glw::GLushort) * m_n_components);
330 		m_ssbo_value_size	= static_cast<glw::GLuint>(sizeof(glw::GLuint) * m_n_components);
331 		m_aligned_size		 = countAlignedSize(m_offset_alignment, m_not_aligned_size);
332 		m_image_format_name  = "";
333 		m_image_type_name	= "";
334 		m_sampler_type_name  = "usamplerBuffer";
335 		m_output_type_name   = "uvec2";
336 		m_value_selector	 = ".xy";
337 		break;
338 
339 	case GL_RG32UI:
340 		m_n_components		 = 2;
341 		m_is_image_supported = false;
342 		m_input_type		 = GL_UNSIGNED_INT;
343 		m_output_type		 = GL_UNSIGNED_INT;
344 		m_not_aligned_size   = static_cast<glw::GLuint>(sizeof(glw::GLuint) * m_n_components);
345 		m_ssbo_value_size	= static_cast<glw::GLuint>(sizeof(glw::GLuint) * m_n_components);
346 		m_aligned_size		 = countAlignedSize(m_offset_alignment, m_not_aligned_size);
347 		m_image_format_name  = "";
348 		m_image_type_name	= "";
349 		m_sampler_type_name  = "usamplerBuffer";
350 		m_output_type_name   = "uvec2";
351 		m_value_selector	 = ".xy";
352 		break;
353 
354 	case GL_RGB32F:
355 		m_n_components		 = 3;
356 		m_is_image_supported = false;
357 		m_input_type		 = GL_FLOAT;
358 		m_output_type		 = GL_FLOAT;
359 		m_not_aligned_size   = static_cast<glw::GLuint>(sizeof(glw::GLfloat) * m_n_components);
360 		m_ssbo_value_size	= static_cast<glw::GLuint>(sizeof(glw::GLfloat) * m_n_components);
361 		m_aligned_size		 = countAlignedSize(m_offset_alignment, m_not_aligned_size);
362 		m_image_format_name  = "";
363 		m_image_type_name	= "";
364 		m_sampler_type_name  = "samplerBuffer";
365 		m_output_type_name   = "vec3";
366 		m_value_selector	 = ".xyz";
367 		break;
368 
369 	case GL_RGB32I:
370 		m_n_components		 = 3;
371 		m_is_image_supported = false;
372 		m_input_type		 = GL_INT;
373 		m_output_type		 = GL_INT;
374 		m_not_aligned_size   = static_cast<glw::GLuint>(sizeof(glw::GLint) * m_n_components);
375 		m_ssbo_value_size	= static_cast<glw::GLuint>(sizeof(glw::GLint) * m_n_components);
376 		m_aligned_size		 = countAlignedSize(m_offset_alignment, m_not_aligned_size);
377 		m_image_format_name  = "";
378 		m_image_type_name	= "";
379 		m_sampler_type_name  = "isamplerBuffer";
380 		m_output_type_name   = "ivec3";
381 		m_value_selector	 = ".xyz";
382 		break;
383 
384 	case GL_RGB32UI:
385 		m_n_components		 = 3;
386 		m_is_image_supported = false;
387 		m_input_type		 = GL_UNSIGNED_INT;
388 		m_output_type		 = GL_UNSIGNED_INT;
389 		m_not_aligned_size   = static_cast<glw::GLuint>(sizeof(glw::GLuint) * m_n_components);
390 		m_ssbo_value_size	= static_cast<glw::GLuint>(sizeof(glw::GLuint) * m_n_components);
391 		m_aligned_size		 = countAlignedSize(m_offset_alignment, m_not_aligned_size);
392 		m_image_format_name  = "";
393 		m_image_type_name	= "";
394 		m_sampler_type_name  = "usamplerBuffer";
395 		m_output_type_name   = "uvec3";
396 		m_value_selector	 = ".xyz";
397 		break;
398 
399 	case GL_RGBA8:
400 		m_n_components		 = 4;
401 		m_is_image_supported = true;
402 		m_input_type		 = GL_UNSIGNED_BYTE;
403 		m_output_type		 = GL_FLOAT;
404 		m_not_aligned_size   = static_cast<glw::GLuint>(sizeof(glw::GLubyte) * m_n_components);
405 		m_ssbo_value_size	= static_cast<glw::GLuint>(sizeof(glw::GLfloat) * m_n_components);
406 		m_aligned_size		 = countAlignedSize(m_offset_alignment, m_not_aligned_size);
407 		m_image_format_name  = "rgba8";
408 		m_image_type_name	= "imageBuffer";
409 		m_sampler_type_name  = "samplerBuffer";
410 		m_output_type_name   = "vec4";
411 		m_value_selector	 = "";
412 		break;
413 
414 	case GL_RGBA16F:
415 		m_n_components		 = 4;
416 		m_is_image_supported = true;
417 		m_input_type		 = GL_HALF_FLOAT;
418 		m_output_type		 = GL_FLOAT;
419 		m_not_aligned_size   = static_cast<glw::GLuint>(sizeof(glw::GLhalf) * m_n_components);
420 		m_ssbo_value_size	= static_cast<glw::GLuint>(sizeof(glw::GLfloat) * m_n_components);
421 		m_aligned_size		 = countAlignedSize(m_offset_alignment, m_not_aligned_size);
422 		m_image_format_name  = "rgba16f";
423 		m_image_type_name	= "imageBuffer";
424 		m_sampler_type_name  = "samplerBuffer";
425 		m_output_type_name   = "vec4";
426 		m_value_selector	 = "";
427 		break;
428 
429 	case GL_RGBA32F:
430 		m_n_components		 = 4;
431 		m_is_image_supported = true;
432 		m_input_type		 = GL_FLOAT;
433 		m_output_type		 = GL_FLOAT;
434 		m_not_aligned_size   = static_cast<glw::GLuint>(sizeof(glw::GLfloat) * m_n_components);
435 		m_ssbo_value_size	= static_cast<glw::GLuint>(sizeof(glw::GLfloat) * m_n_components);
436 		m_aligned_size		 = countAlignedSize(m_offset_alignment, m_not_aligned_size);
437 		m_image_format_name  = "rgba32f";
438 		m_image_type_name	= "imageBuffer";
439 		m_sampler_type_name  = "samplerBuffer";
440 		m_output_type_name   = "vec4";
441 		m_value_selector	 = "";
442 		break;
443 
444 	case GL_RGBA8I:
445 		m_n_components		 = 4;
446 		m_is_image_supported = true;
447 		m_input_type		 = GL_BYTE;
448 		m_output_type		 = GL_INT;
449 		m_not_aligned_size   = static_cast<glw::GLuint>(sizeof(glw::GLbyte) * m_n_components);
450 		m_ssbo_value_size	= static_cast<glw::GLuint>(sizeof(glw::GLint) * m_n_components);
451 		m_aligned_size		 = countAlignedSize(m_offset_alignment, m_not_aligned_size);
452 		m_image_format_name  = "rgba8i";
453 		m_image_type_name	= "iimageBuffer";
454 		m_sampler_type_name  = "isamplerBuffer";
455 		m_output_type_name   = "ivec4";
456 		m_value_selector	 = "";
457 		break;
458 
459 	case GL_RGBA16I:
460 		m_n_components		 = 4;
461 		m_is_image_supported = true;
462 		m_input_type		 = GL_SHORT;
463 		m_output_type		 = GL_INT;
464 		m_not_aligned_size   = static_cast<glw::GLuint>(sizeof(glw::GLshort) * m_n_components);
465 		m_ssbo_value_size	= static_cast<glw::GLuint>(sizeof(glw::GLint) * m_n_components);
466 		m_aligned_size		 = countAlignedSize(m_offset_alignment, m_not_aligned_size);
467 		m_image_format_name  = "rgba16i";
468 		m_image_type_name	= "iimageBuffer";
469 		m_sampler_type_name  = "isamplerBuffer";
470 		m_output_type_name   = "ivec4";
471 		m_value_selector	 = "";
472 		break;
473 
474 	case GL_RGBA32I:
475 		m_n_components		 = 4;
476 		m_is_image_supported = true;
477 		m_input_type		 = GL_INT;
478 		m_output_type		 = GL_INT;
479 		m_not_aligned_size   = static_cast<glw::GLuint>(sizeof(glw::GLint) * m_n_components);
480 		m_ssbo_value_size	= static_cast<glw::GLuint>(sizeof(glw::GLint) * m_n_components);
481 		m_aligned_size		 = countAlignedSize(m_offset_alignment, m_not_aligned_size);
482 		m_image_format_name  = "rgba32i";
483 		m_image_type_name	= "iimageBuffer";
484 		m_sampler_type_name  = "isamplerBuffer";
485 		m_output_type_name   = "ivec4";
486 		m_value_selector	 = "";
487 		break;
488 
489 	case GL_RGBA8UI:
490 		m_n_components		 = 4;
491 		m_is_image_supported = true;
492 		m_input_type		 = GL_UNSIGNED_BYTE;
493 		m_output_type		 = GL_UNSIGNED_INT;
494 		m_not_aligned_size   = static_cast<glw::GLuint>(sizeof(glw::GLubyte) * m_n_components);
495 		m_ssbo_value_size	= static_cast<glw::GLuint>(sizeof(glw::GLuint) * m_n_components);
496 		m_aligned_size		 = countAlignedSize(m_offset_alignment, m_not_aligned_size);
497 		m_image_format_name  = "rgba8ui";
498 		m_image_type_name	= "uimageBuffer";
499 		m_sampler_type_name  = "usamplerBuffer";
500 		m_output_type_name   = "uvec4";
501 		m_value_selector	 = "";
502 		break;
503 
504 	case GL_RGBA16UI:
505 		m_n_components		 = 4;
506 		m_is_image_supported = true;
507 		m_input_type		 = GL_UNSIGNED_SHORT;
508 		m_output_type		 = GL_UNSIGNED_INT;
509 		m_not_aligned_size   = static_cast<glw::GLuint>(sizeof(glw::GLushort) * m_n_components);
510 		m_ssbo_value_size	= static_cast<glw::GLuint>(sizeof(glw::GLuint) * m_n_components);
511 		m_aligned_size		 = countAlignedSize(m_offset_alignment, m_not_aligned_size);
512 		m_image_format_name  = "rgba16ui";
513 		m_image_type_name	= "uimageBuffer";
514 		m_sampler_type_name  = "usamplerBuffer";
515 		m_output_type_name   = "uvec4";
516 		m_value_selector	 = "";
517 		break;
518 
519 	case GL_RGBA32UI:
520 		m_n_components		 = 4;
521 		m_is_image_supported = true;
522 		m_input_type		 = GL_UNSIGNED_INT;
523 		m_output_type		 = GL_UNSIGNED_INT;
524 		m_not_aligned_size   = static_cast<glw::GLuint>(sizeof(glw::GLuint) * m_n_components);
525 		m_ssbo_value_size	= static_cast<glw::GLuint>(sizeof(glw::GLuint) * m_n_components);
526 		m_aligned_size		 = countAlignedSize(m_offset_alignment, m_not_aligned_size);
527 		m_image_format_name  = "rgba32ui";
528 		m_image_type_name	= "uimageBuffer";
529 		m_sampler_type_name  = "usamplerBuffer";
530 		m_output_type_name   = "uvec4";
531 		m_value_selector	 = "";
532 		break;
533 
534 	default:
535 		break;
536 	}
537 }
538 
539 /** Computes aligned size
540  *
541  * @param offsetAlignment value of GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_EXT parameter
542  * @param totalSize       total size of input data per texel
543  *
544  * @return                properly aligned size
545  */
countAlignedSize(glw::GLuint offsetAlignment,glw::GLuint totalSize)546 glw::GLuint FormatInfo::countAlignedSize(glw::GLuint offsetAlignment, glw::GLuint totalSize)
547 {
548 	if (totalSize > offsetAlignment)
549 	{
550 		glw::GLuint rest = totalSize % offsetAlignment;
551 		if (0 == rest)
552 		{
553 			return totalSize;
554 		}
555 		return totalSize + offsetAlignment - rest;
556 	}
557 	else
558 	{
559 		return offsetAlignment;
560 	}
561 }
562 
563 /** Constructor
564  *
565  *  @param context     Test context
566  *  @param name        Test case's name
567  *  @param description Test case's description
568  **/
TextureBufferTextureBufferRange(Context & context,const ExtParameters & extParams,const char * name,const char * description)569 TextureBufferTextureBufferRange::TextureBufferTextureBufferRange(Context& context, const ExtParameters& extParams,
570 																 const char* name, const char* description)
571 	: TestCaseBase(context, extParams, name, description)
572 	, m_cs_id(0)
573 	, m_cs_po_id(0)
574 	, m_ssbo_size_id(0)
575 	, m_ssbo_value_id(0)
576 	, m_tbo_id(0)
577 	, m_tbo_tex_id(0)
578 	, m_texture_buffer_offset_alignment(0)
579 	, m_vao_id(0)
580 	, m_vs_id(0)
581 	, m_fs_id(0)
582 	, m_vsfs_po_id(0)
583 	, m_tf_size_buffer_id(0)
584 	, m_tf_value_buffer_id(0)
585 	, m_buffer_total_size(0)
586 {
587 	/* Nothing to be done here */
588 }
589 
590 /** Initializes GLES objects used during the test.
591  *
592  */
initTest(void)593 void TextureBufferTextureBufferRange::initTest(void)
594 {
595 	/* Check if texture buffer extension is supported */
596 	if (!m_is_texture_buffer_supported)
597 	{
598 		throw tcu::NotSupportedError(TEXTURE_BUFFER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
599 	}
600 
601 	/* Get GL entry points */
602 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
603 
604 	gl.getIntegerv(m_glExtTokens.TEXTURE_BUFFER_OFFSET_ALIGNMENT, &m_texture_buffer_offset_alignment);
605 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error getting GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_EXT parameter value!");
606 
607 	/* Create list of textures internal formats */
608 	std::vector<glw::GLenum> formats;
609 
610 	formats.push_back(GL_R8);
611 	formats.push_back(GL_R16F);
612 	formats.push_back(GL_R32F);
613 	formats.push_back(GL_R8I);
614 	formats.push_back(GL_R16I);
615 	formats.push_back(GL_R32I);
616 	formats.push_back(GL_R8UI);
617 	formats.push_back(GL_R16UI);
618 	formats.push_back(GL_R32UI);
619 	formats.push_back(GL_RG8);
620 	formats.push_back(GL_RG16F);
621 	formats.push_back(GL_RG32F);
622 	formats.push_back(GL_RG8I);
623 	formats.push_back(GL_RG16I);
624 	formats.push_back(GL_RG32I);
625 	formats.push_back(GL_RG8UI);
626 	formats.push_back(GL_RG16UI);
627 	formats.push_back(GL_RG32UI);
628 	formats.push_back(GL_RGB32F);
629 	formats.push_back(GL_RGB32I);
630 	formats.push_back(GL_RGB32UI);
631 	formats.push_back(GL_RGBA8);
632 	formats.push_back(GL_RGBA16F);
633 	formats.push_back(GL_RGBA32F);
634 	formats.push_back(GL_RGBA8I);
635 	formats.push_back(GL_RGBA16I);
636 	formats.push_back(GL_RGBA32I);
637 	formats.push_back(GL_RGBA8UI);
638 	formats.push_back(GL_RGBA16UI);
639 	formats.push_back(GL_RGBA32UI);
640 
641 	/* Create configuration for internal formats and add them to the map */
642 	for (glw::GLuint i = 0; i < formats.size(); ++i)
643 	{
644 		m_configurations[formats[i]] = FormatInfo(formats[i], m_texture_buffer_offset_alignment);
645 		m_buffer_total_size += m_configurations[formats[i]].get_aligned_size();
646 	}
647 
648 	std::vector<glw::GLubyte> buffer(m_buffer_total_size);
649 	memset(&buffer[0], 0, m_buffer_total_size);
650 
651 	glw::GLuint offset = 0;
652 	for (std::map<glw::GLenum, FormatInfo>::iterator it = m_configurations.begin(); it != m_configurations.end(); ++it)
653 	{
654 		FormatInfo& info = it->second;
655 		fillInputData(&buffer[0], offset, info);
656 		offset += info.get_aligned_size();
657 	}
658 
659 	/* Set up a vertex array object */
660 	gl.genVertexArrays(1, &m_vao_id);
661 	gl.bindVertexArray(m_vao_id);
662 
663 	/* Create buffer object */
664 	gl.genBuffers(1, &m_tbo_id);
665 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating buffer object!");
666 	gl.bindBuffer(m_glExtTokens.TEXTURE_BUFFER, m_tbo_id);
667 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object !");
668 	gl.bufferData(m_glExtTokens.TEXTURE_BUFFER, m_buffer_total_size, &buffer[0], GL_STATIC_DRAW);
669 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating buffer object's data store!");
670 }
671 
672 /** Returns Compute shader Code
673  *
674  * @return pointer to literal with Compute Shader Code
675  */
getComputeShaderCode(FormatInfo & info) const676 std::string TextureBufferTextureBufferRange::getComputeShaderCode(FormatInfo& info) const
677 {
678 	std::stringstream result;
679 
680 	result << "${VERSION}\n"
681 			  "\n"
682 			  "${TEXTURE_BUFFER_REQUIRE}\n"
683 			  "\n"
684 			  "precision highp float;\n"
685 			  "\n"
686 			  "layout("
687 		   << info.get_image_format_name().c_str() << ", binding = 0) uniform highp readonly "
688 		   << info.get_image_type_name().c_str() << " image_buffer;\n"
689 													"\n"
690 													"layout(binding = 0 ) buffer ComputeSSBOSize\n"
691 													"{\n"
692 													"    int outImageSize;\n"
693 													"} computeSSBOSize;\n"
694 													"layout(binding = 1 ) buffer ComputeSSBOSizeValue\n"
695 													"{\n"
696 													"    "
697 		   << info.get_output_type_name().c_str() << " outValue;\n"
698 													 "} computeSSBOValue;\n"
699 													 "\n"
700 													 "layout (local_size_x = 1 ) in;\n"
701 													 "\n"
702 													 "void main(void)\n"
703 													 "{\n"
704 													 "    computeSSBOValue.outValue    = imageLoad( image_buffer, 0)"
705 		   << info.get_value_selector().c_str() << ";\n"
706 												   "    computeSSBOSize.outImageSize = imageSize( image_buffer );\n"
707 												   "}\n";
708 
709 	return result.str();
710 }
711 
712 /** Returns Fragment shader Code
713  *
714  * @return pointer to literal with Fragment Shader Code
715  */
getFragmentShaderCode(FormatInfo & info) const716 std::string TextureBufferTextureBufferRange::getFragmentShaderCode(FormatInfo& info) const
717 {
718 	DE_UNREF(info);
719 
720 	std::stringstream result;
721 
722 	result << "${VERSION}\n"
723 			  "\n"
724 			  "${TEXTURE_BUFFER_REQUIRE}\n"
725 			  "\n"
726 			  "precision highp float;\n"
727 			  "\n"
728 			  "void main(void)\n"
729 			  "{\n"
730 			  "}\n";
731 
732 	return result.str();
733 }
734 
735 /** Returns Vertex shader Code
736  *
737  * @return pointer to literal with Vertex Shader Code
738  */
getVertexShaderCode(FormatInfo & info) const739 std::string TextureBufferTextureBufferRange::getVertexShaderCode(FormatInfo& info) const
740 {
741 	std::stringstream result;
742 
743 	const char* pszInterpolationQualifier = "";
744 
745 	if (info.get_output_type() == GL_UNSIGNED_INT || info.get_output_type() == GL_INT)
746 	{
747 		pszInterpolationQualifier = "flat ";
748 	}
749 
750 	result << "${VERSION}\n"
751 			  "\n"
752 			  "${TEXTURE_BUFFER_REQUIRE}\n"
753 			  "\n"
754 			  "precision highp float;\n"
755 			  "\n"
756 			  "uniform highp "
757 		   << info.get_sampler_type_name().c_str() << " sampler_buffer;\n"
758 													  "\n"
759 													  "layout(location = 0 ) out flat int outTextureSize;\n"
760 													  "layout(location = 1 ) out "
761 		   << pszInterpolationQualifier << info.get_output_type_name().c_str()
762 		   << " outValue;\n"
763 			  "void main(void)\n"
764 			  "{\n"
765 			  "    outValue       = texelFetch ( sampler_buffer, 0)"
766 		   << info.get_value_selector().c_str() << ";\n"
767 												   "    outTextureSize = textureSize( sampler_buffer );\n"
768 												   "    gl_Position    = vec4(0.0f, 0.0f, 0.0f, 0.0f);\n"
769 												   "}\n";
770 
771 	return result.str();
772 }
773 
774 /** Delete GLES objects created for iteration */
cleanIteration()775 void TextureBufferTextureBufferRange::cleanIteration()
776 {
777 	/* Get GL entry points */
778 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
779 
780 	/* Reset GLES state */
781 	gl.useProgram(0);
782 	gl.bindBuffer(GL_ARRAY_BUFFER, 0);
783 	gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0);
784 	gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, 0);
785 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);
786 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 1, 0);
787 	gl.bindTexture(m_glExtTokens.TEXTURE_BUFFER, 0);
788 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error reseting GLES state after iteration!");
789 
790 	/* Delete GLES objects */
791 	if (0 != m_vsfs_po_id)
792 	{
793 		gl.deleteProgram(m_vsfs_po_id);
794 		m_vsfs_po_id = 0;
795 	}
796 
797 	if (0 != m_vs_id)
798 	{
799 		gl.deleteShader(m_vs_id);
800 		m_vs_id = 0;
801 	}
802 
803 	if (0 != m_fs_id)
804 	{
805 		gl.deleteShader(m_fs_id);
806 		m_fs_id = 0;
807 	}
808 
809 	if (0 != m_tf_size_buffer_id)
810 	{
811 		gl.deleteBuffers(1, &m_tf_size_buffer_id);
812 		m_tf_size_buffer_id = 0;
813 	}
814 
815 	if (0 != m_tf_value_buffer_id)
816 	{
817 		gl.deleteBuffers(1, &m_tf_value_buffer_id);
818 		m_tf_value_buffer_id = 0;
819 	}
820 
821 	if (0 != m_cs_po_id)
822 	{
823 		gl.deleteProgram(m_cs_po_id);
824 		m_cs_po_id = 0;
825 	}
826 
827 	if (0 != m_cs_id)
828 	{
829 		gl.deleteShader(m_cs_id);
830 		m_cs_id = 0;
831 	}
832 
833 	if (0 != m_ssbo_size_id)
834 	{
835 		gl.deleteBuffers(1, &m_ssbo_size_id);
836 		m_ssbo_size_id = 0;
837 	}
838 
839 	if (0 != m_ssbo_value_id)
840 	{
841 		gl.deleteBuffers(1, &m_ssbo_value_id);
842 		m_ssbo_value_id = 0;
843 	}
844 
845 	if (0 != m_tbo_tex_id)
846 	{
847 		gl.deleteTextures(1, &m_tbo_tex_id);
848 		m_tbo_tex_id = 0;
849 	}
850 
851 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error removing iteration resources!");
852 }
853 
854 /** Executes the test.
855  *
856  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
857  *
858  *  Note the function throws exception should an error occur!
859  *
860  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
861  **/
iterate(void)862 tcu::TestNode::IterateResult TextureBufferTextureBufferRange::iterate(void)
863 {
864 	/* Initialize */
865 	initTest();
866 
867 	/* Get GL entry points */
868 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
869 
870 	bool		testResult = true;
871 	glw::GLuint offset	 = 0;
872 
873 	for (std::map<glw::GLenum, FormatInfo>::iterator it = m_configurations.begin(); it != m_configurations.end(); ++it)
874 	{
875 		FormatInfo& info = it->second;
876 
877 		/* Create texture object */
878 		gl.genTextures(1, &m_tbo_tex_id);
879 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating texture object!");
880 		gl.activeTexture(GL_TEXTURE0);
881 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting active texture unit!");
882 		gl.bindTexture(m_glExtTokens.TEXTURE_BUFFER, m_tbo_tex_id);
883 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture buffer object!");
884 		gl.texBufferRange(m_glExtTokens.TEXTURE_BUFFER, info.get_internal_format(), m_tbo_id, offset,
885 						  info.get_not_aligned_size());
886 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting buffer object as data store for texture buffer!");
887 
888 		/* Create transform feedback buffer objects */
889 		gl.genBuffers(1, &m_tf_size_buffer_id);
890 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating buffer object!");
891 		gl.bindBuffer(GL_ARRAY_BUFFER, m_tf_size_buffer_id);
892 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object!");
893 		gl.bufferData(GL_ARRAY_BUFFER, sizeof(glw::GLint), DE_NULL, GL_DYNAMIC_COPY);
894 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating buffer object's data store!");
895 
896 		std::vector<glw::GLubyte> buffer(info.get_ssbo_value_size());
897 		memset(&buffer[0], 0, info.get_ssbo_value_size());
898 
899 		gl.genBuffers(1, &m_tf_value_buffer_id);
900 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating buffer object!");
901 		gl.bindBuffer(GL_ARRAY_BUFFER, m_tf_value_buffer_id);
902 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object!");
903 		gl.bufferData(GL_ARRAY_BUFFER, info.get_ssbo_value_size(), &buffer[0], GL_DYNAMIC_COPY);
904 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating buffer object's data store!");
905 
906 		/* Configure program object using Vertex Shader and Fragment Shader */
907 		m_vsfs_po_id = gl.createProgram();
908 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating program object!");
909 
910 		const char* varyings[] = { "outTextureSize", "outValue" };
911 
912 		gl.transformFeedbackVaryings(m_vsfs_po_id, 2, varyings, GL_SEPARATE_ATTRIBS);
913 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting transform feedback varyings!");
914 
915 		m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
916 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating shader object!");
917 
918 		m_vs_id = gl.createShader(GL_VERTEX_SHADER);
919 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating shader object!");
920 
921 		std::string fsSource = getFragmentShaderCode(info);
922 		std::string vsSource = getVertexShaderCode(info);
923 		const char* fsCode   = fsSource.c_str();
924 		const char* vsCode   = vsSource.c_str();
925 
926 		if (!buildProgram(m_vsfs_po_id, m_fs_id, 1, &fsCode, m_vs_id, 1, &vsCode))
927 		{
928 			TCU_FAIL("Could not build program from valid vertex/fragment shader code!");
929 		}
930 
931 		gl.useProgram(m_vsfs_po_id);
932 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting active program object!");
933 
934 		glw::GLint sampler_location = gl.getUniformLocation(m_vsfs_po_id, "sampler_buffer");
935 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error getting uniform location!");
936 		if (sampler_location == -1)
937 		{
938 			TCU_FAIL("Failed to get uniform location for valid uniform variable");
939 		}
940 
941 		gl.uniform1i(sampler_location, 0);
942 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting value for uniform location!");
943 
944 		/* Configure transform feedback */
945 		gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_tf_size_buffer_id);
946 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object to transform feedback binding point.");
947 		gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 1, m_tf_value_buffer_id);
948 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object to transform feedback binding point.");
949 
950 		gl.beginTransformFeedback(GL_POINTS);
951 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error beginning transform feedback.");
952 
953 		/* Render */
954 		gl.drawArrays(GL_POINTS, 0, 1);
955 		glw::GLenum glerr = gl.getError();
956 
957 		gl.endTransformFeedback();
958 		GLU_EXPECT_NO_ERROR(glerr, "Error drawing arrays");
959 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error ending transform feedback.");
960 
961 		gl.memoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
962 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting memory barrier.");
963 
964 		/* Check results */
965 		if (!checkResult(info, "Vertex/Fragment shader", true))
966 		{
967 			testResult = false;
968 		}
969 
970 		/* Run compute shader if internal format is supported by image_load_store */
971 		if (info.get_is_image_supported())
972 		{
973 			/* Create Shader Storage Buffer Object */
974 			gl.genBuffers(1, &m_ssbo_size_id);
975 			GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating buffer object!");
976 			gl.bindBuffer(GL_ARRAY_BUFFER, m_ssbo_size_id);
977 			GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding  buffer object!");
978 			gl.bufferData(GL_ARRAY_BUFFER, sizeof(glw::GLint), 0, GL_DYNAMIC_COPY);
979 			GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating buffer object's data store!");
980 
981 			gl.genBuffers(1, &m_ssbo_value_id);
982 			GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating buffer object!");
983 			gl.bindBuffer(GL_ARRAY_BUFFER, m_ssbo_value_id);
984 			GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding  buffer object!");
985 			gl.bufferData(GL_ARRAY_BUFFER, info.get_ssbo_value_size(), &buffer[0], GL_DYNAMIC_COPY);
986 			GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating buffer object's data store!");
987 
988 			/* Create compute shader program */
989 			m_cs_po_id = gl.createProgram();
990 			GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating program object!");
991 
992 			m_cs_id = gl.createShader(GL_COMPUTE_SHADER);
993 			GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating shader object!");
994 
995 			std::string csSource = getComputeShaderCode(info);
996 			const char* csCode   = csSource.c_str();
997 
998 			if (!buildProgram(m_cs_po_id, m_cs_id, 1, &csCode))
999 			{
1000 				TCU_FAIL("Could not build program from valid compute shader code!");
1001 			}
1002 
1003 			gl.useProgram(m_cs_po_id);
1004 			GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting active program object!");
1005 
1006 			/* Configure SSBO objects */
1007 			gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_ssbo_size_id);
1008 			GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object to shader storage binding point!");
1009 			gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_ssbo_value_id);
1010 			GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object to shader storage binding point!");
1011 
1012 			/* Bind texture to image unit*/
1013 			gl.bindImageTexture(0, m_tbo_tex_id, 0, GL_FALSE, 0, GL_READ_ONLY, info.get_internal_format());
1014 			GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object to image unit 0!");
1015 
1016 			/* Run compute shader */
1017 			gl.dispatchCompute(1, 1, 1);
1018 			GLU_EXPECT_NO_ERROR(gl.getError(), "Error running compute shader!");
1019 
1020 			gl.memoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
1021 			GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting memory barrier!");
1022 
1023 			if (!checkResult(info, "Compute shader", false))
1024 			{
1025 				testResult = false;
1026 			}
1027 		}
1028 
1029 		offset += info.get_aligned_size();
1030 		cleanIteration();
1031 	}
1032 
1033 	if (testResult)
1034 	{
1035 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1036 	}
1037 	else
1038 	{
1039 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1040 	}
1041 
1042 	return STOP;
1043 }
1044 
1045 /** Check test results
1046  *
1047  *   @param info              test configuration
1048  *   @param phase             name of test phase
1049  *   @param transformFeedback contains information if verification method should use transformfeedback, otherwise it uses SSBO
1050  *
1051  *   @return                  return true if result values are es expected, otherwise return false
1052  */
checkResult(FormatInfo & info,const char * phase,bool transformFeedback)1053 bool TextureBufferTextureBufferRange::checkResult(FormatInfo& info, const char* phase, bool transformFeedback)
1054 {
1055 	/* Get GL entry points */
1056 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1057 
1058 	glw::GLenum bufferTarget  = GL_NONE;
1059 	glw::GLuint bufferSizeId  = GL_NONE;
1060 	glw::GLuint bufferValueId = GL_NONE;
1061 
1062 	if (transformFeedback)
1063 	{
1064 		bufferTarget  = GL_TRANSFORM_FEEDBACK_BUFFER;
1065 		bufferSizeId  = m_tf_size_buffer_id;
1066 		bufferValueId = m_tf_value_buffer_id;
1067 	}
1068 	else
1069 	{
1070 		bufferTarget  = GL_SHADER_STORAGE_BUFFER;
1071 		bufferSizeId  = m_ssbo_size_id;
1072 		bufferValueId = m_ssbo_value_id;
1073 	}
1074 
1075 	bool testResult = true;
1076 
1077 	/* Get result data */
1078 	gl.bindBuffer(bufferTarget, bufferSizeId);
1079 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer!");
1080 
1081 	glw::GLint* size = (glw::GLint*)gl.mapBufferRange(bufferTarget, 0, sizeof(glw::GLint), GL_MAP_READ_BIT);
1082 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error mapping buffer!");
1083 
1084 	const glw::GLint expectedSize = 1;
1085 
1086 	/* Reagrding test specification size should be equal 1*/
1087 	/* Log error if expected and result data are not equal */
1088 	if (*size != expectedSize)
1089 	{
1090 		m_testCtx.getLog() << tcu::TestLog::Message << "Texture size is wrong for " << phase << " phase \n"
1091 						   << "Internal Format: " << glu::getUncompressedTextureFormatName(info.get_internal_format())
1092 						   << "\n"
1093 						   << "Expected size:   " << expectedSize << "\n"
1094 						   << "Result size:     " << size << "\n"
1095 						   << tcu::TestLog::EndMessage;
1096 	}
1097 
1098 	gl.unmapBuffer(bufferTarget);
1099 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error unmapping buffer!");
1100 
1101 	gl.bindBuffer(bufferTarget, bufferValueId);
1102 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer!");
1103 
1104 	std::stringstream expVal;
1105 	std::stringstream resVal;
1106 
1107 	/* Log error if expected and result data are not equal */
1108 	switch (info.get_output_type())
1109 	{
1110 	case GL_FLOAT:
1111 	{
1112 		glw::GLfloat* res =
1113 			(glw::GLfloat*)gl.mapBufferRange(bufferTarget, 0, info.get_ssbo_value_size(), GL_MAP_READ_BIT);
1114 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error mapping buffer!");
1115 
1116 		std::vector<glw::GLfloat> expected(info.get_n_components());
1117 
1118 		fillOutputData(reinterpret_cast<glw::GLubyte*>(&expected[0]), info);
1119 
1120 		for (glw::GLuint i = 0; i < info.get_n_components(); ++i)
1121 		{
1122 			if (de::abs(res[i] - expected[i]) > m_epsilon_float)
1123 			{
1124 				expVal.str("");
1125 				resVal.str("");
1126 				expVal << expected[i];
1127 				resVal << res[i];
1128 
1129 				logError(phase, glu::getUncompressedTextureFormatName(info.get_internal_format()), i,
1130 						 expVal.str().c_str(), resVal.str().c_str());
1131 
1132 				testResult = false;
1133 			}
1134 		}
1135 	}
1136 	break;
1137 
1138 	case GL_INT:
1139 	{
1140 		glw::GLint* res = (glw::GLint*)gl.mapBufferRange(bufferTarget, 0, info.get_ssbo_value_size(), GL_MAP_READ_BIT);
1141 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error mapping buffer!");
1142 
1143 		std::vector<glw::GLint> expected(info.get_n_components());
1144 
1145 		fillOutputData(reinterpret_cast<glw::GLubyte*>(&expected[0]), info);
1146 
1147 		for (glw::GLuint i = 0; i < info.get_n_components(); ++i)
1148 		{
1149 			if (res[i] != expected[i])
1150 			{
1151 				expVal.str("");
1152 				resVal.str("");
1153 				expVal << expected[i];
1154 				resVal << res[i];
1155 
1156 				logError(phase, glu::getUncompressedTextureFormatName(info.get_internal_format()), i,
1157 						 expVal.str().c_str(), resVal.str().c_str());
1158 
1159 				testResult = false;
1160 			}
1161 		}
1162 	}
1163 	break;
1164 
1165 	case GL_UNSIGNED_INT:
1166 	{
1167 		glw::GLuint* res =
1168 			(glw::GLuint*)gl.mapBufferRange(bufferTarget, 0, info.get_ssbo_value_size(), GL_MAP_READ_BIT);
1169 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error mapping buffer!");
1170 
1171 		std::vector<glw::GLuint> expected(info.get_n_components());
1172 
1173 		fillOutputData(reinterpret_cast<glw::GLubyte*>(&expected[0]), info);
1174 
1175 		for (glw::GLuint i = 0; i < info.get_n_components(); ++i)
1176 		{
1177 			if (res[i] != expected[i])
1178 			{
1179 				expVal.str("");
1180 				resVal.str("");
1181 				expVal << expected[i];
1182 				resVal << res[i];
1183 
1184 				logError(phase, glu::getUncompressedTextureFormatName(info.get_internal_format()), i,
1185 						 expVal.str().c_str(), resVal.str().c_str());
1186 
1187 				testResult = false;
1188 			}
1189 		}
1190 	}
1191 	break;
1192 
1193 	default:
1194 	{
1195 		gl.unmapBuffer(bufferTarget);
1196 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error ummapping buffer!");
1197 
1198 		TCU_FAIL("Not allowed output type");
1199 	}
1200 	}
1201 
1202 	gl.unmapBuffer(bufferTarget);
1203 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error ummapping buffer!");
1204 
1205 	return testResult;
1206 }
1207 
1208 /** Create error message and log it
1209  *
1210  * @param phase          name of phase
1211  * @param internalFormat name of internal format
1212  * @param component      component position
1213  * @param exptectedValue string with expected value
1214  * @param resultValue    string with result   value
1215  *
1216  */
logError(const char * phase,const char * internalFormat,glw::GLuint component,const char * exptectedValue,const char * resultValue)1217 void TextureBufferTextureBufferRange::logError(const char* phase, const char* internalFormat, glw::GLuint component,
1218 											   const char* exptectedValue, const char* resultValue)
1219 {
1220 	m_testCtx.getLog() << tcu::TestLog::Message << "Result is different for " << phase << " phase \n"
1221 					   << "Internal Format: " << internalFormat << "\n"
1222 					   << "Component Position: " << component << "\n"
1223 					   << "Expected value: " << exptectedValue << "\n"
1224 					   << "Result value: " << resultValue << "\n"
1225 					   << tcu::TestLog::EndMessage;
1226 }
1227 
1228 /** Deinitializes GLES objects created during the test.
1229  *
1230  */
deinit(void)1231 void TextureBufferTextureBufferRange::deinit(void)
1232 {
1233 	/* Call base class' deinit() */
1234 	TestCaseBase::deinit();
1235 
1236 	/* Check if texture buffer extension is supported */
1237 	if (!m_is_texture_buffer_supported)
1238 	{
1239 		return;
1240 	}
1241 
1242 	/* Get GL entry points */
1243 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1244 
1245 	/* Reset GLES state */
1246 	gl.bindBuffer(m_glExtTokens.TEXTURE_BUFFER, 0);
1247 	gl.bindVertexArray(0);
1248 
1249 	/* Delete GLES objects */
1250 	if (0 != m_tbo_id)
1251 	{
1252 		gl.deleteBuffers(1, &m_tbo_id);
1253 		m_tbo_id = 0;
1254 	}
1255 
1256 	if (0 != m_vao_id)
1257 	{
1258 		gl.deleteVertexArrays(1, &m_vao_id);
1259 	}
1260 
1261 	cleanIteration();
1262 }
1263 
1264 /** Fill buffer with input data for texture buffer
1265  *
1266  * @param buffer buffer where data will be stored
1267  * @param offset offset into buffer
1268  * @param info   test configuration
1269  *
1270  */
fillInputData(glw::GLubyte * buffer,glw::GLuint offset,FormatInfo & info)1271 void TextureBufferTextureBufferRange::fillInputData(glw::GLubyte* buffer, glw::GLuint offset, FormatInfo& info)
1272 {
1273 	/* Initial value should give value equal to 1 on output */
1274 
1275 	/* Check input data type */
1276 	switch (info.get_input_type())
1277 	{
1278 	case GL_FLOAT:
1279 	{
1280 		glw::GLfloat* pointer = reinterpret_cast<glw::GLfloat*>(&buffer[offset]);
1281 		for (glw::GLuint i = 0; i < info.get_n_components(); ++i)
1282 		{
1283 			*pointer++ = 1.0f;
1284 		}
1285 	}
1286 	break;
1287 
1288 	case GL_HALF_FLOAT:
1289 	{
1290 		glw::GLhalf* pointer = reinterpret_cast<glw::GLhalf*>(&buffer[offset]);
1291 
1292 		glw::GLfloat val = 1.0f;
1293 
1294 		/* Convert float to half float */
1295 		glw::GLuint	temp32   = 0;
1296 		glw::GLuint	temp32_2 = 0;
1297 		unsigned short temp16   = 0;
1298 		unsigned short temp16_2 = 0;
1299 
1300 		memcpy(&temp32, &val, sizeof(glw::GLfloat));
1301 		temp32_2 = temp32 >> 31;
1302 		temp16   = (unsigned short)((temp32_2 >> 31) << 5);
1303 		temp32_2 = temp32 >> 23;
1304 		temp16_2 = temp32_2 & 0xff;
1305 		temp16_2 = (unsigned short)((temp16_2 - 0x70) & ((glw::GLuint)((glw::GLint)(0x70 - temp16_2) >> 4) >> 27));
1306 		temp16   = (unsigned short)((temp16 | temp16_2) << 10);
1307 		temp32_2 = temp32 >> 13;
1308 		temp16   = (unsigned short)(temp16 | (temp32_2 & 0x3ff));
1309 
1310 		for (glw::GLuint i = 0; i < info.get_n_components(); ++i)
1311 		{
1312 			*pointer++ = temp16;
1313 		}
1314 	}
1315 	break;
1316 
1317 	case GL_UNSIGNED_BYTE:
1318 	{
1319 		glw::GLubyte* pointer = reinterpret_cast<glw::GLubyte*>(&buffer[offset]);
1320 		glw::GLubyte  val	 = 0;
1321 
1322 		/* Normalized Values */
1323 		if (info.get_internal_format() == GL_R8 || info.get_internal_format() == GL_RG8 ||
1324 			info.get_internal_format() == GL_RGBA8)
1325 		{
1326 			val = 255;
1327 		}
1328 		else
1329 		{
1330 			val = 1;
1331 		}
1332 		for (glw::GLuint i = 0; i < info.get_n_components(); ++i)
1333 		{
1334 			*pointer++ = val;
1335 		}
1336 	}
1337 	break;
1338 
1339 	case GL_UNSIGNED_SHORT:
1340 	{
1341 		glw::GLushort* pointer = reinterpret_cast<glw::GLushort*>(&buffer[offset]);
1342 
1343 		for (glw::GLuint i = 0; i < info.get_n_components(); ++i)
1344 		{
1345 			*pointer++ = (glw::GLushort)1;
1346 		}
1347 	}
1348 	break;
1349 	case GL_UNSIGNED_INT:
1350 	{
1351 		glw::GLuint* pointer = reinterpret_cast<glw::GLuint*>(&buffer[offset]);
1352 
1353 		for (glw::GLuint i = 0; i < info.get_n_components(); ++i)
1354 		{
1355 			*pointer++ = 1;
1356 		}
1357 	}
1358 	break;
1359 	case GL_INT:
1360 	{
1361 		glw::GLint* pointer = reinterpret_cast<glw::GLint*>(&buffer[offset]);
1362 		for (glw::GLuint i = 0; i < info.get_n_components(); ++i)
1363 		{
1364 			*pointer++ = 1;
1365 		}
1366 	}
1367 	break;
1368 	case GL_SHORT:
1369 	{
1370 		glw::GLshort* pointer = reinterpret_cast<glw::GLshort*>(&buffer[offset]);
1371 		for (glw::GLuint i = 0; i < info.get_n_components(); ++i)
1372 		{
1373 			*pointer++ = (glw::GLshort)1;
1374 		}
1375 	}
1376 	break;
1377 	case GL_BYTE:
1378 	{
1379 		glw::GLbyte* pointer = reinterpret_cast<glw::GLbyte*>(&buffer[offset]);
1380 		for (glw::GLuint i = 0; i < info.get_n_components(); ++i)
1381 		{
1382 			*pointer++ = (glw::GLbyte)1;
1383 		}
1384 	}
1385 	break;
1386 	default:
1387 		TCU_FAIL("Not allowed input type");
1388 	}
1389 }
1390 
1391 /** Fill buffer with output data for texture buffer
1392  *
1393  * @param buffer buffer where data will be stored
1394  * @param info   test configuration
1395  *
1396  */
fillOutputData(glw::GLubyte * buffer,FormatInfo & info)1397 void TextureBufferTextureBufferRange::fillOutputData(glw::GLubyte* buffer, FormatInfo& info)
1398 {
1399 	switch (info.get_output_type())
1400 	{
1401 	case GL_FLOAT:
1402 	{
1403 		glw::GLfloat* pointer = reinterpret_cast<glw::GLfloat*>(&buffer[0]);
1404 		for (unsigned int i = 0; i < info.get_n_components(); ++i)
1405 		{
1406 			*pointer++ = 1.0f;
1407 		}
1408 	}
1409 	break;
1410 
1411 	case GL_INT:
1412 	{
1413 		glw::GLint* pointer = reinterpret_cast<glw::GLint*>(&buffer[0]);
1414 		for (unsigned int i = 0; i < info.get_n_components(); ++i)
1415 		{
1416 			*pointer++ = 1;
1417 		}
1418 	}
1419 	break;
1420 
1421 	case GL_UNSIGNED_INT:
1422 	{
1423 		glw::GLuint* pointer = reinterpret_cast<glw::GLuint*>(&buffer[0]);
1424 		for (unsigned int i = 0; i < info.get_n_components(); ++i)
1425 		{
1426 			*pointer++ = 1;
1427 		}
1428 	}
1429 	break;
1430 
1431 	default:
1432 		TCU_FAIL("Not allowed output type");
1433 	}
1434 }
1435 
1436 } // namespace glcts
1437