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()
689            << " image_buffer;\n"
690               "\n"
691               "layout(binding = 0 ) buffer ComputeSSBOSize\n"
692               "{\n"
693               "    int outImageSize;\n"
694               "} computeSSBOSize;\n"
695               "layout(binding = 1 ) buffer ComputeSSBOSizeValue\n"
696               "{\n"
697               "    "
698            << info.get_output_type_name().c_str()
699            << " outValue;\n"
700               "} computeSSBOValue;\n"
701               "\n"
702               "layout (local_size_x = 1 ) in;\n"
703               "\n"
704               "void main(void)\n"
705               "{\n"
706               "    computeSSBOValue.outValue    = imageLoad( image_buffer, 0)"
707            << info.get_value_selector().c_str()
708            << ";\n"
709               "    computeSSBOSize.outImageSize = imageSize( image_buffer );\n"
710               "}\n";
711 
712     return result.str();
713 }
714 
715 /** Returns Fragment shader Code
716  *
717  * @return pointer to literal with Fragment Shader Code
718  */
getFragmentShaderCode(FormatInfo & info) const719 std::string TextureBufferTextureBufferRange::getFragmentShaderCode(FormatInfo &info) const
720 {
721     DE_UNREF(info);
722 
723     std::stringstream result;
724 
725     result << "${VERSION}\n"
726               "\n"
727               "${TEXTURE_BUFFER_REQUIRE}\n"
728               "\n"
729               "precision highp float;\n"
730               "\n"
731               "void main(void)\n"
732               "{\n"
733               "}\n";
734 
735     return result.str();
736 }
737 
738 /** Returns Vertex shader Code
739  *
740  * @return pointer to literal with Vertex Shader Code
741  */
getVertexShaderCode(FormatInfo & info) const742 std::string TextureBufferTextureBufferRange::getVertexShaderCode(FormatInfo &info) const
743 {
744     std::stringstream result;
745 
746     const char *pszInterpolationQualifier = "";
747 
748     if (info.get_output_type() == GL_UNSIGNED_INT || info.get_output_type() == GL_INT)
749     {
750         pszInterpolationQualifier = "flat ";
751     }
752 
753     result << "${VERSION}\n"
754               "\n"
755               "${TEXTURE_BUFFER_REQUIRE}\n"
756               "\n"
757               "precision highp float;\n"
758               "\n"
759               "uniform highp "
760            << info.get_sampler_type_name().c_str()
761            << " sampler_buffer;\n"
762               "\n"
763               "layout(location = 0 ) out flat int outTextureSize;\n"
764               "layout(location = 1 ) out "
765            << pszInterpolationQualifier << info.get_output_type_name().c_str()
766            << " outValue;\n"
767               "void main(void)\n"
768               "{\n"
769               "    outValue       = texelFetch ( sampler_buffer, 0)"
770            << info.get_value_selector().c_str()
771            << ";\n"
772               "    outTextureSize = textureSize( sampler_buffer );\n"
773               "    gl_Position    = vec4(0.0f, 0.0f, 0.0f, 0.0f);\n"
774               "}\n";
775 
776     return result.str();
777 }
778 
779 /** Delete GLES objects created for iteration */
cleanIteration()780 void TextureBufferTextureBufferRange::cleanIteration()
781 {
782     /* Get GL entry points */
783     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
784 
785     /* Reset GLES state */
786     gl.useProgram(0);
787     gl.bindBuffer(GL_ARRAY_BUFFER, 0);
788     gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0);
789     gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, 0);
790     gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);
791     gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 1, 0);
792     gl.bindTexture(m_glExtTokens.TEXTURE_BUFFER, 0);
793     GLU_EXPECT_NO_ERROR(gl.getError(), "Error reseting GLES state after iteration!");
794 
795     /* Delete GLES objects */
796     if (0 != m_vsfs_po_id)
797     {
798         gl.deleteProgram(m_vsfs_po_id);
799         m_vsfs_po_id = 0;
800     }
801 
802     if (0 != m_vs_id)
803     {
804         gl.deleteShader(m_vs_id);
805         m_vs_id = 0;
806     }
807 
808     if (0 != m_fs_id)
809     {
810         gl.deleteShader(m_fs_id);
811         m_fs_id = 0;
812     }
813 
814     if (0 != m_tf_size_buffer_id)
815     {
816         gl.deleteBuffers(1, &m_tf_size_buffer_id);
817         m_tf_size_buffer_id = 0;
818     }
819 
820     if (0 != m_tf_value_buffer_id)
821     {
822         gl.deleteBuffers(1, &m_tf_value_buffer_id);
823         m_tf_value_buffer_id = 0;
824     }
825 
826     if (0 != m_cs_po_id)
827     {
828         gl.deleteProgram(m_cs_po_id);
829         m_cs_po_id = 0;
830     }
831 
832     if (0 != m_cs_id)
833     {
834         gl.deleteShader(m_cs_id);
835         m_cs_id = 0;
836     }
837 
838     if (0 != m_ssbo_size_id)
839     {
840         gl.deleteBuffers(1, &m_ssbo_size_id);
841         m_ssbo_size_id = 0;
842     }
843 
844     if (0 != m_ssbo_value_id)
845     {
846         gl.deleteBuffers(1, &m_ssbo_value_id);
847         m_ssbo_value_id = 0;
848     }
849 
850     if (0 != m_tbo_tex_id)
851     {
852         gl.deleteTextures(1, &m_tbo_tex_id);
853         m_tbo_tex_id = 0;
854     }
855 
856     GLU_EXPECT_NO_ERROR(gl.getError(), "Error removing iteration resources!");
857 }
858 
859 /** Executes the test.
860  *
861  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
862  *
863  *  Note the function throws exception should an error occur!
864  *
865  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
866  **/
iterate(void)867 tcu::TestNode::IterateResult TextureBufferTextureBufferRange::iterate(void)
868 {
869     /* Initialize */
870     initTest();
871 
872     /* Get GL entry points */
873     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
874 
875     bool testResult    = true;
876     glw::GLuint offset = 0;
877 
878     for (std::map<glw::GLenum, FormatInfo>::iterator it = m_configurations.begin(); it != m_configurations.end(); ++it)
879     {
880         FormatInfo &info = it->second;
881 
882         /* Create texture object */
883         gl.genTextures(1, &m_tbo_tex_id);
884         GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating texture object!");
885         gl.activeTexture(GL_TEXTURE0);
886         GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting active texture unit!");
887         gl.bindTexture(m_glExtTokens.TEXTURE_BUFFER, m_tbo_tex_id);
888         GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture buffer object!");
889         gl.texBufferRange(m_glExtTokens.TEXTURE_BUFFER, info.get_internal_format(), m_tbo_id, offset,
890                           info.get_not_aligned_size());
891         GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting buffer object as data store for texture buffer!");
892 
893         /* Create transform feedback buffer objects */
894         gl.genBuffers(1, &m_tf_size_buffer_id);
895         GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating buffer object!");
896         gl.bindBuffer(GL_ARRAY_BUFFER, m_tf_size_buffer_id);
897         GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object!");
898         gl.bufferData(GL_ARRAY_BUFFER, sizeof(glw::GLint), DE_NULL, GL_DYNAMIC_COPY);
899         GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating buffer object's data store!");
900 
901         std::vector<glw::GLubyte> buffer(info.get_ssbo_value_size());
902         memset(&buffer[0], 0, info.get_ssbo_value_size());
903 
904         gl.genBuffers(1, &m_tf_value_buffer_id);
905         GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating buffer object!");
906         gl.bindBuffer(GL_ARRAY_BUFFER, m_tf_value_buffer_id);
907         GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object!");
908         gl.bufferData(GL_ARRAY_BUFFER, info.get_ssbo_value_size(), &buffer[0], GL_DYNAMIC_COPY);
909         GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating buffer object's data store!");
910 
911         /* Configure program object using Vertex Shader and Fragment Shader */
912         m_vsfs_po_id = gl.createProgram();
913         GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating program object!");
914 
915         const char *varyings[] = {"outTextureSize", "outValue"};
916 
917         gl.transformFeedbackVaryings(m_vsfs_po_id, 2, varyings, GL_SEPARATE_ATTRIBS);
918         GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting transform feedback varyings!");
919 
920         m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
921         GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating shader object!");
922 
923         m_vs_id = gl.createShader(GL_VERTEX_SHADER);
924         GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating shader object!");
925 
926         std::string fsSource = getFragmentShaderCode(info);
927         std::string vsSource = getVertexShaderCode(info);
928         const char *fsCode   = fsSource.c_str();
929         const char *vsCode   = vsSource.c_str();
930 
931         if (!buildProgram(m_vsfs_po_id, m_fs_id, 1, &fsCode, m_vs_id, 1, &vsCode))
932         {
933             TCU_FAIL("Could not build program from valid vertex/fragment shader code!");
934         }
935 
936         gl.useProgram(m_vsfs_po_id);
937         GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting active program object!");
938 
939         glw::GLint sampler_location = gl.getUniformLocation(m_vsfs_po_id, "sampler_buffer");
940         GLU_EXPECT_NO_ERROR(gl.getError(), "Error getting uniform location!");
941         if (sampler_location == -1)
942         {
943             TCU_FAIL("Failed to get uniform location for valid uniform variable");
944         }
945 
946         gl.uniform1i(sampler_location, 0);
947         GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting value for uniform location!");
948 
949         /* Configure transform feedback */
950         gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_tf_size_buffer_id);
951         GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object to transform feedback binding point.");
952         gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 1, m_tf_value_buffer_id);
953         GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object to transform feedback binding point.");
954 
955         gl.beginTransformFeedback(GL_POINTS);
956         GLU_EXPECT_NO_ERROR(gl.getError(), "Error beginning transform feedback.");
957 
958         /* Render */
959         gl.drawArrays(GL_POINTS, 0, 1);
960         glw::GLenum glerr = gl.getError();
961 
962         gl.endTransformFeedback();
963         GLU_EXPECT_NO_ERROR(glerr, "Error drawing arrays");
964         GLU_EXPECT_NO_ERROR(gl.getError(), "Error ending transform feedback.");
965 
966         gl.memoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
967         GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting memory barrier.");
968 
969         /* Check results */
970         if (!checkResult(info, "Vertex/Fragment shader", true))
971         {
972             testResult = false;
973         }
974 
975         /* Run compute shader if internal format is supported by image_load_store */
976         if (info.get_is_image_supported())
977         {
978             /* Create Shader Storage Buffer Object */
979             gl.genBuffers(1, &m_ssbo_size_id);
980             GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating buffer object!");
981             gl.bindBuffer(GL_ARRAY_BUFFER, m_ssbo_size_id);
982             GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding  buffer object!");
983             gl.bufferData(GL_ARRAY_BUFFER, sizeof(glw::GLint), 0, GL_DYNAMIC_COPY);
984             GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating buffer object's data store!");
985 
986             gl.genBuffers(1, &m_ssbo_value_id);
987             GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating buffer object!");
988             gl.bindBuffer(GL_ARRAY_BUFFER, m_ssbo_value_id);
989             GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding  buffer object!");
990             gl.bufferData(GL_ARRAY_BUFFER, info.get_ssbo_value_size(), &buffer[0], GL_DYNAMIC_COPY);
991             GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating buffer object's data store!");
992 
993             /* Create compute shader program */
994             m_cs_po_id = gl.createProgram();
995             GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating program object!");
996 
997             m_cs_id = gl.createShader(GL_COMPUTE_SHADER);
998             GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating shader object!");
999 
1000             std::string csSource = getComputeShaderCode(info);
1001             const char *csCode   = csSource.c_str();
1002 
1003             if (!buildProgram(m_cs_po_id, m_cs_id, 1, &csCode))
1004             {
1005                 TCU_FAIL("Could not build program from valid compute shader code!");
1006             }
1007 
1008             gl.useProgram(m_cs_po_id);
1009             GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting active program object!");
1010 
1011             /* Configure SSBO objects */
1012             gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_ssbo_size_id);
1013             GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object to shader storage binding point!");
1014             gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_ssbo_value_id);
1015             GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object to shader storage binding point!");
1016 
1017             /* Bind texture to image unit*/
1018             gl.bindImageTexture(0, m_tbo_tex_id, 0, GL_FALSE, 0, GL_READ_ONLY, info.get_internal_format());
1019             GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object to image unit 0!");
1020 
1021             /* Run compute shader */
1022             gl.dispatchCompute(1, 1, 1);
1023             GLU_EXPECT_NO_ERROR(gl.getError(), "Error running compute shader!");
1024 
1025             gl.memoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
1026             GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting memory barrier!");
1027 
1028             if (!checkResult(info, "Compute shader", false))
1029             {
1030                 testResult = false;
1031             }
1032         }
1033 
1034         offset += info.get_aligned_size();
1035         cleanIteration();
1036     }
1037 
1038     if (testResult)
1039     {
1040         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1041     }
1042     else
1043     {
1044         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1045     }
1046 
1047     return STOP;
1048 }
1049 
1050 /** Check test results
1051  *
1052  *   @param info              test configuration
1053  *   @param phase             name of test phase
1054  *   @param transformFeedback contains information if verification method should use transformfeedback, otherwise it uses SSBO
1055  *
1056  *   @return                  return true if result values are es expected, otherwise return false
1057  */
checkResult(FormatInfo & info,const char * phase,bool transformFeedback)1058 bool TextureBufferTextureBufferRange::checkResult(FormatInfo &info, const char *phase, bool transformFeedback)
1059 {
1060     /* Get GL entry points */
1061     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1062 
1063     glw::GLenum bufferTarget  = GL_NONE;
1064     glw::GLuint bufferSizeId  = GL_NONE;
1065     glw::GLuint bufferValueId = GL_NONE;
1066 
1067     if (transformFeedback)
1068     {
1069         bufferTarget  = GL_TRANSFORM_FEEDBACK_BUFFER;
1070         bufferSizeId  = m_tf_size_buffer_id;
1071         bufferValueId = m_tf_value_buffer_id;
1072     }
1073     else
1074     {
1075         bufferTarget  = GL_SHADER_STORAGE_BUFFER;
1076         bufferSizeId  = m_ssbo_size_id;
1077         bufferValueId = m_ssbo_value_id;
1078     }
1079 
1080     bool testResult = true;
1081 
1082     /* Get result data */
1083     gl.bindBuffer(bufferTarget, bufferSizeId);
1084     GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer!");
1085 
1086     glw::GLint *size = (glw::GLint *)gl.mapBufferRange(bufferTarget, 0, sizeof(glw::GLint), GL_MAP_READ_BIT);
1087     GLU_EXPECT_NO_ERROR(gl.getError(), "Error mapping buffer!");
1088 
1089     const glw::GLint expectedSize = 1;
1090 
1091     /* Reagrding test specification size should be equal 1*/
1092     /* Log error if expected and result data are not equal */
1093     if (*size != expectedSize)
1094     {
1095         m_testCtx.getLog() << tcu::TestLog::Message << "Texture size is wrong for " << phase << " phase \n"
1096                            << "Internal Format: " << glu::getUncompressedTextureFormatName(info.get_internal_format())
1097                            << "\n"
1098                            << "Expected size:   " << expectedSize << "\n"
1099                            << "Result size:     " << size << "\n"
1100                            << tcu::TestLog::EndMessage;
1101     }
1102 
1103     gl.unmapBuffer(bufferTarget);
1104     GLU_EXPECT_NO_ERROR(gl.getError(), "Error unmapping buffer!");
1105 
1106     gl.bindBuffer(bufferTarget, bufferValueId);
1107     GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer!");
1108 
1109     std::stringstream expVal;
1110     std::stringstream resVal;
1111 
1112     /* Log error if expected and result data are not equal */
1113     switch (info.get_output_type())
1114     {
1115     case GL_FLOAT:
1116     {
1117         glw::GLfloat *res =
1118             (glw::GLfloat *)gl.mapBufferRange(bufferTarget, 0, info.get_ssbo_value_size(), GL_MAP_READ_BIT);
1119         GLU_EXPECT_NO_ERROR(gl.getError(), "Error mapping buffer!");
1120 
1121         std::vector<glw::GLfloat> expected(info.get_n_components());
1122 
1123         fillOutputData(reinterpret_cast<glw::GLubyte *>(&expected[0]), info);
1124 
1125         for (glw::GLuint i = 0; i < info.get_n_components(); ++i)
1126         {
1127             if (de::abs(res[i] - expected[i]) > m_epsilon_float)
1128             {
1129                 expVal.str("");
1130                 resVal.str("");
1131                 expVal << expected[i];
1132                 resVal << res[i];
1133 
1134                 logError(phase, glu::getUncompressedTextureFormatName(info.get_internal_format()), i,
1135                          expVal.str().c_str(), resVal.str().c_str());
1136 
1137                 testResult = false;
1138             }
1139         }
1140     }
1141     break;
1142 
1143     case GL_INT:
1144     {
1145         glw::GLint *res = (glw::GLint *)gl.mapBufferRange(bufferTarget, 0, info.get_ssbo_value_size(), GL_MAP_READ_BIT);
1146         GLU_EXPECT_NO_ERROR(gl.getError(), "Error mapping buffer!");
1147 
1148         std::vector<glw::GLint> expected(info.get_n_components());
1149 
1150         fillOutputData(reinterpret_cast<glw::GLubyte *>(&expected[0]), info);
1151 
1152         for (glw::GLuint i = 0; i < info.get_n_components(); ++i)
1153         {
1154             if (res[i] != expected[i])
1155             {
1156                 expVal.str("");
1157                 resVal.str("");
1158                 expVal << expected[i];
1159                 resVal << res[i];
1160 
1161                 logError(phase, glu::getUncompressedTextureFormatName(info.get_internal_format()), i,
1162                          expVal.str().c_str(), resVal.str().c_str());
1163 
1164                 testResult = false;
1165             }
1166         }
1167     }
1168     break;
1169 
1170     case GL_UNSIGNED_INT:
1171     {
1172         glw::GLuint *res =
1173             (glw::GLuint *)gl.mapBufferRange(bufferTarget, 0, info.get_ssbo_value_size(), GL_MAP_READ_BIT);
1174         GLU_EXPECT_NO_ERROR(gl.getError(), "Error mapping buffer!");
1175 
1176         std::vector<glw::GLuint> expected(info.get_n_components());
1177 
1178         fillOutputData(reinterpret_cast<glw::GLubyte *>(&expected[0]), info);
1179 
1180         for (glw::GLuint i = 0; i < info.get_n_components(); ++i)
1181         {
1182             if (res[i] != expected[i])
1183             {
1184                 expVal.str("");
1185                 resVal.str("");
1186                 expVal << expected[i];
1187                 resVal << res[i];
1188 
1189                 logError(phase, glu::getUncompressedTextureFormatName(info.get_internal_format()), i,
1190                          expVal.str().c_str(), resVal.str().c_str());
1191 
1192                 testResult = false;
1193             }
1194         }
1195     }
1196     break;
1197 
1198     default:
1199     {
1200         gl.unmapBuffer(bufferTarget);
1201         GLU_EXPECT_NO_ERROR(gl.getError(), "Error ummapping buffer!");
1202 
1203         TCU_FAIL("Not allowed output type");
1204     }
1205     }
1206 
1207     gl.unmapBuffer(bufferTarget);
1208     GLU_EXPECT_NO_ERROR(gl.getError(), "Error ummapping buffer!");
1209 
1210     return testResult;
1211 }
1212 
1213 /** Create error message and log it
1214  *
1215  * @param phase          name of phase
1216  * @param internalFormat name of internal format
1217  * @param component      component position
1218  * @param exptectedValue string with expected value
1219  * @param resultValue    string with result   value
1220  *
1221  */
logError(const char * phase,const char * internalFormat,glw::GLuint component,const char * exptectedValue,const char * resultValue)1222 void TextureBufferTextureBufferRange::logError(const char *phase, const char *internalFormat, glw::GLuint component,
1223                                                const char *exptectedValue, const char *resultValue)
1224 {
1225     m_testCtx.getLog() << tcu::TestLog::Message << "Result is different for " << phase << " phase \n"
1226                        << "Internal Format: " << internalFormat << "\n"
1227                        << "Component Position: " << component << "\n"
1228                        << "Expected value: " << exptectedValue << "\n"
1229                        << "Result value: " << resultValue << "\n"
1230                        << tcu::TestLog::EndMessage;
1231 }
1232 
1233 /** Deinitializes GLES objects created during the test.
1234  *
1235  */
deinit(void)1236 void TextureBufferTextureBufferRange::deinit(void)
1237 {
1238     /* Call base class' deinit() */
1239     TestCaseBase::deinit();
1240 
1241     /* Check if texture buffer extension is supported */
1242     if (!m_is_texture_buffer_supported)
1243     {
1244         return;
1245     }
1246 
1247     /* Get GL entry points */
1248     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1249 
1250     /* Reset GLES state */
1251     gl.bindBuffer(m_glExtTokens.TEXTURE_BUFFER, 0);
1252     gl.bindVertexArray(0);
1253 
1254     /* Delete GLES objects */
1255     if (0 != m_tbo_id)
1256     {
1257         gl.deleteBuffers(1, &m_tbo_id);
1258         m_tbo_id = 0;
1259     }
1260 
1261     if (0 != m_vao_id)
1262     {
1263         gl.deleteVertexArrays(1, &m_vao_id);
1264     }
1265 
1266     cleanIteration();
1267 }
1268 
1269 /** Fill buffer with input data for texture buffer
1270  *
1271  * @param buffer buffer where data will be stored
1272  * @param offset offset into buffer
1273  * @param info   test configuration
1274  *
1275  */
fillInputData(glw::GLubyte * buffer,glw::GLuint offset,FormatInfo & info)1276 void TextureBufferTextureBufferRange::fillInputData(glw::GLubyte *buffer, glw::GLuint offset, FormatInfo &info)
1277 {
1278     /* Initial value should give value equal to 1 on output */
1279 
1280     /* Check input data type */
1281     switch (info.get_input_type())
1282     {
1283     case GL_FLOAT:
1284     {
1285         glw::GLfloat *pointer = reinterpret_cast<glw::GLfloat *>(&buffer[offset]);
1286         for (glw::GLuint i = 0; i < info.get_n_components(); ++i)
1287         {
1288             *pointer++ = 1.0f;
1289         }
1290     }
1291     break;
1292 
1293     case GL_HALF_FLOAT:
1294     {
1295         glw::GLhalf *pointer = reinterpret_cast<glw::GLhalf *>(&buffer[offset]);
1296 
1297         glw::GLfloat val = 1.0f;
1298 
1299         /* Convert float to half float */
1300         glw::GLuint temp32      = 0;
1301         glw::GLuint temp32_2    = 0;
1302         unsigned short temp16   = 0;
1303         unsigned short temp16_2 = 0;
1304 
1305         memcpy(&temp32, &val, sizeof(glw::GLfloat));
1306         temp32_2 = temp32 >> 31;
1307         temp16   = (unsigned short)((temp32_2 >> 31) << 5);
1308         temp32_2 = temp32 >> 23;
1309         temp16_2 = temp32_2 & 0xff;
1310         temp16_2 = (unsigned short)((temp16_2 - 0x70) & ((glw::GLuint)((glw::GLint)(0x70 - temp16_2) >> 4) >> 27));
1311         temp16   = (unsigned short)((temp16 | temp16_2) << 10);
1312         temp32_2 = temp32 >> 13;
1313         temp16   = (unsigned short)(temp16 | (temp32_2 & 0x3ff));
1314 
1315         for (glw::GLuint i = 0; i < info.get_n_components(); ++i)
1316         {
1317             *pointer++ = temp16;
1318         }
1319     }
1320     break;
1321 
1322     case GL_UNSIGNED_BYTE:
1323     {
1324         glw::GLubyte *pointer = reinterpret_cast<glw::GLubyte *>(&buffer[offset]);
1325         glw::GLubyte val      = 0;
1326 
1327         /* Normalized Values */
1328         if (info.get_internal_format() == GL_R8 || info.get_internal_format() == GL_RG8 ||
1329             info.get_internal_format() == GL_RGBA8)
1330         {
1331             val = 255;
1332         }
1333         else
1334         {
1335             val = 1;
1336         }
1337         for (glw::GLuint i = 0; i < info.get_n_components(); ++i)
1338         {
1339             *pointer++ = val;
1340         }
1341     }
1342     break;
1343 
1344     case GL_UNSIGNED_SHORT:
1345     {
1346         glw::GLushort *pointer = reinterpret_cast<glw::GLushort *>(&buffer[offset]);
1347 
1348         for (glw::GLuint i = 0; i < info.get_n_components(); ++i)
1349         {
1350             *pointer++ = (glw::GLushort)1;
1351         }
1352     }
1353     break;
1354     case GL_UNSIGNED_INT:
1355     {
1356         glw::GLuint *pointer = reinterpret_cast<glw::GLuint *>(&buffer[offset]);
1357 
1358         for (glw::GLuint i = 0; i < info.get_n_components(); ++i)
1359         {
1360             *pointer++ = 1;
1361         }
1362     }
1363     break;
1364     case GL_INT:
1365     {
1366         glw::GLint *pointer = reinterpret_cast<glw::GLint *>(&buffer[offset]);
1367         for (glw::GLuint i = 0; i < info.get_n_components(); ++i)
1368         {
1369             *pointer++ = 1;
1370         }
1371     }
1372     break;
1373     case GL_SHORT:
1374     {
1375         glw::GLshort *pointer = reinterpret_cast<glw::GLshort *>(&buffer[offset]);
1376         for (glw::GLuint i = 0; i < info.get_n_components(); ++i)
1377         {
1378             *pointer++ = (glw::GLshort)1;
1379         }
1380     }
1381     break;
1382     case GL_BYTE:
1383     {
1384         glw::GLbyte *pointer = reinterpret_cast<glw::GLbyte *>(&buffer[offset]);
1385         for (glw::GLuint i = 0; i < info.get_n_components(); ++i)
1386         {
1387             *pointer++ = (glw::GLbyte)1;
1388         }
1389     }
1390     break;
1391     default:
1392         TCU_FAIL("Not allowed input type");
1393     }
1394 }
1395 
1396 /** Fill buffer with output data for texture buffer
1397  *
1398  * @param buffer buffer where data will be stored
1399  * @param info   test configuration
1400  *
1401  */
fillOutputData(glw::GLubyte * buffer,FormatInfo & info)1402 void TextureBufferTextureBufferRange::fillOutputData(glw::GLubyte *buffer, FormatInfo &info)
1403 {
1404     switch (info.get_output_type())
1405     {
1406     case GL_FLOAT:
1407     {
1408         glw::GLfloat *pointer = reinterpret_cast<glw::GLfloat *>(&buffer[0]);
1409         for (unsigned int i = 0; i < info.get_n_components(); ++i)
1410         {
1411             *pointer++ = 1.0f;
1412         }
1413     }
1414     break;
1415 
1416     case GL_INT:
1417     {
1418         glw::GLint *pointer = reinterpret_cast<glw::GLint *>(&buffer[0]);
1419         for (unsigned int i = 0; i < info.get_n_components(); ++i)
1420         {
1421             *pointer++ = 1;
1422         }
1423     }
1424     break;
1425 
1426     case GL_UNSIGNED_INT:
1427     {
1428         glw::GLuint *pointer = reinterpret_cast<glw::GLuint *>(&buffer[0]);
1429         for (unsigned int i = 0; i < info.get_n_components(); ++i)
1430         {
1431             *pointer++ = 1;
1432         }
1433     }
1434     break;
1435 
1436     default:
1437         TCU_FAIL("Not allowed output type");
1438     }
1439 }
1440 
1441 } // namespace glcts
1442